House of Roman

Reading time: 5 minutes

tip

Ucz się i ćwicz AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Wsparcie HackTricks

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ń. Jednak została załatana.

Kod

Cel

  • RCE poprzez nadużywanie względnych wskaźników

Wymagania

  • Edytuj wskaźniki fastbin i unsorted bin
  • 12 bitów losowości musi być brutalnie wymuszonych (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 mieć możliwość modyfikacji wskaźnika 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 przykład). Jeśli BF nie działa, program po prostu się zawiesza (więc zaczynaj od nowa, aż zadziała).

Następnie wykonuje się 2 malloci, 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). Dlatego możemy 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ść, inaczej program się zawiesi.

Aby wywołać zapis main_arena + 0x68 w __malloc_hook, wykonujemy po ustawieniu __malloc_hook w unsorted_bin_ptr->bk po prostu: malloc(0x80)

Krok 3: Ustaw __malloc_hook na system

W pierwszym kroku zakończyliśmy kontrolowanie kawałka zawierającego __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 przykład).

Na koniec, gdy poprawny adres zostanie nadpisany, wywołaj malloc i uruchom one_gadget.

Referencje

tip

Ucz się i ćwicz AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Wsparcie HackTricks