Off by one overflow
Tip
Učite i vežbajte AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Učite i vežbajte Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Podržite HackTricks
- Proverite planove pretplate!
- Pridružite se 💬 Discord grupi ili telegram grupi ili pratite nas na Twitteru 🐦 @hacktricks_live.
- Podelite hakerske trikove slanjem PR-ova na HackTricks i HackTricks Cloud github repozitorijume.
Osnovne informacije
Imanje pristupa 1B overflow-u omogućava napadaču da izmeni size polje narednog chunk-a. Ovo omogućava manipulisanje kojim chunk-ovima se zapravo free-uje, potencijalno generišući chunk koji sadrži drugi legitimni chunk. Eksploatacija je slična double free ili preklapajućim chunk-ovima.
Postoje 2 vrste off by one ranjivosti:
- Arbitrary byte: Ovaj tip omogućava prepisivanje tog bajta bilo kojom vrednošću
- Null byte (off-by-null): Ovaj tip omogućava prepisivanje tog bajta samo sa 0x00
- Uobičajen primer ove ranjivosti vidi se u sledećem kodu gde je ponašanje
strlenistrcpynekonzistentno, što dozvoljava postavljanje 0x00 bajta na početak narednog chunk-a. - Ovo se može iskoristiti pomoću House of Einherjar.
- Ako se koristi Tcache, ovo se može iskoristiti za double free situaciju.
Off-by-null
```c // 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; } ```Između ostalog, sada kad god je chunk free, prethodni size se poredi sa size-om podešenim u chunk-ovim metadata poljima, što čini ovaj attack prilično složenim od verzije 2.28.
Primer koda:
- https://github.com/DhavalKapil/heap-exploitation/blob/d778318b6a14edad18b20421f5a06fa1a6e6920e/assets/files/shrinking_free_chunks.c
- Ovaj attack više ne radi zbog upotrebe Tcaches.
- Štaviše, ako pokušaš da ga zloupotrebiš koristeći veće chunks (tako da tcaches nisu uključeni), dobićeš grešku:
malloc(): invalid next size (unsorted)
Cilj
- Naterati jedan chunk da bude sadržan unutar drugog chunk-a tako da pisanje preko drugog chunk-a dozvoljava prepisivanje sadržanog chunka
Zahtevi
- Off by one overflow za modifikovanje size metadata informacija
General off-by-one attack
- Allocate tri chunk-a
A,BiC(npr. sizes 0x20), i još jedan da se spreči consolidation sa top-chunk-om. - Free
C(ubacen u 0x20 Tcache free-list). - Iskoristi chunk
Ada overflovuješB. Iskoristi off-by-one da modifikuješsizepoljeBsa 0x21 na 0x41. - Sada imamo
Bkoji sadrži free chunkC - Free
Bi allocate-uj 0x40 chunk (biće postavljen ovde ponovo) - Možemo modifikovati
fdpointer izC, koji je još uvek free (Tcache poisoning)
Off-by-null attack
- Rezervisana su 3 chunka memorije (a, b, c) jedan za drugim. Zatim se srednji free-uje. Prvi sadrži off by one overflow ranjivost i napadač je zloupotrebljava sa 0x00 (ako je prethodni bajt bio 0x10 to bi nateralo srednji chunk da ukaže da je 0x10 manji nego što zaista jeste).
- Zatim se alociraju još 2 manja chunka u srednjem free-ovanom chunk-u (b), mada, pošto
b + b->sizenikada ne ažurira c chunk zato što pokazana adresa je manja nego što treba. - Zatim se b1 i c free-uju. Pošto
c - c->prev_sizei dalje pokazuje na b (sada b1), oba se konsoliduju u jedan chunk. Međutim, b2 je i dalje između b1 i c. - Na kraju, izvodi se novi malloc koji preuzima ovo memorijsko područje koje zapravo sadrži b2, što omogućava vlasniku novog malloc-a da kontroliše sadržaj b2.
This image explains perfectly the attack:
.png)
https://heap-exploitation.dhavalkapil.com/attacks/shrinking_free_chunks
Moderni glibc hardening i napomene za bypass (>=2.32)
- Safe-Linking sada štiti svaki singly linked bin pointer čuvajući
fd = ptr ^ (chunk_addr >> 12), pa off-by-one koji menja samo najniži bajtsizeobično takođe zahteva heap leak da bi se ponovo izračunao XOR mask pre nego što Tcache poisoning funkcioniše. - A practical leakless trick is to “double-protect” a pointer: encode a pointer you already control with
PROTECT_PTR, then reuse the same gadget to encode your forged pointer so the alignment check passes without revealing new addresses. - Workflow za Safe-Linking + single-byte corruptions:
- Grow the victim chunk until it fully covers a freed chunk you already control (overlapping-chunk setup).
- Leak any heap pointer (stdout, UAF, partially controlled struct) and derive the key
heap_base >> 12. - Re-encode free-list pointers before writing them—stage the encoded value inside user data and memcpy it later if you only own single-byte writes.
- Combine with Tcache bin attacks to redirect allocations into
__free_hookortcache_perthread_structentries once the forged pointer is properly encoded.
A minimal helper to rehearse the encode/decode step while debugging modern exploits:
def protect(ptr, chunk_addr):
return ptr ^ (chunk_addr >> 12)
def reveal(encoded, chunk_addr):
return encoded ^ (chunk_addr >> 12)
chunk = 0x55555555c2c0
encoded_fd = protect(0xdeadbeefcaf0, chunk)
print(hex(reveal(encoded_fd, chunk))) # 0xdeadbeefcaf0
Nedavni stvarni cilj: glibc __vsyslog_internal off-by-one (CVE-2023-6779)
- U januaru 2024 Qualys je detaljno opisao CVE-2023-6779, off-by-one u
__vsyslog_internal()koji se aktivira kadasyslog()/vsyslog()format stringovi premašeINT_MAX, pa terminirajući\0korumpira najmanje značajni bajt poljasizenarednog chunk-a na sistemima sa glibc 2.37–2.39 (Qualys advisory). - Njihov exploit pipeline za Fedora 38:
- Napraviti predugačak
openlog()ident tako davasprintfvrati heap buffer pored podataka koje kontroliše napadač. - Pozvati
syslog()da prepiše bajtsize | prev_inusesusednog chunk-a, osloboditi ga i prisiliti konsolidaciju koja prekriva podatke napadača. - Iskoristiti preklapajući prikaz da korumpira
tcache_perthread_structmetadata i usmeriti narednu alokaciju na__free_hook, prepisujući je sasystem/one_gadget za root.
- Da biste reprodukovali corrupting write u harness-u, fork-ujte se sa gigantskim
argv[0], pozoviteopenlog(NULL, LOG_PID, LOG_USER)i zatimsyslog(LOG_INFO, "%s", payload)gde jepayload = b"A" * 0x7fffffff;pwndbg’sheap binsodmah prikazuje single-byte overwrite. - Ubuntu prati bag kao CVE-2023-6779, dokumentujući istu INT truncation koja ovo čini pouzdanim off-by-one primitive.
Ostali primeri & reference
- https://heap-exploitation.dhavalkapil.com/attacks/shrinking_free_chunks
- Bon-nie-appetit. HTB Cyber Apocalypse CTF 2022
- Off-by-one zato što
strlenuzima u obzir poljesizenarednog chunk-a. - Koristi se Tcache, tako da opšti off-by-one napadi rade da se dobije arbitrary write primitive pomoću Tcache poisoning.
- Asis CTF 2016 b00ks
- Moguće je zloupotrebiti off-by-one da bi se leak-ovala adresa sa heap-a zato što je bajt 0x00 kraja stringa prepisan narednim poljem.
- Arbitrary write se dobija zloupotrebom off-by-one write-a da bi se pokazivač uputio na drugo mesto gde će biti napravljena lažna struktura sa lažnim pokazivačima. Zatim je moguće slediti pokazivač te strukture da bi se ostvario arbitrary write.
- Adresa libc-a se leak-uje zato što, ako se heap proširi koristeći mmap, memorija alocirana putem mmap ima fiksni offset u odnosu na libc.
- Na kraju, arbitrary write se zloupotrebljava da se upiše u adresu
__free_hooksa one_gadget-om. - plaidctf 2015 plaiddb
- Postoji NULL off-by-one ranjivost u funkciji
getlinekoja čita linije korisničkog unosa. Ta funkcija se koristi da pročita “key” sadržaja, a ne sadržaj. - U writeupu je kreirano 5 početnih chunk-ova:
- chunk1 (0x200)
- chunk2 (0x50)
- chunk5 (0x68)
- chunk3 (0x1f8)
- chunk4 (0xf0)
- chunk defense (0x400) da se izbegne konsolidacija sa top chunk-om
- Zatim su chunk 1, 5 i 3 oslobođeni, pa:
-
[ 0x200 Chunk 1 (free) ] [ 0x50 Chunk 2 ] [ 0x68 Chunk 5 (free) ] [ 0x1f8 Chunk 3 (free) ] [ 0xf0 Chunk 4 ] [ 0x400 Chunk defense ]
- Zatim, zloupotrebljavajući chunk3 (0x1f8) null off-by-one se koristi za upis prev_size na `0x4e0`.
- Primećuje se kako veličine inicijalno alociranih chunk-ova 1, 2, 5 i 3 plus header-i četiri od tih chunk-ova jednak je `0x4e0`: `hex(0x1f8 + 0x10 + 0x68 + 0x10 + 0x50 + 0x10 + 0x200) = 0x4e0`
- Zatim je chunk 4 oslobođen, generišući chunk koji obuhvata sve chunk-ove do početka:
- ```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 ]
- Zatim je alocirano `0x200` bajtova popunjavajući originalni chunk 1
- I još jednih `0x200` bajtova je alocirano i chunk2 je uništen i stoga nema leak-a i ovo ne radi? Možda ovo ne bi trebalo raditi
- Zatim alocira još jedan chunk sa 0x58 "a"-ova (prepisujući chunk2 i dosežući chunk5) i menja `fd` fast bin chunka chunk5 da pokazuje na `__malloc_hook`
- Zatim se alocira chunk od 0x68 tako da je lažni fast bin chunk u `__malloc_hook` sledeći fast bin chunk
- Na kraju, novi fast bin chunk od 0x68 se alocira i `__malloc_hook` je prepisan sa adresom `one_gadget`
## Reference
- [Qualys Security Advisory – CVE-2023-6246/6779/6780](https://www.qualys.com/2024/01/30/cve-2023-6246/syslog.txt)
- [Ubuntu Security – CVE-2023-6779](https://ubuntu.com/security/CVE-2023-6779)
- [Breaking Safe-Linking in Modern Glibc – Google CTF 2022 "saas" analysis](https://blog.csdn.net/2402_86373248/article/details/148717274)
> [!TIP]
> Učite i vežbajte AWS Hacking:<img src="../../../../../images/arte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../../../../images/arte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">\
> Učite i vežbajte GCP Hacking: <img src="../../../../../images/grte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training GCP Red Team Expert (GRTE)**](https://training.hacktricks.xyz/courses/grte)<img src="../../../../../images/grte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">
> Učite i vežbajte Azure Hacking: <img src="../../../../../images/azrte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training Azure Red Team Expert (AzRTE)**](https://training.hacktricks.xyz/courses/azrte)<img src="../../../../../images/azrte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">
>
> <details>
>
> <summary>Podržite HackTricks</summary>
>
> - Proverite [**planove pretplate**](https://github.com/sponsors/carlospolop)!
> - **Pridružite se** 💬 [**Discord grupi**](https://discord.gg/hRep4RUj7f) ili [**telegram grupi**](https://t.me/peass) ili **pratite** nas na **Twitteru** 🐦 [**@hacktricks_live**](https://twitter.com/hacktricks_live)**.**
> - **Podelite hakerske trikove slanjem PR-ova na** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repozitorijume.
>
> </details>
HackTricks

