House of Roman

Wesprzyj HackTricks

Podstawowe informacje

Była to bardzo interesująca technika, która umożliwiała RCE bez wycieków poprzez fałszywe fastbiny, atak na unsorted_bin i względne nadpisywanie. Jednak została załatana.

Kod

Cel

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

Wymagania

  • Edytuj wskaźniki fastbin i unsorted bin

  • Należy brutalnie przełamać 12 bitów losowości (0,02% szansy), aby zadziałało

Kroki ataku

Część 1: Fastbin Chunk wskazuje na __malloc_hook

Utwórz kilka chunków:

  • fastbin_victim (0x60, przesunięcie 0): Chunk UAF później do edycji wskaźnika sterty, aby wskazywał na wartość LibC.

  • chunk2 (0x80, przesunięcie 0x70): Dla dobrego wyrównania

  • main_arena_use (0x80, przesunięcie 0x100)

  • relative_offset_heap (0x60, przesunięcie 0x190): względne przesunięcie na chunku 'main_arena_use'

Następnie zwolnij(main_arena_use), co umieści ten chunk na liście unsorted i otrzymasz wskaźnik do main_arena + 0x68 zarówno w wskaźnikach fd, jak i bk.

Teraz alokowany jest nowy chunk fake_libc_chunk(0x60), ponieważ będzie zawierał wskaźniki do main_arena + 0x68 w fd i bk.

Następnie zwolnij relative_offset_heap i fastbin_victim.

/*
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 przesunięcie odległości od fake_libc_chunk, który zawiera wskaźnik do main_arena + 0x68

  • Zmieniając ostatni bajt fastbin_victim.fd, można sprawić, że fastbin_victim wskazuje na main_arena + 0x68

Dla powyższych działań atakujący musi być w stanie modyfikować wskaźnik fd fastbin_victim.

Następnie, main_arena + 0x68 nie jest tak interesujące, więc zmodyfikujmy go tak, aby wskaźnik wskazywał na __malloc_hook.

Zauważ, że __memalign_hook zazwyczaj zaczyna się od 0x7f i zer przed nim, więc można to sfałszować jako wartość w fast binie 0x70. Ponieważ ostatnie 4 bity adresu są losowe, istnieje 2^4=16 możliwości, aby wartość wskazywała tam, gdzie jesteśmy zainteresowani. Dlatego tutaj wykonywany jest atak BF, aby kawałek kończył się tak: 0x70: fastbin_victim -> fake_libc_chunk -> (__malloc_hook - 0x23).

(Dla więcej informacji na temat pozostałych bajtów sprawdź wyjaśnienie w how2heap przykładzie). Jeśli atak BF nie zadziała, program po prostu się zawiesi (więc zacznij ponownie, aż zadziała).

Następnie wykonywane są 2 alokacje pamięci, aby usunąć 2 początkowe kawałki fast binów, a trzecia jest alokowana, aby uzyskać kawałek w __malloc_hook:

malloc(0x60);
malloc(0x60);
uint8_t* malloc_hook_chunk = malloc(0x60);

Część 2: Atak na unsorted_bin

Więcej informacji można znaleźć tutaj:

Unsorted Bin Attack

Ale w skrócie pozwala to na zapisanie main_arena + 0x68 w dowolnym miejscu określonym przez chunk->bk. A dla ataku wybieramy __malloc_hook. Następnie, po nadpisaniu go, użyjemy względnego nadpisania, aby wskazać na one_gadget.

Aby to osiągnąć, zaczynamy od uzyskania fragmentu i umieszczenia go w unsorted bin:

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);

Wykorzystaj UAF w tym fragmencie, aby wskazać unsorted_bin_ptr->bk na adres __malloc_hook (wcześniej już to brutalnie obliczyliśmy).

Zauważ, że ten atak narusza nieuporządkowany blok (stąd też mały i duży). Dlatego teraz możemy korzystać tylko z alokacji z szybkiego bloku (bardziej złożony program może wykonywać inne alokacje i się zawiesić), aby wywołać to musimy zaalokować taką samą wielkość, inaczej program się zawiesi.

Więc, aby wywołać zapis main_arena + 0x68 w __malloc_hook, po ustawieniu __malloc_hook w unsorted_bin_ptr->bk, musimy po prostu wykonać: malloc(0x80)

Krok 3: Ustawienie __malloc_hook na system

W kroku pierwszym kontrolowaliśmy kawałek zawierający __malloc_hook (w zmiennej malloc_hook_chunk) i w drugim kroku udało nam się zapisać main_arena + 0x68 tutaj.

Teraz wykorzystujemy częściowe nadpisanie w malloc_hook_chunk, aby użyć adresu libc, który tam zapisaliśmy (main_arena + 0x68) do wskazania adresu one_gadget.

Tutaj konieczne jest bruteforce'owanie 12 bitów losowości (więcej informacji w how2heap przykładzie).

Wreszcie, gdy poprawny adres zostanie nadpisany, wywołaj malloc i wywołaj one_gadget.

Referencje

Wsparcie dla HackTricks

Last updated