The hiding is performed through file system function hooking. On Linux, every fs driver provides functions to open, read, write and perform operations with files and directories. This functions are stored in a struct file_operations, stored inside every inode. Therefore, every file_operations contains a pointer to the open, read, write(and many other) functions which will be called whenever a user tries to execute those actions on a filesystem object.
So what i did was to retrieve a certain inode and modify the pointer to its read function, replacing it with my own function. In this new function, filtering on the input was performed, in order to remove the entries i wanted to hide.
Let's take for example the connection hiding mechanism. netstat takes tcp connections information from a virtual file named /proc/net/tcp. This file contains one entry per line, each one indicating source and destination port, source and destination address and more information about each open connection. In order to hide a certain connection, i replaced the default read function with my own, in which i read entries on that file and skipped those containing the port i needed to hide.
In order to give orders to the rootkit, i used the same mechanism. I added a write function pointer to the file /proc/buddyinfo, which by default has no write permissions. So after hooking that function, whenever any user writes something to that virtual file, the rootkit will read what was wrote and execute actions based on the input. The commands it supports are the next ones:
- hide/show. This commands hide/show the rootkit from lsmod(actually from /proc/modules).
- hsport PORT/ssport PORT. Hides(hsport) connection which have PORT as their source port, or "unhides it"(ssport) if it was previously hidden.
- hdport PORT/sdport PORT. Same as above but using destination port instead of source.
- hpid PID/spid PID. Hides or "unhides" a process that has PID as its pid. This is done by hooking the /proc readdir pointer.
- huser USER/suser USER. This commands hide or "unhide" a logged in user, so that who or other similar commands won't indicate USER is logged in the system. This is done by hooking /var/run/utmp.
- root PID. This makes the process identified by PID to contain uid 0 and gid 0. This is kind of dirty but works well; the credentials struct from the init process is copied to the process identified by PID.
You can get the source code https://github.com/mfontanini/Programs-Scripts/tree/master/rootkit. In order to compile it, you require your kernel's headers(on debian-based distributions, this can be found on the package linux-headers-2.6.X.X, where X depend on your kernel version). Download both the Makefile and the source file, and then just execute:
makeThat's all. Hope you find it useful!
insmod rootkit.ko
Me tira este error cuando trato de compilarlo en un Ubuntu
ReplyDelete$ make
make -C /lib/modules/3.0.0-13-generic/build M=/home/ecerutti/rk modules
make[1]: se ingresa al directorio «/usr/src/linux-headers-3.0.0-13-generic»
CC [M] /home/ecerutti/rk/rootkit.o
/home/ecerutti/rk/rootkit.c: En la función ‘hook_proc’:
/home/ecerutti/rk/rootkit.c:493:5: error: declaración implícita de la función ‘path_lookup’ [-Werror=implicit-function-declaration]
cc1: algunos avisos se tratan como errores
make[2]: *** [/home/ecerutti/rk/rootkit.o] Error 1
make[1]: *** [_module_/home/ecerutti/rk] Error 2
make[1]: se sale del directorio «/usr/src/linux-headers-3.0.0-13-generic»
make: *** [all] Error 2
Estoy usando la última versión de Ubuntu
$ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=11.10
DISTRIB_CODENAME=oneiric
DISTRIB_DESCRIPTION="Ubuntu 11.10"
con un kernel 3.0.0
$ uname -a
Linux dulcinea 3.0.0-13-generic #22-Ubuntu SMP Wed Nov 2 13:25:36 UTC 2011 i686 athlon i386 GNU/Linux
tengo instalado los headers y las build-essentials
$ dpkg -l | grep linux-header
ii linux-headers-3.0.0-13 3.0.0-13.22 Header files related to Linux kernel version 3.0.0
ii linux-headers-3.0.0-13-generic 3.0.0-13.22 Linux kernel headers for version 3.0.0 on x86/x86_64
ii linux-headers-generic 3.0.0.13.15 Generic Linux kernel headers
$ dpkg -l | grep essential
ii build-essential 11.5ubuntu1 Informational list of build-essential packages
Estuve googleando un poco en busca de alguna solución pero no vi nada útil.
Saludos
Esteban
Thanks for writing and releasing this! It is very helpful to us security tool developers to have samples to examine and test against.
ReplyDeleteI've just posted a memory image from a (test) system that I loaded your rootkit on:
http://secondlookforensics.com/linux-memory-images/
Thanks :-)
ReplyDeleteFYI, hiding processes this way won't work for recent kernels where proc_dir_entry is opaque structure (no definition inside include files).
ReplyDeleteI would like to once average coder rootkit is injected on to a machine what process name will be appearing in ps aux list as malicious (average coder) and what is the MD5 hashes. Average coder rootkit
ReplyDeleteyour blog is very informative thanks for the write up folow the links to get some nice insit
ReplyDeletecarfentanil for sale
KETAMINE for sale
Diphenidine for sale
Buy MMB-2201 Online
buy weed online georgia
ReplyDeleteThank you - Just shared this post with a colleague who would benefit from reading this, really enjoyed it. You can also check about rootkit Debian from elstel.org
ReplyDelete