高级ROP之SROP利用
字数 2387 2025-08-19 12:41:42

SROP (Sigreturn Oriented Programming) 利用技术详解

1. SROP 基础知识

1.1 SROP 概念

SROP (Sigreturn Oriented Programming) 是一种利用 sigreturn 系统调用的高级ROP攻击技术。其核心原理是通过伪造 Signal Frame 来控制程序执行流程。

1.2 Signal 机制原理

Signal 机制是类 Unix 系统中进程间通信的一种方法,也称为软中断信号。其工作流程如下:

  1. 内核向进程发送 signal,进程被挂起进入内核态
  2. 内核保存进程上下文(所有寄存器压入栈中),包括:
    • Signal 信息
    • 指向 sigreturn 的系统调用地址
  3. 跳转到注册的 signal handler 处理 signal
  4. signal handler 返回后,执行 sigreturn 系统调用恢复保存的上下文

1.3 Signal Frame 结构

Signal Frame 包含以下关键部分:

  • ucontext 结构(保存的寄存器值)
  • siginfo 结构(signal 信息)
  • sigreturn 系统调用地址

32位和64位系统的 sigreturn 调用号:

  • 32位:119 (0x77)
  • 64位:15 (0xf)

2. SROP 利用条件

要成功利用 SROP 攻击,需要满足以下条件:

  1. 栈溢出:能够控制栈的内容
  2. 控制 rax 寄存器:能够设置 rax 为 sigreturn 的系统调用号
  3. syscall 可用:存在 syscall 指令或函数
  4. 足够的栈空间:能够布置伪造的 Signal Frame

3. SROP 攻击步骤

3.1 基本攻击流程

  1. 通过栈溢出劫持返回地址
  2. 构造 SROP 链:
    • 控制 rax 寄存器为 sigreturn 的系统调用号
    • 执行 syscall 进入 sigreturn 系统调用
  3. 精心构造栈布局,使 sigreturn 系统调用后的 pop 指令能够控制各寄存器

3.2 获取 shell 的寄存器设置

要执行 execve("/bin/sh", 0, 0),需要设置以下寄存器:

  • rax → 59 (execve 的系统调用号)
  • rdi → "/bin/sh" 字符串地址
  • rsi → 0
  • rdx → 0
  • rip → syscall 指令地址

4. SROP 链构造

当需要多次系统调用时(如沙箱环境下需要 open/read/write),可以构造 SROP 链:

  1. 通过设置 rsp 寄存器,使一个 SROP 结束后自动进入下一个 SROP
  2. 每个 SROP 负责一个特定的系统调用
  3. 链式调用直到完成所有需要的操作

5. 工具使用

pwntools 提供了方便的 SROP 构造工具 SigreturnFrame()

frame = SigreturnFrame()
frame.rax = constants.SYS_execve
frame.rdi = binsh_addr
frame.rsi = 0
frame.rdx = 0
frame.rip = syscall_addr

在 payload 中使用 bytes(frame) 将其转换为字节序列。

6. 注意事项

6.1 syscall 的两种形式

  1. syscall 函数

    • 在 IDA 中显示为 call _syscall
    • 需要遵循寄存器传参规则
    • 构造时需要考虑函数调用约定
  2. syscall 指令

    • 在 IDA 中显示为 syscall 机器码 (0F 05)
    • 通常以 sys_readsys_write 等伪代码形式出现
    • 直接执行系统调用,无需额外处理

6.2 栈空间不足的解决方案

当溢出空间不足时,可以采用栈迁移技术:

  1. 利用有限的溢出空间修改 rsp
  2. 将栈迁移到更大的空间(如 .bss 段)
  3. 在新的栈空间布置完整的 SROP 链

7. 实战案例分析

7.1 案例1:2023江西省赛初赛pwn2

漏洞点

char buf[16];
sys_read(0, buf, 0x200uLL);  // 明显的栈溢出

利用步骤

  1. 利用溢出控制返回地址
  2. 设置 rax 为 15 (sigreturn 调用号)
  3. 构造 Signal Frame 执行 execve("/bin/sh", 0, 0)

关键点

  • 通过栈迁移将控制流转移到 .bss 段
  • 分阶段构造 SROP 链(先 read 再 execve)

7.2 案例2:第六届安洵杯网络安全挑战赛pwn2

特殊条件

  • 开启了沙箱保护(仅允许 read/write/open/chmod/rt_sigreturn/exit_group)
  • 输入长度有限(需要栈迁移)

利用步骤

  1. 利用有限的溢出空间进行栈迁移
  2. 将栈迁移到 .bss 段的大空间
  3. 构造三段式 SROP 链:
    • open("./flag", 0, 0)
    • read(3, buf, 0x50) // 3 是打开的文件描述符
    • write(1, buf, 0x50) // 1 是标准输出

关键点

  • 通过调试确定 rsp 的正确位置
  • 确保每个 SROP 结束后 rsp 指向下一个 SROP 的起始点
  • 处理文件描述符的传递

8. 调试技巧

  1. 使用 gdb 调试时,可以在关键位置设置断点:

    gdb.attach(io, 'b *0x40136e')
    
  2. 观察栈布局和寄存器变化,确保 Signal Frame 被正确解析

  3. 对于复杂的 SROP 链,可以分段调试,确保每一段都能正确执行

9. 防御措施

  1. 启用栈保护机制(如 Canary)
  2. 限制 sigreturn 系统调用的使用
  3. 使用地址随机化(ASLR)增加预测难度
  4. 对敏感系统调用进行过滤

