hacktricks/binary-exploitation/libc-heap/off-by-one-overflow.md

136 lines
9.2 KiB
Markdown

# Prekoračenje za jedan bajt
{% hint style="success" %}
Naučite i vežbajte hakovanje AWS-a:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
Naučite i vežbajte hakovanje GCP-a: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
<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 hakovanje trikova slanjem PR-ova na** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repozitorijume.
</details>
{% endhint %}
## Osnovne informacije
Imajući samo pristup prekoračenju za 1B, napadač može izmeniti polje `size` sledećeg bloka. Ovo omogućava manipulaciju blokovima koji su zapravo oslobođeni, potencijalno generišući blok koji sadrži drugi legitimni blok. Eksploatacija je slična [dvostrukom oslobođavanju](double-free.md) ili preklapanju blokova.
Postoje 2 vrste ranjivosti prekoračenja za jedan bajt:
* Proizvoljan bajt: Ova vrsta omogućava prepisivanje tog bajta sa bilo kojom vrednošću
* Nula bajt (off-by-null): Ova vrsta omogućava prepisivanje tog bajta samo sa 0x00
* Čest primer ove ranjivosti može se videti u sledećem kodu gde je ponašanje `strlen` i `strcpy` nekonzistentno, što omogućava postavljanje bajta 0x00 na početku sledećeg bloka.
* Ovo se može iskoristiti sa [House of Einherjar](house-of-einherjar.md).
* Ako se koristi Tcache, ovo se može iskoristiti u situaciju [dvostrukog oslobođavanja](double-free.md).
<details>
<summary>Off-by-null</summary>
```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;
}
```
</details>
Između ostalih provera, sada kada je komad slobodan, prethodna veličina se upoređuje sa veličinom konfigurisanom u metapodacima komada, čineći ovaj napad prilično složenim od verzije 2.28.
### Primer koda:
* [https://github.com/DhavalKapil/heap-exploitation/blob/d778318b6a14edad18b20421f5a06fa1a6e6920e/assets/files/shrinking\_free\_chunks.c](https://github.com/DhavalKapil/heap-exploitation/blob/d778318b6a14edad18b20421f5a06fa1a6e6920e/assets/files/shrinking\_free\_chunks.c)
* Ovaj napad više ne funkcioniše zbog korišćenja Tcache-a.
* Štaviše, ako pokušate da ga zloupotrebite koristeći veće komade (tako da Tcache-i nisu uključeni), dobićete grešku: `malloc(): invalid next size (unsorted)`
### Cilj
* Da se komad nalazi unutar drugog komada, tako da pristup pisanju preko tog drugog komada omogućava prepisivanje sadržaja sadržanog komada
### Zahtevi
* Prekoračenje za jedan bajt kako bi se izmenile informacije o veličini metapodataka
### Opšti napad off-by-one
* Alocirajte tri komada `A`, `B` i `C` (recimo veličine 0x20), i još jedan da spreči konsolidaciju sa vršnim komadom.
* Oslobodite `C` (ubacen u 0x20 Tcache listu slobodnih komada).
* Koristite komad `A` da prekoračite na `B`. Iskoristite off-by-one da izmenite polje `size` u `B` sa 0x21 na 0x41.
* Sada imamo `B` koji sadrži slobodan komad `C`
* Oslobodite `B` i alocirajte 0x40 komad (biće ponovo postavljen ovde)
* Možemo izmeniti pokazivač `fd` iz `C`, koji je i dalje slobodan (Tcache trovanje)
### Off-by-null napad
* Rezervišite 3 komada memorije (a, b, c) jedan za drugim. Zatim se oslobađa srednji komad. Prvi komad sadrži ranjivost prekoračenja za jedan bajt i napadač je zloupotrebljava sa 0x00 (ako je prethodni bajt bio 0x10, to bi navelo srednji komad da pokaže da je 0x10 manji nego što zaista jeste).
* Zatim se alociraju još 2 manja komada u oslobodjenom srednjem komadu (b), međutim, pošto `b + b->size` nikada ne ažurira c komad jer je pokazana adresa manja nego što bi trebalo.
* Zatim se oslobađaju b1 i c. Pošto `c - c->prev_size` i dalje pokazuje na b (sada b1), oba se konsoliduju u jedan komad. Međutim, b2 je i dalje unutar između b1 i c.
* Na kraju, vrši se nova alokacija memorije koja će zapravo sadržati b2, omogućavajući vlasniku nove alokacije da kontroliše sadržaj b2.
Ova slika savršeno objašnjava napad:
<figure><img src="../../.gitbook/assets/image (1247).png" alt=""><figcaption><p><a href="https://heap-exploitation.dhavalkapil.com/attacks/shrinking_free_chunks">https://heap-exploitation.dhavalkapil.com/attacks/shrinking_free_chunks</a></p></figcaption></figure>
## Ostali primeri i reference
* [**https://heap-exploitation.dhavalkapil.com/attacks/shrinking\_free\_chunks**](https://heap-exploitation.dhavalkapil.com/attacks/shrinking\_free\_chunks)
* [**Bon-nie-appetit. HTB Cyber Apocalypse CTF 2022**](https://7rocky.github.io/en/ctf/htb-challenges/pwn/bon-nie-appetit/)
* Off-by-one zbog `strlen` koji uzima u obzir polje `size` sledećeg komada.
* Koristi se Tcache, pa opšti off-by-one napadi funkcionišu kako bi se dobio proizvoljni zapis sa Tcache trovanjem.
* [**Asis CTF 2016 b00ks**](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/off\_by\_one/#1-asis-ctf-2016-b00ks)
* Moguće je zloupotrebiti off-by-one da bi se procurela adresa iz hipa jer bajt 0x00 na kraju stringa biva prepisan sledećim poljem.
* Proizvoljni zapis se dobija zloupotrebom off-by-one zapisa kako bi se pokazivač usmerio na drugo mesto gde će biti izgrađena lažna struktura sa lažnim pokazivačima. Zatim je moguće pratiti pokazivač ove strukture kako bi se dobio proizvoljni zapis.
* Adresa libc-a procuri jer ako se hip proširi korišćenjem mmap, memorija alocirana pomoću mmap ima fiksni offset od libc-a.
* Na kraju se zloupotrebljava proizvoljni zapis kako bi se upisalo na adresu \_\_free\_hook sa jednim gedžetom.
* [**plaidctf 2015 plaiddb**](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/off\_by\_one/#instance-2-plaidctf-2015-plaiddb)
* Postoji NULL off-by-one ranjivost u funkciji `getline` koja čita linije korisničkog unosa. Ova funkcija se koristi za čitanje "ključa" sadržaja, a ne samog sadržaja.
* U objašnjenju se stvara 5 početnih komada:
* komad1 (0x200)
* komad2 (0x50)
* komad5 (0x68)
* komad3 (0x1f8)
* komad4 (0xf0)
* komad odbrane (0x400) kako bi se izbegla konsolidacija sa vršnim komadom
* Zatim se oslobađuju komadi 1, 5 i 3, tako da:
* ```python
[ 0x200 Komad 1 (slobodan) ] [ 0x50 Komad 2 ] [ 0x68 Komad 5 (slobodan) ] [ 0x1f8 Komad 3 (slobodan) ] [ 0xf0 Komad 4 ] [ 0x400 Komad odbrane ]
```
* Zatim se zloupotrebljava komad3 (0x1f8) null off-by-one zapisom prev\_size na `0x4e0`.
* Primetite kako veličine početno alociranih komada1, 2, 5 i 3 plus zaglavlja 4 tih komada iznose `0x4e0`: `hex(0x1f8 + 0x10 + 0x68 + 0x10 + 0x50 + 0x10 + 0x200) = 0x4e0`
* Zatim se oslobađuje komad 4, generišući komad koji troši sve komade do početka:
* ```python
[ 0x4e0 Komad 1-2-5-3 (slobodan) ] [ 0xf0 Komad 4 (korumpiran) ] [ 0x400 Komad odbrane ]
```
* ```python
[ 0x200 Komad 1 (slobodan) ] [ 0x50 Komad 2 ] [ 0x68 Komad 5 (slobodan) ] [ 0x1f8 Komad 3 (slobodan) ] [ 0xf0 Komad 4 ] [ 0x400 Komad odbrane ]
```
* Zatim se alocira `0x200` bajtova popunjavajući originalni komad 1
* I alocira se još 0x200 bajtova i uništava se komad2 i stoga nema curenja i ovo ne funkcioniše? Možda ovo ne bi trebalo da se uradi
* Zatim se alocira još jedan komad sa 0x58 "a" (prepisujući komad2 i dosežući komad5) i menja se `fd` brze binarne grupe komada komada5 usmeravajući ga ka `__malloc_hook`
* Zatim se alocira komad od 0x68 tako da je lažni brzi binarni komad u `__malloc_hook` sledeći brzi binarni komad
* Na kraju, alocira se novi brzi binarni komad od 0x68 i `__malloc_hook` se prepisuje sa adresom `one_gadget`
{% hint style="success" %}
Naučite i vežbajte hakovanje AWS-a:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
Naučite i vežbajte hakovanje GCP-a: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
<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 nas **pratite** na **Twitteru** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Podelite hakovanje trikove slanjem PR-ova na** [**HackTricks**](https://github.com/carlospolop/hacktricks) **i** [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) **github repozitorijume.**