Off by one overflow
Last updated
Last updated
Naučite i vežbajte hakovanje AWS-a:HackTricks Training AWS Red Team Expert (ARTE) Naučite i vežbajte hakovanje GCP-a: HackTricks Training GCP Red Team Expert (GRTE)
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 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.
Ako se koristi Tcache, ovo se može iskoristiti u situaciju dvostrukog oslobođavanja.
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.
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)
Da se komad nalazi unutar drugog komada, tako da pristup pisanju preko tog drugog komada omogućava prepisivanje sadržaja sadržanog komada
Prekoračenje za jedan bajt kako bi se izmenile informacije o veličini metapodataka
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)
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:
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.
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.
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:
[ 0x200 Komad 1 (slobodan) ] [ 0x50 Komad 2 ] [ 0x68 Komad 5 (slobodan) ] [ 0x1f8 Komad 3 (slobodan) ] [ 0xf0 Komad 4 ] [ 0x400 Komad odbrane ]
[ 0x200 Komad 1 (slobodan) ] [ 0x50 Komad 2 ] [ 0x68 Komad 5 (slobodan) ] [ 0x1f8 Komad 3 (slobodan) ] [ 0xf0 Komad 4 ] [ 0x400 Komad odbrane ]