Recently, I needed to detect the hooks in the Syscalls Table and I chose to develop a Linux module which warns me if a pointer is hooked in the table. I think this type of module already exists, but I needed to execute a python script when the syscalls have been hooked.
There are several types of hooking methodes. In a recent post Michael Coppola talk about Inline Kernel Function Hooking. In my case it's a classical hook in the Syscalls Table. The following scheme represents the classical Syscalls Table hooking.
The module wich warns if a syscalls is hooked, does a copy of the Syscall Table to save all syscalls pointers. After this first step, the module uses the kernel timer to check every X secondes the diff between the Syscall Table and the copy. If a diff is found, the module creates a workqueue to execute the python script and restore the good syscall pointer. The python script is executed with root creds and the syscall number which is hooked, is passed as the first argument of script (sys.argv).
The following scheme represents the module conception.
The module contains 3 defines, PATCH_BIN, PATH_SCRIPT and TIME_SLEEP. If you want to execute a PHP or Perl script you can change PATH_BIN by the PHP or Perl path. The TIME_SLEEP define is the duration in msec between checks.
#define PATH_BIN "/usr/bin/python2.7" /* python path */ #define PATH_SCRIPT "/opt/scripts/hook_detected.py" /* Your python script */ #define TIME_SLEEP 30000 /* In msec */
The syscall which is hooked is passed as the first argument of script. For example you can create a python script which warns by mail when a syscall is hooked.
#!/usr/bin/env python2.7 import smtplib import sys RCPT_TO = 'firstname.lastname@example.org' GUSER = 'email@example.com' GPWD = 'you_passwd' SMTP = 'smtp.gmail.com' if __name__ == "__main__": smtpserver = smtplib.SMTP(SMTP, 587) smtpserver.ehlo() smtpserver.starttls() smtpserver.ehlo smtpserver.login(GUSER, GPWD) msg = 'To: ' + RCPT_TO + '\n' msg += 'From: ' + GUSER + '\n' msg += 'Subject:Hook analyzer - Hook detected !\n\n' msg += 'Hook analyzer has detected a hook in syscall table ' msg += '(syscall %s).\n' %(sys.argv) msg += 'The syscall was restored.\n\n' smtpserver.sendmail(GUSER, RCPT_TO, msg) smtpserver.close() sys.exit(0)
This module needs to be run before a rootkit, otherwise the Syscall Table is already corrupted. The module was tested on kernel 3.2.0 (Ubuntu) and the sources are here.