113 lines
5.7 KiB
Markdown

# House of Roman
{{#include ../../banners/hacktricks-training.md}}
## Osnovne informacije
Ovo je bila veoma zanimljiva tehnika koja je omogućila RCE bez leak-ova putem lažnih fastbins, napada na unsorted_bin i relativnih prepisivanja. Međutim, to je [**zakrpljeno**](https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=b90ddd08f6dd688e651df9ee89ca3a69ff88cd0c).
### Kod
- Možete pronaći primer na [https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c)
### Cilj
- RCE zloupotrebom relativnih pokazivača
### Zahtevi
- Urediti fastbin i unsorted bin pokazivače
- 12 bita nasumičnosti mora biti brute-forced (0.02% šanse) da uspe
## Koraci napada
### Deo 1: Fastbin Chunk pokazuje na \_\_malloc_hook
Kreirajte nekoliko chunk-ova:
- `fastbin_victim` (0x60, offset 0): UAF chunk koji će kasnije urediti pokazivač na heap da pokazuje na LibC vrednost.
- `chunk2` (0x80, offset 0x70): Za dobru poravnanje
- `main_arena_use` (0x80, offset 0x100)
- `relative_offset_heap` (0x60, offset 0x190): relativni offset na 'main_arena_use' chunk
Zatim `free(main_arena_use)` koji će staviti ovaj chunk u unsorted listu i dobiti pokazivač na `main_arena + 0x68` u oba `fd` i `bk` pokazivača.
Sada se alocira novi chunk `fake_libc_chunk(0x60)` jer će sadržati pokazivače na `main_arena + 0x68` u `fd` i `bk`.
Zatim se oslobađaju `relative_offset_heap` i `fastbin_victim`.
```c
/*
Current heap layout:
0x0: fastbin_victim - size 0x70
0x70: alignment_filler - size 0x90
0x100: fake_libc_chunk - size 0x70 (contains a fd ptr to main_arena + 0x68)
0x170: leftover_main - size 0x20
0x190: relative_offset_heap - size 0x70
bin layout:
fastbin: fastbin_victim -> relative_offset_heap
unsorted: leftover_main
*/
```
- `fastbin_victim` ima `fd` koji pokazuje na `relative_offset_heap`
- `relative_offset_heap` je ofset udaljenosti od `fake_libc_chunk`, koji sadrži pokazivač na `main_arena + 0x68`
- Promenom poslednjeg bajta `fastbin_victim.fd` moguće je da `fastbin_victim` pokazuje na `main_arena + 0x68`
Za prethodne akcije, napadač treba da bude sposoban da modifikuje fd pokazivač `fastbin_victim`.
Zatim, `main_arena + 0x68` nije toliko zanimljiv, pa hajde da ga modifikujemo tako da pokazivač pokazuje na **`__malloc_hook`**.
Napomena da `__memalign_hook` obično počinje sa `0x7f` i nulama pre njega, tako da je moguće da se lažno predstavi kao vrednost u `0x70` brzom binu. Pošto su poslednja 4 bita adrese **nasumična**, postoji `2^4=16` mogućnosti za vrednost da završi na mestu koje nas zanima. Tako se ovde izvodi BF napad tako da se komad završi kao: **`0x70: fastbin_victim -> fake_libc_chunk -> (__malloc_hook - 0x23)`.**
(Za više informacija o ostalim bajtovima proverite objašnjenje u [how2heap](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c)[ primeru](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c)). Ako BF ne uspe, program se jednostavno sruši (tako da ponovo pokušajte dok ne uspe).
Zatim, izvršavaju se 2 malloc-a da se uklone 2 inicijalna fast bin komada, a treći se alocira da dobije komad u **`__malloc_hook:`**
```c
malloc(0x60);
malloc(0x60);
uint8_t* malloc_hook_chunk = malloc(0x60);
```
### Deo 2: Unsorted_bin napad
Za više informacija možete proveriti:
{{#ref}}
unsorted-bin-attack.md
{{#endref}}
Ali u suštini omogućava da se napiše `main_arena + 0x68` na bilo koju lokaciju koju odredimo u `chunk->bk`. I za napad biramo `__malloc_hook`. Zatim, nakon prepisivanja, koristićemo relativno prepisivanje da usmerimo na `one_gadget`.
Za ovo počinjemo da dobijamo chunk i stavljamo ga u **unsorted bin**:
```c
uint8_t* unsorted_bin_ptr = malloc(0x80);
malloc(0x30); // Don't want to consolidate
puts("Put chunk into unsorted_bin\n");
// Free the chunk to create the UAF
free(unsorted_bin_ptr);
```
Iskoristite UAF u ovom delu da usmerite `unsorted_bin_ptr->bk` na adresu `__malloc_hook` (to smo prethodno brute-forcovali).
> [!CAUTION]
> Imajte na umu da ovaj napad korumpira nesortiranu kantu (takođe malu i veliku). Dakle, možemo samo **koristiti alokacije iz brze kante sada** (složeniji program može izvršiti druge alokacije i srušiti se), a da bismo to pokrenuli, moramo **alokirati istu veličinu ili će se program srušiti.**
Dakle, da bismo pokrenuli pisanje `main_arena + 0x68` u `__malloc_hook`, nakon postavljanja `__malloc_hook` u `unsorted_bin_ptr->bk` jednostavno treba da uradimo: **`malloc(0x80)`**
### Korak 3: Postavite \_\_malloc_hook na sistem
U prvom koraku smo završili kontrolišući deo koji sadrži `__malloc_hook` (u varijabli `malloc_hook_chunk`), a u drugom koraku smo uspeli da napišemo `main_arena + 0x68` ovde.
Sada, zloupotrebljavamo delimično prepisivanje u `malloc_hook_chunk` da bismo koristili libc adresu koju smo napisali tamo (`main_arena + 0x68`) da **usmerimo adresu `one_gadget`**.
Ovde je potrebno **brute-forcovati 12 bita nasumičnosti** (više informacija u [how2heap](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c)[ primeru](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c)).
Na kraju, kada je ispravna adresa prepisana, **pozovite `malloc` i pokrenite `one_gadget`**.
## Reference
- [https://github.com/shellphish/how2heap](https://github.com/shellphish/how2heap)
- [https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c)
- [https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_roman/](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_roman/)
{{#include ../../banners/hacktricks-training.md}}