利用setcontext来进行ORW

当遇到堆题禁用execve时我们就需要用ORW的方法来读取flag,那么堆题如何实现栈迁移来进行ORW就成了一个问题,而利用setcontext是解决这个问题的一个方案

首先来了解什么是setcontext?

setcontext是libc中的一个函数,而它的汇编代码中含有大量的 mov <寄存器> 这类汇编语句,如下图(注:setcontext以glibc2.29为分界线,2.29以下和2.29及以上有较大不同):
![[Pasted image 20250227233231.png]]

上图是glibc2.27中的 setcontext 的汇编部分,可以看到其中有非常多的控制寄存器的mov指令,它们都利用 rdi+<偏移值> 来获取具体的数值,所以如果我们可以控制 rdi寄存器 随后将程序跳转到 setcontext+53(也就是图中mov rsp,[rdi+0xa0h]的位置) 这样我们就可以控制包括 rip rsp 这两个重要寄存器,

基本思路

控制执行流之后就有两种思路:

  1. 是直接控制程序执行流去执行ROP链
  2. 是先用 mprotect 函数开辟一段可读可写可执行的空间再跳到上面去执行 shellcode

这里我们主要讲解执行ROP链ORW的思路:
控制 rsp寄存器 到我们布置好 ROP的地址,然后控制 ripret地址

如何控制rip并开始ORW?

通过观察上图发现最后一条指令是ret而其中有一个push rcx的操作,因此可以判断ret返回的地方就是rcx中存储的地址
那么此时栈中的情况就是下面的这样

ORW部分的代码
... ...
ORW部分的代码
rcx中的值  <-- rsp

-----我是分割线-----

ret指令 <-- rip

setcontext最后是一个ret指令那么就是

ORW部分的代码
... ...
ORW部分的代码 <-- rsp

-----我是分割线-----

rcx中存放的指令 <-- rip

那么为了能够开始我们的ORW,所以我们需要控制rcxret指令的地址也就是控制rdi+0xa8h这个地方为ret指令的地址

glibc2.29之前的一般利用思路:

1.想办法修改free_hook为setcontext+53

2.申请一个chunk1
chunk1_usr_addr+0xa0=rsp迁移地址;
chunk1_usr_addr+0xa8=ret指令地址;

3.申请一个chunk2
chunk2中存放ORW的ROP链,同时这也是rsp需要迁移的地方

4. free(chunk1) 此时的rdi恰好指向chunk_usr_addr,然后可以触发后续一些列的东西

glibc2.29之后的改变

下面来看看glibc2.29之后setcontext做出了哪些改变
![[Pasted image 20250126230319.png]]

调整:从rdi+偏移变成了rdx+偏移

rdi+偏移变成了rdx+偏移这是一个很大的改变,因为我们打堆题一般利用setcontext的思路是修改free_hooksetcontext+53,然后这个时候rdi恰好指向了 chunk_usr_addr,但是如果从 rdi 到了 rdx,那么我们该如何控制 rdx 就成了一个问题

由于在free的时候我们可以控制的只有rdi那么我们就需要一个既可以通过rdi来控制rdx,又可以通过rdi来控制ripgadget

那么真的会有这样的gadget吗?(有的兄弟,有的)
在glibc2.29中有类似这样的gadget,既可以控制rdx,最后又可以控制rip

mov rdx, [rdi+0x8]; mov rax, [rdi]; mov rdi, rdx; jmp rax;
mov rdx, [rdi+0x8]; mov [rsp], rax; call qword ptr [rdx+0x20];

这里我们就简单讲一下第二个gadget要咋用
一般我们需要构造三个堆块,三个堆块的作用分别如下

将free_hook赋值为上面mov rdx,qword ptr [rdi+8];

chunk1:
	prev_size, size
setcontext+53, rdi_addr[一般是chunk2_usr_data-0xa0] (这里需要计算好,rdi+0xa0的位置是rsp_addr也就是chunk3_usr_data,rdi+0xa8得是rip的地址[一般放ret])

chunk2:
	orw_addr(chunk3_usr_data), ret_addr

chunk3:
	prev_size, size
	... ... ... ...
	pop_r_ret, XXXX   --> orw 的ROP链

然后再glibc2.31的setcontext再次做出了调整 mov rsp, [rdx+0xa0h] 的位置变成了setcontext+61但是这个改变并不算大,但是在glibc2.31中上面我们发现的两个牛逼gadget被制裁了,只剩下一个了(泪目了,老铁)

mov rdx, [rdi+0x8]; mov [rsp], rax; call qword ptr [rdx+0x20];

参考:
文章 - srop搭配高低版本的setcontext - 先知社区
setcontext+orw - 狒猩橙 - 博客园

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值