LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Security (https://www.linuxquestions.org/questions/linux-security-4/)
-   -   Rootkit Hunter reported warnings (https://www.linuxquestions.org/questions/linux-security-4/rootkit-hunter-reported-warnings-860232/)

qrange 02-02-2011 08:57 AM

Rootkit Hunter reported warnings
 
rk reports these warnings, can someone please please check hashes?

[14:53:49] /bin/login [ Warning ]
[14:53:49] Warning: The file properties have changed:
[14:53:49] File: /bin/login
[14:53:49] Current hash: 5ca80f48aab7b01ef8ac5bba4019a94a3b0996a4
[14:53:49] Stored hash : 484d4f850a41645bb9f7b58a852c2631dc161bab
[14:53:49] Current inode: 105675 Stored inode: 105693
[14:53:49] Current file modification time: 1258209718
[14:53:49] Stored file modification time : 1227369664

[14:53:51] /bin/su [ Warning ]
[14:53:51] Warning: The file properties have changed:
[14:53:51] File: /bin/su
[14:53:51] Current hash: b1a3166a3c09cf58a717b50d03c7f5b316dabbf5
[14:53:51] Stored hash : 44b691fd7f022cd8bfd4e10cdda33b853cde47ad
[14:53:51] Current inode: 105676 Stored inode: 105694
[14:53:51] Current file modification time: 1258209718
[14:53:51] Stored file modification time : 1227369664


[14:53:52] /usr/bin/dpkg [ Warning ]
[14:53:52] Warning: The file properties have changed:
[14:53:53] File: /usr/bin/dpkg
[14:53:53] Current hash: d478e79772b78b64cd5161a4d684b8f52f2e7f5e
[14:53:53] Stored hash : e2a8eed5a68005f0f6372cca5658f518664166fc
[14:53:53] Current inode: 359820 Stored inode: 675750
[14:53:53] Current size: 365420 Stored size: 365196
[14:53:53] Current file modification time: 1294222205
[14:53:53] Stored file modification time : 1233612813

anomie 02-02-2011 09:03 AM

Have you updated packages since the last rkhunter run?

qrange 02-02-2011 09:54 AM

hm, yes, its been a long time since I used --propupd so its probably normal, sorry..

still, I wish there was an updated list of bin/ hashes somewhere on net..

Nominal Animal 02-04-2011 01:39 PM

I went nuts and decided to create a checksum verifier.

This is in three parts to let you customize it better. The first script just accumulates a table of known packages. The second script generates a list of packages (and the interesting files in them) based on the local files and local package repository. The output will most likely contain packages for many other architectures, so you should filter the output for proper package candidates. The third script is the workhorse: it eats lists of files and local or remote packages, and generates SHA1 checksums of the files inside those packages.

Here is the repository/file tree package list catalog script. This lets you grab the package list from a local tree (for example, from known good DVD/CD-ROM media), or from (the ls-lR file in) a reliable repository. Save it as e.g. package-list:
Code:

#!/bin/bash
IFS="
"
if [ $# -lt 1 ] || [ "$1" == "-h" ] || [ "$1" == "--help" ]; then
    exec >&2
    echo ""
    echo "Usage: $0 [ -h | --help ]"
    echo " $0 directories or repositories ..."
    echo ""
    echo "This script will scan the specified directories and"
    echo "repositories, and list all packages in a concise from"
    echo "to standard output."
    echo ""
    exit 1
fi

while [ $# -gt 0 ]; do
    arg="$1"
    shift 1
    if [ -e "$arg" ]; then
        find "$arg" -type f -name '*.deb' -printf '%f local %p\n' | sed -e 's|^\([^ _]*\)_[^ ]* |\1 |'
    else
        wget -O - "${arg%/}/ls-lR" | gawk -v "prefix=${arg%/}/" '
            BEGIN {
                RS="(\n\r?|\r\n?)[\t\n\v\f\r ]*"
                FS="[\t\v\f ]+"
                path = ""
            }
            /^\// {
                pre = $0
                gsub(/^\/+/, "", pre)
                gsub(/\/*:*[\t ]*$/, "", pre)
                path = prefix "/" pre "/"
                gsub(/\/\/+/, "/", path)
                gsub(/:\/+/, "://", path)
                next
            }
            /^\.\// {
                pre = $0
                gsub(/^(\.\/)+/, "", pre)
                gsub(/^\/+/, "", pre)
                gsub(/\/*:*[\t ]*$/, "", pre)
                path = prefix "/" pre "/"
                gsub(/\/\/+/, "/", path)
                gsub(/:\/+/, "://", path)
                next
            }
            /\.deb$/ {
                file = $(NF)
                name = file
                gsub(/_.*$/, "", name)
                gsub(/^.*\//, "", name)
                printf("%s remote %s%s\n", name, path, file)
            }'
    fi
done

exit 0

Then, the next script uses dpkg-query to check which packages own the local files. It then looks at the package names in the table generated by the above script, and lists those that match, along with the name of the interesting file. Save this script as e.g. locate-package:
Code:

#!/bin/bash
if [ "$1" == "-h" ] || [ "$1" == "--help" ] || [ $# -lt 2 ]; then
    exec >&2
    echo ""
    echo "Usage: $0 [ -h | --help ]"
    echo " $0 package-list file .."
    echo ""
    exit 1
fi

if [ -x "$1" ] || [ ! -r "$1" ] || [ ! -s "$1" ]; then
    echo "$1: Cannot read package list file." >&2
    exit 1
else
    packages="$1"
    shift 1
fi

errors=0
list=()
IFS="
"
OFS="
"
while [ $# -gt 0 ]; do
    source="$1"
    file="$1"
    shift 1
    if [ -z "$file" ]; then
        continue
    fi

    while [ -h "$file" ]; do
        old="$file"
        file="`readlink "$file"`"
        if [ "$old" == "$file" ] || [ -z "$file" ]; then
            echo "$old: Broken symlink ($source)" >&2
            errors=$[errors | 2]
            continue 2
        fi
    done

    if [ ! -f "$file" ]; then
        echo "$file: No such file." >&2
        errors=$[errors | 1]
        continue
    fi

    matches=0

    for spec in `dpkg-query -S "$file"` ; do
        actual="${file#*:}"
        package="${spec%%:*}"
        package="${package//[\t ]/}"
        echo "$package $file"
        matches=$[matches + 1]
    done
    if [ $matches -lt 1 ]; then
        echo "$file: No packages found!" >&2
        errors=$[errors | 4]
    fi
done | awk -v "catalog=$packages" '
    BEGIN {
        RS="[\t\v\f ]*(\r?\n|\n\r)[\t\n\v\f\r ]*"
        FS="[\t\v\f ]+"
    }
    {
        if (NF >= 2 && length($1) > 0 && length($2) > 0)
            package[$2] = $1
    }
    END {
        while ((getline < catalog) > 0)
            for (file in package)
                if ($1 == package[file])
                    print file, $2, $3
    }
'
exit $errors

The final script is the one that takes the list of files and interesting local or remote packages, and generates the SHA1 checksums. Save this script as e.g. package-checksums:
Code:

#!/bin/bash
if [ "$1" == "-h" ] || [ "$1" == "--help" ]; then
    exec >&2
    echo ""
    echo "Usage: $0 [ -h | --help ]"
    echo " $0 [ files .. ]"
    echo ""
    echo "This script reads in lines of form"
    echo " /path/to/file local /path/to/package.deb"
    echo " /path/to/file remote http://../package.deb"
    echo "and compares and reports the SHA1 checksums."
    echo ""
    exit 0
fi
DIR="/tmp/checkpackage-`hostname -s`.$$"
trap "rm -rf '$DIR'" EXIT
if ! mkdir -m 0700 "$DIR" ; then
    echo "$DIR: Cannot create temporary directory." >&2
    exit 1
fi

errors=0
while read path type source ; do
    package="$DIR/${source##*/}"
    if [ ! -f "$package" ]; then
        case "$type" in
        local)
            if ! cp -f "$source" "$package" >&2 ; then
                rm -f "$package"
                echo "$source: Cannot copy package." >&2
                errors=$[errors | 1]
            fi
            ;;
        remote)
            if ! wget -O "$package" "$source" >&2 ; then
                rm -f "$package"
                echo "$source: Cannot obtain package." >&2
                errors=$[errors | 2]
            fi
            ;;
        *)
            echo "$type: Unknown method to retrieve '$source'." >&2
            errors=$[errors | 4]
            ;;
        esac
    fi
    if [ -f "$package" ]; then
        hash="`dpkg-deb --fsys-tarfile "$package" | tar -O -x ".$path" | sha256sum -b -`"
        hash="${hash%% \*-}"
        if [ -n "$hash" ]; then
            echo "$hash *$path ($source)"
        else
            echo "$source: Package does not contain $path." >&2
            errors=$[errors | 8]
        fi
    fi
done

exit $errors

It may be a bit cumbersome, but this way you can control each phase best. Note that the final script may transfer a lot of packages (although each package only once), so it's best to use trim at least the final list before running the third script.

If I wanted to check if my /usr/bin/sudo and /bin/su match the Debian upstream, I'd use the above scripts something like this (using Bash):
Code:

files="/bin/su /usr/bin/sudo"

# Save a list of known packages as debian.packages -- this repository is closest to me
./package-list http://ftp.funet.fi/pub/mirrors/ftp.debian.org/debian > debian.packages

# Generate a list of packages containing the interesting files
./locate-package debian.packages $files > check.list

# Get the checksums of matching i386 packages
grep -e i386 check.list | ./package-checksums > upstream.sha1

# Get the checksums of my local files
sha1sum -b $files > local.sha1

Then I'd compare local.sha1 first to the logs, and then to the upstream.sha1 file.
There are certain rootkits that may have hooked sha1sum or the standard C libraries, in which case the
log and the output may not match. (I'm assuming RKHunter uses SHA1 checksums; I'm not sure, though.)

If you have a known good copy of all the packages in e.g. readonly media, you should be able to modify
the above (even using the third script only) to check the file hashes yourself.

Hope this helps,
Nominal Animal


All times are GMT -5. The time now is 10:43 PM.