技术社区
安全培训
技术社群
积分商城
先知平台
漏洞库
历史记录
清空历史记录
相关的动态
相关的文章
相关的用户
相关的圈子
相关的话题
注册
登录
JOP 利用思想和 JOP 链构造分析全过程,以一个题目为例
selph
二进制安全
169浏览 · 2025-02-28 02:24
返回文档
前言
题目来自 Hack the Box 困难难度的 pwn 题目:no return,是栈溢出题目,但是真的没有可用的ret指令,gadget反而以jmp结尾居多,很容易想到曾经见过的一个名词:JOP
本文以该题目为例,分享JOP的思想和构造JOP链的过程,本题构造方法不唯一,以其中一种方式为例
参考资料[4]为非预期解,通过构造SROP配合jmp完成RCE,并非本文主题,有兴趣可以去看看
题目情况
A hop, skip, and a jump to the flag.
逆向分析
start:
给了个地址泄露,位于rsp的值
还有一些其他的代码:
利用分析
利用思路分析
程序情况分析:
●
程序是栈溢出,但是没有ret退出,而是jmp的方式跳转到栈上的返回地址
●
给了栈地址,意味着缓冲区地址可知
●
没有PIE,意味着可以任意跳转到其他的片段,可以通过控制寄存器的值来控制跳转
那么思路就是,想办法凑出参数执行execve的syscall
目标就是:
●
rax = 0x3b
●
rdi = 指向
/bin/sh
的指针
●
rsi = 0
●
rdx = 0
●
最后调用syscall
而程序中提供的gadget,全都是以jmp结尾的跳转而非ret,这里是JOP的技法!
在各种资料里介绍ROP的时候,都会顺带一提,还有JOP,通过jmp指令完成跳转
ROP 和 JOP
ROP
和
JOP
二者结构如上图(参考资料[3])
ROP
依赖
返回指令(ret)
链式调用gadget。攻击者通过覆盖栈上的返回地址,使程序依次执行多个以
ret
结尾的代码片段。通过栈溢出控制连续的返回地址,形成“链式”执行流程。例如,通过
pop
指令设置寄存器参数,再调用系统函数,构造的栈本身就是个夹杂数据的跳转表
JOP
利用
间接跳转指令(jmp)
链接gadget。攻击者篡改寄存器或内存中的跳转目标地址,构造非连续的代码执行链。依赖间接跳转指令的灵活性,可能通过“调度器gadget”动态选择后续执行的代码片段,攻击链更复杂且非线性。
构造JOP链路需要找到一组分发器-分发表组合,通过分发器选择分发表,跳转到指定的以jmp返回的gadget中,然后jmp回分发器,再次进入分发表跳转到下一个gadget。
找到 JOP 分发器 gadget
一个比较理想的情况是,有一组寄存器在后续gadget中不会被影响,分发器选择分发表中的地址时,通过同一组gadget进行
程序中给出的gadget大多以
jmp [rcx]
和
jmp [rdx]
结尾,这两个寄存器的变化应该会很频繁,不适合用作分发器gadget
排除掉这俩以后,还剩如下gadget:
只剩下2个,初始状态,rbp,rbx,rdx的值都是可控的,因为rdx的值会经常变化,所以只剩下1个满足要求的gadget
让
rbp-0x39
指向内存中可控区域(分发表),让
rbx=8
,即可每次跳转到该gadget的时候,执行分发表中的下一个gadget
构造 JOP 链 - 初始形态
此时 payload 的初始形态已经构成:
可控区域总共0xc0大小,其中0xb0位置是栈溢出控制的返回地址所在,设置为初始化寄存器的跳转gadget那里:
其中0xb8是新的rsp,然后依次设置了其他寄存器,通过
jmp qword ptr [rdi+1]
跳转到分发器,分发器跳转到分发表(0x80处开始)
构造 JOP 链 - 分析寄存器赋值
目标要处理的寄存器是:
●
rax = 0x3b
●
rdi = 指向
/bin/sh
的指针
●
rsi = 0
●
rdx = 0
可控rdi的gadget只有一个:通过rcx来赋值,然后跳转到rdx,需要rcx和rdx可控,rcx执行字符串地址,rdx指向分发器
rcx的值需要是指针,这里还有一个gadget能完成:
可控rax的gadget也只有一个:通过rdx赋值,跳转到rcx,需要rdx和rcx可控,rdx=0x3b,rcx指向分发器(因为初始rax=0,意味着后续在执行到这之前,rax始终是0,所以同时这里还能满足最后要rdx=0的条件
对于rsi,可以在初始化阶段完成赋值,且后续可能不会用到
对于rdx,除了rax那个之外,也只有一个gadget,通过栈将值pop给rdx,然后跳转到rcx
构造 JOP 链
rdx和rcx都是初始可控的,可以手动指向分发器
根据刚刚找出的gadget分析,最难搞的是让rcx指向字符串地址,但是也有gadget可以完成赋值,所以先凑rax还是rdi都行,这里以先rdi为例进行构造
所以第一步,先完成rdi指向字符串的目标
这里设置rcx指向字符串地址,rdx指向分发表,完成第一次跳转:
结束之后,rcx是不可用的数据,准备进入下一次跳转
第二步,设置rdx,这里的gadget可以修复变得不可用的rcx的值:
通过栈提供rdx需要的值(0x3b),后续赋值rax使用
此时的payload:
此时rsi=0,rdx=0x3b,rdi=sh字符串地址,rax=0
去完成rax的设置:
最后rcx依然指向分发器:
此时参数已经凑齐了,下一次跳转依然从分发表中取值,只需要指向syscall的地址即可
完整exp
总结
JOP链构造的思路:
1
找分发器和分发表
2
找到可能要用的gadget(例如我需要对某个寄存器赋值,找到相关gadget)
3
分析可能要用到的gadget,在分发器结构不变的情况下,串联gadget
参考资料
●
[1]
Hack-The-Box-pwn-challenge[no-return] | 0xfd's blog
●
[2]
Will's Root: Jump Oriented Programming and Call Oriented Programming (JOP and PCOP)
●
[3]
asiaccs11.pdf
●
[4]
No Return | 7Rocky
0
人收藏
0
人喜欢
转载
分享
0
条评论
某人
表情
可输入
255
字
评论
发布投稿
热门文章
1
从零掌握java内存马大全(基于LearnJavaMemshellFromZero复现重组)
2
突破网络限制,Merlin Agent助你轻松搭建跳板网络!
3
从白帽角度浅谈SRC业务威胁情报挖掘与实战
4
基于规则的流量加解密工具-CloudX
5
从0到1大模型MCP自动化漏洞挖掘实践
近期热点
一周
月份
季度
1
从零掌握java内存马大全(基于LearnJavaMemshellFromZero复现重组)
2
突破网络限制,Merlin Agent助你轻松搭建跳板网络!
3
从白帽角度浅谈SRC业务威胁情报挖掘与实战
4
基于规则的流量加解密工具-CloudX
5
从0到1大模型MCP自动化漏洞挖掘实践
暂无相关信息
暂无相关信息
优秀作者
1
T0daySeeker
贡献值:38700
2
一天
贡献值:24800
3
Yale
贡献值:21000
4
1674701160110592
贡献值:18000
5
1174735059082055
贡献值:16000
6
Loora1N
贡献值:13000
7
bkbqwq
贡献值:12800
8
手术刀
贡献值:11000
9
lufei
贡献值:11000
10
xsran
贡献值:10600
目录
前言
题目情况
逆向分析
利用分析
利用思路分析
ROP 和 JOP
找到 JOP 分发器 gadget
构造 JOP 链 - 初始形态
构造 JOP 链 - 分析寄存器赋值
构造 JOP 链
完整exp
总结
参考资料
转载
标题
作者:
你好
http://www.a.com/asdsabdas
文章
转载
自
复制到剪贴板