#!/bin/bash

# This script requires a copy of an uncompressed kernel to be placed in the script directory  
# The kernel copy must match the exact version running on this system.  

if [ -e /boot/System.map ]
then 
	Sysmap=/boot/System.map
else

	Sysmap=`ls /boot | grep System`
	Sysmap=`echo /boot/$Sysmap`

fi
if [ `echo "$Sysmap" | grep .gz` == `echo "$Sysmap"` ]
then
 	rm -f ./system.map.tmp*
        cp `echo $Sysmap` ./system.map.tmp.gz
        gzip -d system.map.tmp.gz
        Sysmap="./system.map.tmp"
fi
if [ ! -e "$Sysmap" ]
then
     Sysmap=`ls /boot | grep System | grep default`
     Sysmap=`echo /boot/$Sysmap`
fi
if [ ! -e "$Sysmap" ]
then
        echo "TRUE:"
        echo "AddListItem([[[]]],[[[Error]]])"
        echo "AddListItem([[[Error]]],[[[Unable to find a suitable sysmap, make sure you read the complete documentation of this check]]])"
        echo "!!SCRIPT_FINISHED!!"
        exit
fi
# if you wish to use the kernel from the boot directory, uncomment the line below which starts with "kernel". 
# Make sure an uncompressed kernel does reside in the boot directory.
# while this operation will in most cases work, it is not recommanded since 
# if the system was compromised the kernel itself might have been changed to avoid detection.
# it is recommanded that instead a fresh backup is used.
#kernel=`ls /boot | grep vmlinux`
# if you uncomment the line above please make sure to comment out the next line
kernel=`ls | grep vmlinux`
if [ ! -e "$kernel" ]
then
	kernel=`ls /boot | grep vmlinux`
	kernel=`echo /boot/$kernel`
	for check in $kernel
	do
		if  [ -e "$check" ] 
		then
			kernel=$check
		fi 
	done 
fi
if [ `echo $kernel | grep .gz` == `echo $kernel` ]
then
 	rm -f ./vmlinux.tmp*
        cp `echo $kernel` ./vmlinux.tmp.gz
        gzip -d vmlinux.tmp.gz
        kernel="./vmlinux.tmp"
fi
if [ "$kernel" == "/boot/" ]
then
	kernel=""
fi
if [ ! -e "$kernel" ]
then 
	echo "TRUE:"
	echo "AddListItem([[[]]],[[[Error]]])"
	echo "AddListItem([[[Error]]],[[[Unable to find Kernel, make sure you read the complete documentation of this check]]])"
 	echo "!!SCRIPT_FINISHED!!"
	exit
fi 

kernelloc=`cat $Sysmap | grep sys_call_table | grep -v ?`
kernelloc=`echo $kernelloc | awk '{ print $1 }'`
sysmaploc=`nm $kernel | grep sys_call_table | grep -v ?`
sysmaploc=`echo $sysmaploc | awk '{ print $1 }'`

#compare kernel table location with sysmap
if [ "$kernelloc" != "$sysmaploc" ]
then
	echo "TRUE:"
	echo "AddListItem([[[]]],[[[Kernel sys_call_table doesn't match SystemMap sys_call_table -> 0x$kernelloc : 0x$sysmaploc]]])"
	echo "!!SCRIPT_FINISHED!!"
	exit
fi

cat << EOF > gdb-kernel
#!/usr/bin/expect -f
set timeout -1
spawn gdb -q $kernel [lrange \$argv 1 1]
match_max 100000
expect "(gdb) "
send -- "set height 5000\r"
expect "(gdb) "
send -- "x/255 [lrange \$argv 0 0]"
expect -exact "[lrange \$argv 0 0]"
send -- "\r"
expect "(gdb) "
send -- "q\r"
expect eof
EOF

chmod u+x gdb-kernel
./gdb-kernel 0x$kernelloc > table.raw
grep 0x table.raw | grep -v \#0 | grep -v Core > kernel-stored
rm -f table.raw
./gdb-kernel 0x$kernelloc /proc/kcore > tablek.raw
grep 0x tablek.raw | grep -v \#0 | grep -v Core > kernel-running
rm -f tablek.raw

rm -f gdb-kernel
result=`diff kernel-stored kernel-running`
if [ "$result" != "" ]
then
	echo TRUE:
	echo "AddListItem([[[]]],[[[Possible RootKit Detected]]])"
	echo "AddListItem([[[Possible RootKit Detected]]],[[[Kernel system call table of the provided kernel file does not match table of the current running kernel. This might indicate the presence of a rootkit or other system calls hijacking software]]])"
	echo "AddListItem([[[Possible RootKit Detected]]],[[[Check the file kernel-stored and kernel-running (Stored in the home directory of the user specified in LNSS) to find out which addresses have been tampered with]]])"
else
	echo FALSE:
	rm -f kernel-stored
	rm -f kernel-running
fi

echo "!!SCRIPT_FINISHED!!"

