mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
113 lines
5.9 KiB
Markdown
113 lines
5.9 KiB
Markdown
# House of Roman
|
|
|
|
{{#include ../../banners/hacktricks-training.md}}
|
|
|
|
## Podstawowe informacje
|
|
|
|
To była bardzo interesująca technika, która pozwalała na RCE bez wycieków za pomocą fałszywych fastbins, ataku unsorted_bin i względnych nadpisywań. Została jednak [**załatana**](https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=b90ddd08f6dd688e651df9ee89ca3a69ff88cd0c).
|
|
|
|
### Kod
|
|
|
|
- Możesz znaleźć przykład w [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)
|
|
|
|
### Cel
|
|
|
|
- RCE poprzez nadużycie względnych wskaźników
|
|
|
|
### Wymagania
|
|
|
|
- Edytuj wskaźniki fastbin i unsorted bin
|
|
- 12 bitów losowości musi być brutalnie przeszukiwanych (0,02% szans na powodzenie)
|
|
|
|
## Kroki ataku
|
|
|
|
### Część 1: Wskaźnik Fastbin Chunk do \_\_malloc_hook
|
|
|
|
Utwórz kilka chunków:
|
|
|
|
- `fastbin_victim` (0x60, offset 0): chunk UAF, który później edytuje wskaźnik heap, aby wskazywał na wartość LibC.
|
|
- `chunk2` (0x80, offset 0x70): dla dobrej wyrównania
|
|
- `main_arena_use` (0x80, offset 0x100)
|
|
- `relative_offset_heap` (0x60, offset 0x190): względny offset na chunku 'main_arena_use'
|
|
|
|
Następnie `free(main_arena_use)`, co umieści ten chunk na liście unsorted i uzyska wskaźnik do `main_arena + 0x68` w obu wskaźnikach `fd` i `bk`.
|
|
|
|
Teraz przydzielany jest nowy chunk `fake_libc_chunk(0x60)`, ponieważ będzie zawierał wskaźniki do `main_arena + 0x68` w `fd` i `bk`.
|
|
|
|
Następnie `relative_offset_heap` i `fastbin_victim` są zwalniane.
|
|
```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` ma `fd` wskazujący na `relative_offset_heap`
|
|
- `relative_offset_heap` to offset odległości od `fake_libc_chunk`, który zawiera wskaźnik do `main_arena + 0x68`
|
|
- Zmieniając tylko ostatni bajt `fastbin_victim.fd`, możliwe jest, aby `fastbin_victim` wskazywał na `main_arena + 0x68`
|
|
|
|
Aby wykonać powyższe działania, atakujący musi być w stanie zmodyfikować wskaźnik fd `fastbin_victim`.
|
|
|
|
Następnie `main_arena + 0x68` nie jest zbyt interesujące, więc zmodyfikujmy to, aby wskaźnik wskazywał na **`__malloc_hook`**.
|
|
|
|
Zauważ, że `__memalign_hook` zazwyczaj zaczyna się od `0x7f` i zer przed nim, więc możliwe jest sfałszowanie go jako wartości w szybkim binie `0x70`. Ponieważ ostatnie 4 bity adresu są **losowe**, istnieje `2^4=16` możliwości, gdzie wartość może kończyć się tam, gdzie jesteśmy zainteresowani. Dlatego tutaj przeprowadzany jest atak BF, aby kawałek kończył się jak: **`0x70: fastbin_victim -> fake_libc_chunk -> (__malloc_hook - 0x23)`**.
|
|
|
|
(Aby uzyskać więcej informacji na temat pozostałych bajtów, sprawdź wyjaśnienie w [how2heap](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c)[ przykład](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c)). Jeśli BF nie działa, program po prostu się zawiesza (więc zaczynaj od nowa, aż zadziała).
|
|
|
|
Następnie wykonuje się 2 mallocy, aby usunąć 2 początkowe kawałki szybkiego binu, a trzeci jest alokowany, aby uzyskać kawałek w **`__malloc_hook:`**
|
|
```c
|
|
malloc(0x60);
|
|
malloc(0x60);
|
|
uint8_t* malloc_hook_chunk = malloc(0x60);
|
|
```
|
|
### Część 2: Atak na unsorted_bin
|
|
|
|
Aby uzyskać więcej informacji, możesz sprawdzić:
|
|
|
|
{{#ref}}
|
|
unsorted-bin-attack.md
|
|
{{#endref}}
|
|
|
|
Ale zasadniczo pozwala to na zapisanie `main_arena + 0x68` w dowolnej lokalizacji określonej w `chunk->bk`. A do ataku wybieramy `__malloc_hook`. Następnie, po nadpisaniu go, użyjemy względnego nadpisania, aby wskazać na `one_gadget`.
|
|
|
|
W tym celu zaczynamy od uzyskania chunk i umieszczamy go w **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);
|
|
```
|
|
Użyj UAF w tym kawałku, aby wskazać `unsorted_bin_ptr->bk` na adres `__malloc_hook` (wcześniej to brutalnie wymusiliśmy).
|
|
|
|
> [!CAUTION]
|
|
> Zauważ, że ten atak psuje niesortowany bin (a więc również mały i duży). Możemy więc teraz **używać tylko alokacji z szybkiego binu** (bardziej złożony program może wykonać inne alokacje i się zawiesić), a aby to wywołać, musimy **alokować tę samą wielkość, w przeciwnym razie program się zawiesi.**
|
|
|
|
Aby wywołać zapis `main_arena + 0x68` w `__malloc_hook`, wykonujemy po ustawieniu `__malloc_hook` w `unsorted_bin_ptr->bk`, musimy po prostu zrobić: **`malloc(0x80)`**
|
|
|
|
### Krok 3: Ustaw \_\_malloc_hook na system
|
|
|
|
W pierwszym kroku zakończyliśmy kontrolując kawałek zawierający `__malloc_hook` (w zmiennej `malloc_hook_chunk`), a w drugim kroku udało nam się zapisać `main_arena + 0x68` tutaj.
|
|
|
|
Teraz nadużywamy częściowego nadpisania w `malloc_hook_chunk`, aby użyć adresu libc, który tam zapisaliśmy (`main_arena + 0x68`), aby **wskazać adres `one_gadget`**.
|
|
|
|
Tutaj potrzebne jest **brutalne wymuszenie 12 bitów losowości** (więcej informacji w [how2heap](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c)[ przykład](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c)).
|
|
|
|
Na koniec, gdy poprawny adres zostanie nadpisany, **wywołaj `malloc` i uruchom `one_gadget`**.
|
|
|
|
## References
|
|
|
|
- [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}}
|