10. 总结

SROP 是一种强大的攻击技术,它通过伪造 Signal Frame 实现了对程序完全控制。相比传统 ROP,SROP 具有以下优势:

  1. 一次性设置所有寄存器,减少 gadget 需求
  2. 可以构造复杂的调用链
  3. 在沙箱环境下尤其有效

掌握 SROP 技术需要深入理解 signal 机制和系统调用约定,通过实际案例练习可以更好地掌握这一技术。

SROP (Sigreturn Oriented Programming) 利用技术详解 1. SROP 基础知识 1.1 SROP 概念 SROP (Sigreturn Oriented Programming) 是一种利用 sigreturn 系统调用的高级ROP攻击技术。其核心原理是通过伪造 Signal Frame 来控制程序执行流程。 1.2 Signal 机制原理 Signal 机制是类 Unix 系统中进程间通信的一种方法,也称为软中断信号。其工作流程如下: 内核向进程发送 signal,进程被挂起进入内核态 内核保存进程上下文(所有寄存器压入栈中),包括: Signal 信息 指向 sigreturn 的系统调用地址 跳转到注册的 signal handler 处理 signal signal handler 返回后,执行 sigreturn 系统调用恢复保存的上下文 1.3 Signal Frame 结构 Signal Frame 包含以下关键部分: ucontext 结构(保存的寄存器值) siginfo 结构(signal 信息) sigreturn 系统调用地址 32位和64位系统的 sigreturn 调用号: 32位:119 (0x77) 64位:15 (0xf) 2. SROP 利用条件 要成功利用 SROP 攻击,需要满足以下条件: 栈溢出 :能够控制栈的内容 控制 rax 寄存器 :能够设置 rax 为 sigreturn 的系统调用号 syscall 可用 :存在 syscall 指令或函数 足够的栈空间 :能够布置伪造的 Signal Frame 3. SROP 攻击步骤 3.1 基本攻击流程 通过栈溢出劫持返回地址 构造 SROP 链: 控制 rax 寄存器为 sigreturn 的系统调用号 执行 syscall 进入 sigreturn 系统调用 精心构造栈布局,使 sigreturn 系统调用后的 pop 指令能够控制各寄存器 3.2 获取 shell 的寄存器设置 要执行 execve("/bin/sh", 0, 0) ,需要设置以下寄存器: rax → 59 ( execve 的系统调用号) rdi → "/bin/sh" 字符串地址 rsi → 0 rdx → 0 rip → syscall 指令地址 4. SROP 链构造 当需要多次系统调用时(如沙箱环境下需要 open/read/write),可以构造 SROP 链: 通过设置 rsp 寄存器,使一个 SROP 结束后自动进入下一个 SROP 每个 SROP 负责一个特定的系统调用 链式调用直到完成所有需要的操作 5. 工具使用 pwntools 提供了方便的 SROP 构造工具 SigreturnFrame() : 在 payload 中使用 bytes(frame) 将其转换为字节序列。 6. 注意事项 6.1 syscall 的两种形式 syscall 函数 : 在 IDA 中显示为 call _syscall 需要遵循寄存器传参规则 构造时需要考虑函数调用约定 syscall 指令 : 在 IDA 中显示为 syscall 机器码 (0F 05) 通常以 sys_read 、 sys_write 等伪代码形式出现 直接执行系统调用,无需额外处理 6.2 栈空间不足的解决方案 当溢出空间不足时,可以采用栈迁移技术: 利用有限的溢出空间修改 rsp 将栈迁移到更大的空间(如 .bss 段) 在新的栈空间布置完整的 SROP 链 7. 实战案例分析 7.1 案例1:2023江西省赛初赛pwn2 漏洞点 : 利用步骤 : 利用溢出控制返回地址 设置 rax 为 15 ( sigreturn 调用号) 构造 Signal Frame 执行 execve("/bin/sh", 0, 0) 关键点 : 通过栈迁移将控制流转移到 .bss 段 分阶段构造 SROP 链(先 read 再 execve) 7.2 案例2:第六届安洵杯网络安全挑战赛pwn2 特殊条件 : 开启了沙箱保护(仅允许 read/write/open/chmod/rt_ sigreturn/exit_ group) 输入长度有限(需要栈迁移) 利用步骤 : 利用有限的溢出空间进行栈迁移 将栈迁移到 .bss 段的大空间 构造三段式 SROP 链: open("./flag", 0, 0) read(3, buf, 0x50) // 3 是打开的文件描述符 write(1, buf, 0x50) // 1 是标准输出 关键点 : 通过调试确定 rsp 的正确位置 确保每个 SROP 结束后 rsp 指向下一个 SROP 的起始点 处理文件描述符的传递 8. 调试技巧 使用 gdb 调试时,可以在关键位置设置断点: 观察栈布局和寄存器变化,确保 Signal Frame 被正确解析 对于复杂的 SROP 链,可以分段调试,确保每一段都能正确执行 9. 防御措施 启用栈保护机制(如 Canary) 限制 sigreturn 系统调用的使用 使用地址随机化(ASLR)增加预测难度 对敏感系统调用进行过滤 10. 总结 SROP 是一种强大的攻击技术,它通过伪造 Signal Frame 实现了对程序完全控制。相比传统 ROP,SROP 具有以下优势: 一次性设置所有寄存器,减少 gadget 需求 可以构造复杂的调用链 在沙箱环境下尤其有效 掌握 SROP 技术需要深入理解 signal 机制和系统调用约定,通过实际案例练习可以更好地掌握这一技术。