Off by one overflow
Reading time: 5 minutes
tip
Impara e pratica l'Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica l'Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)
Supporta HackTricks
- Controlla i piani di abbonamento!
- Unisciti al 💬 gruppo Discord o al gruppo telegram o seguici su Twitter 🐦 @hacktricks_live.
- Condividi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos di github.
Basic Information
Avere accesso a un overflow di 1B consente a un attaccante di modificare il campo size
del chunk successivo. Questo consente di manomettere quali chunk sono effettivamente liberati, generando potenzialmente un chunk che contiene un altro chunk legittimo. L'exploitation è simile a double free o chunk sovrapposti.
Ci sono 2 tipi di vulnerabilità off by one:
- Byte arbitrario: Questo tipo consente di sovrascrivere quel byte con qualsiasi valore
- Byte nullo (off-by-null): Questo tipo consente di sovrascrivere quel byte solo con 0x00
- Un esempio comune di questa vulnerabilità può essere visto nel seguente codice dove il comportamento di
strlen
estrcpy
è incoerente, il che consente di impostare un byte 0x00 all'inizio del chunk successivo. - Questo può essere sfruttato con il House of Einherjar.
- Se si utilizza Tcache, questo può essere sfruttato in una situazione di double free.
Off-by-null
// From https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/off_by_one/
int main(void)
{
char buffer[40]="";
void *chunk1;
chunk1 = malloc(24);
puts("Get Input");
gets(buffer);
if(strlen(buffer)==24)
{
strcpy(chunk1,buffer);
}
return 0;
}
Tra i vari controlli, ora ogni volta che un chunk è libero, la dimensione precedente viene confrontata con la dimensione configurata nel chunk dei metadati, rendendo questo attacco piuttosto complesso dalla versione 2.28.
Esempio di codice:
- https://github.com/DhavalKapil/heap-exploitation/blob/d778318b6a14edad18b20421f5a06fa1a6e6920e/assets/files/shrinking_free_chunks.c
- Questo attacco non funziona più a causa dell'uso di Tcaches.
- Inoltre, se provi ad abusarne utilizzando chunk più grandi (quindi i tcaches non sono coinvolti), riceverai l'errore:
malloc(): invalid next size (unsorted)
Obiettivo
- Far sì che un chunk sia contenuto all'interno di un altro chunk in modo che l'accesso in scrittura su quel secondo chunk consenta di sovrascrivere quello contenuto
Requisiti
- Off by one overflow per modificare le informazioni sulla dimensione dei metadati
Attacco generale off-by-one
- Allocare tre chunk
A
,B
eC
(diciamo dimensioni 0x20), e un altro per prevenire la consolidazione con il top-chunk. - Liberare
C
(inserito nella lista libera Tcache da 0x20). - Usare il chunk
A
per sovrascrivereB
. Abusare dell'off-by-one per modificare il camposize
diB
da 0x21 a 0x41. - Ora abbiamo
B
che contiene il chunk liberoC
- Liberare
B
e allocare un chunk da 0x40 (verrà posizionato qui di nuovo) - Possiamo modificare il puntatore
fd
diC
, che è ancora libero (avvelenamento Tcache)
Attacco off-by-null
- 3 chunk di memoria (a, b, c) vengono riservati uno dopo l'altro. Poi il chunk centrale viene liberato. Il primo contiene una vulnerabilità di overflow off by one e l'attaccante ne abusa con un 0x00 (se il byte precedente era 0x10 farebbe sì che il chunk centrale indichi che è 0x10 più piccolo di quanto non sia realmente).
- Poi, vengono allocati 2 chunk più piccoli nel chunk liberato centrale (b), tuttavia, poiché
b + b->size
non aggiorna mai il chunk c perché l'indirizzo puntato è più piccolo di quanto dovrebbe. - Poi, b1 e c vengono liberati. Poiché
c - c->prev_size
punta ancora a b (b1 ora), entrambi vengono consolidati in un chunk. Tuttavia, b2 è ancora all'interno tra b1 e c. - Infine, viene eseguita una nuova malloc reclamando quest'area di memoria che conterrà effettivamente b2, consentendo al proprietario della nuova malloc di controllare il contenuto di b2.
Questa immagine spiega perfettamente l'attacco:
Altri Esempi & Riferimenti
- https://heap-exploitation.dhavalkapil.com/attacks/shrinking_free_chunks
- Bon-nie-appetit. HTB Cyber Apocalypse CTF 2022
- Off-by-one a causa di
strlen
che considera il camposize
del chunk successivo. - Tcache è in uso, quindi un attacco generale off-by-one funziona per ottenere una scrittura arbitraria con avvelenamento Tcache.
- Asis CTF 2016 b00ks
- È possibile abusare di un off by one per rivelare un indirizzo dall'heap perché il byte 0x00 alla fine di una stringa viene sovrascritto dal campo successivo.
- La scrittura arbitraria è ottenuta abusando della scrittura off by one per far puntare il puntatore a un altro luogo dove verrà costruita una struttura falsa con puntatori falsi. Poi, è possibile seguire il puntatore di questa struttura per ottenere una scrittura arbitraria.
- L'indirizzo libc viene rivelato perché se l'heap viene esteso utilizzando mmap, la memoria allocata da mmap ha un offset fisso rispetto a libc.
- Infine, la scrittura arbitraria viene abusata per scrivere nell'indirizzo di __free_hook con un one gadget.
- plaidctf 2015 plaiddb
- Esiste una vulnerabilità off by one NULL nella funzione
getline
che legge le righe di input dell'utente. Questa funzione viene utilizzata per leggere la "chiave" del contenuto e non il contenuto. - Nella scrittura vengono creati 5 chunk iniziali:
- chunk1 (0x200)
- chunk2 (0x50)
- chunk5 (0x68)
- chunk3 (0x1f8)
- chunk4 (0xf0)
- chunk difensivo (0x400) per evitare la consolidazione con il top chunk
- Poi i chunk 1, 5 e 3 vengono liberati, quindi:
-
[ 0x200 Chunk 1 (free) ] [ 0x50 Chunk 2 ] [ 0x68 Chunk 5 (free) ] [ 0x1f8 Chunk 3 (free) ] [ 0xf0 Chunk 4 ] [ 0x400 Chunk defense ]
- Poi abusando di chunk3 (0x1f8) l'off-by-one nullo viene abusato scrivendo il prev_size a `0x4e0`.
- Nota come le dimensioni dei chunk inizialmente allocati 1, 2, 5 e 3 più le intestazioni di 4 di quei chunk siano uguali a `0x4e0`: `hex(0x1f8 + 0x10 + 0x68 + 0x10 + 0x50 + 0x10 + 0x200) = 0x4e0`
- Poi, il chunk 4 viene liberato, generando un chunk che consuma tutti i chunk fino all'inizio:
- ```python
[ 0x4e0 Chunk 1-2-5-3 (free) ] [ 0xf0 Chunk 4 (corrupted) ] [ 0x400 Chunk defense ]
[ 0x200 Chunk 1 (free) ] [ 0x50 Chunk 2 ] [ 0x68 Chunk 5 (free) ] [ 0x1f8 Chunk 3 (free) ] [ 0xf0 Chunk 4 ] [ 0x400 Chunk defense ]