hacktricks/binary-exploitation/heap/unsorted-bin-attack.md

11 KiB

Atak na nieposortowany blok

Zacznij od zera i stań się ekspertem od hakowania AWS dzięki htARTE (HackTricks AWS Red Team Expert)!

Inne sposoby wsparcia HackTricks:

Podstawowe informacje

Aby uzyskać więcej informacji na temat tego, co oznacza nieposortowany blok, sprawdź tę stronę:

{% content-ref url="bins-and-memory-allocations.md" %} bins-and-memory-allocations.md {% endcontent-ref %}

Nieposortowane listy mogą zapisać adres w unsorted_chunks (av) w adresie bk fragmentu. Dlatego jeśli atakujący może zmodyfikować adres wskaźnika bk w fragmencie wewnątrz nieposortowanego bloku, może zapisać ten adres w dowolnym adresie, co może pomóc w ujawnieniu adresów libc lub obejściu niektórych zabezpieczeń.

W zasadzie ten atak pozwala nadpisać dowolny adres dużą liczbą (adres, który może być adresem sterty lub adresem libc), na przykład adresem stosu, który może być ujawniony, lub ograniczeniem, takim jak globalna zmienna global_max_fast, aby umożliwić tworzenie bloków fast bin o większych rozmiarach (i przejście od ataku na nieposortowany blok do ataku na fast bin).

{% hint style="success" %} Przyjrzyjmy się przykładowi podanemu w https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted_bin_attack/#principle i użyjmy wartości 0x4000 i 0x5000 zamiast 0x400 i 0x500 jako rozmiarów fragmentów (aby uniknąć tcaches), można zobaczyć, że obecnie błąd malloc(): unsorted double linked list corrupted jest wywoływany.

Dlatego ten atak na nieposortowany blok teraz (oprócz innych sprawdzeń) wymaga również naprawienia zduplikowanej listy połączonej, aby to ominąć victim->bck->fd == victim lub nie victim->fd == av (arena). Oznacza to, że adres, w który chcemy zapisać, musi mieć adres fałszywego fragmentu w swojej pozycji fd, a fałszywy fragment fd wskazuje na arenę. {% endhint %}

{% hint style="danger" %} Zauważ, że ten atak psuje nieposortowany blok (a także mały i duży). Dlatego teraz możemy korzystać tylko z alokacji z bloków fast bin (bardziej złożony program może wykonywać inne alokacje i się zawiesić), a aby to wywołać, musimy zaalokować ten sam rozmiar, inaczej program się zawiesi.

Zauważ, że ustawienie global_max_fast może pomóc w tym przypadku, zakładając, że fast bin będzie w stanie obsłużyć wszystkie inne alokacje, dopóki exploit nie zostanie zakończony. {% endhint %}

Kod od guyinatuxedo dobrze to wyjaśnia, chociaż jeśli zmodyfikujesz alokacje pamięci tak, aby alokować pamięć wystarczająco dużą, aby nie trafić do tcaches, zobaczysz, że wcześniej wspomniany błąd uniemożliwia zastosowanie tej techniki: malloc(): unsorted double linked list corrupted

Atak na nieposortowany blok wyciek informacji

To tak naprawdę bardzo podstawowe pojęcie. Fragmenty w nieposortowanym bloku będą miały wskaźniki podwójne wskaźniki, aby utworzyć blok. Pierwszy fragment w nieposortowanym bloku będzie faktycznie mieć FD i BK wskazujące na część głównej areny (libc).
Dlatego jeśli możesz umieścić fragment wewnątrz nieposortowanego bloku i odczytać go (użyj po zwolnieniu) lub ponownie go zaalokować bez nadpisywania co najmniej 1 z wskaźników, aby następnie go odczytać, możesz uzyskać wyciek informacji z libc.

Podobny atak użyty w tym opisie, polegał na nadużyciu struktury 4 fragmentów (A, B, C i D - D służył tylko do zapobieżenia konsolidacji z głównym fragmentem). Następnie użyto przepełnienia bajtami zerowymi w B, aby sprawić, że C wskaże, że B jest nieużywany. Ponadto w B zmodyfikowano dane prev_size, więc rozmiar zamiast być rozmiarem B, był A+B.
Następnie C został zwolniony i skonsolidowany z A+B (ale B nadal był używany). Zaalokowano nowy fragment o rozmiarze A, a następnie wyciekły adresy libc zostały zapisane do B, skąd zostały wycieknięte.

Odwołania i inne przykłady

  • https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted_bin_attack/#hitcon-training-lab14-magic-heap
  • Celem jest nadpisanie zmiennej globalnej wartością większą niż 4869, aby uzyskać flagę, a PIE nie jest włączone.
  • Możliwe jest generowanie fragmentów o dowolnych rozmiarach i występuje przepełnienie sterty o pożądanym rozmiarze.
  • Atak rozpoczyna się od utworzenia 3 fragmentów: fragmentu0 do nadużycia przepełnienia, fragmentu1 do przepełnienia i fragmentu2, aby główny fragment nie konsolidował poprzednich.
  • Następnie fragment1 jest zwalniany, a fragment0 jest przepełniany, aby wskaźnik bk fragmentu1 wskazywał na: bk = magic - 0x10
  • Następnie zaalokowany jest fragment3 o tym samym rozmiarze co fragment1, co spowoduje atak na nieposortowany blok i zmodyfikuje wartość zmiennej globalnej, umożliwiając uzyskanie flagi.
  • https://guyinatuxedo.github.io/31-unsortedbin_attack/0ctf16_zerostorage/index.html
  • Funkcja łączenia jest podatna, ponieważ jeśli oba przekazane indeksy są takie same, to zrealokuje na nim i zwolni go, ale zwróci wskaźnik do tego zwolnionego obszaru, który można wykorzystać.
  • Dlatego tworzone są 2 fragmenty: fragment0, który zostanie połączony sam ze sobą i fragment1, aby zapobiec konsolidacji z głównym fragmentem. Następnie funkcja merge jest wywoływana z fragmentem0 dwukrotnie, co spowoduje użycie po zwolnieniu.
  • Następnie wywoływana jest funkcja view z indeksem 2 (który jest indeksem użytego po zwolnieniu fragmentu), co spowoduje wyciek adresu libc.
  • Ponieważ binarny ma zabezpieczenia, aby alokować tylko rozmiary większe niż global_max_fast, więc nie używany jest fastbin, atak na nieposortowany blok zostanie wykorzystany do nadpisania zmiennej globalnej global_max_fast.
  • Następnie możliwe jest wywołanie funkcji edycji z indeksem 2 (wskaźnik użyty po zwolnieniu) i nadpisanie wskaźnika bk, aby wskazywał na p64(global_max_fast-0x10). Następnie tworząc nowy fragment użyje się wcześniej skompromitowanego adresu zwolnienia (0x20), co spowoduje atak na nieposortowany blok, nadpisując global_max_fast dużą wartością, umożliwiając teraz tworzenie fragmentów w fast binach.
  • Teraz wykonywany jest atak na fast bin:
  • Po pierwsze odkryto, że możliwe jest pracowanie z szybkimi fragmentami o rozmiarze 200 w lokalizacji __free_hook:
  • gef➤  p &__free_hook
    

$1 = (void (**)(void *, const void *)) 0x7ff1e9e607a8 <__free_hook> gef➤ x/60gx 0x7ff1e9e607a8 - 0x59 0x7ff1e9e6074f: 0x0000000000000000 0x0000000000000200 0x7ff1e9e6075f: 0x0000000000000000 0x0000000000000000 0x7ff1e9e6076f <list_all_lock+15>: 0x0000000000000000 0x0000000000000000 0x7ff1e9e6077f <_IO_stdfile_2_lock+15>: 0x0000000000000000 0x0000000000000000

  • Jeśli uda nam się uzyskać szybki kawałek o rozmiarze 0x200 w tej lokalizacji, będzie możliwe nadpisanie wskaźnika funkcji, który zostanie wykonany
  • W tym celu tworzony jest nowy kawałek o rozmiarze 0xfc i funkcja scalająca jest wywoływana z tym wskaźnikiem dwukrotnie, w ten sposób uzyskujemy wskaźnik do zwolnionego kawałka o rozmiarze 0xfc*2 = 0x1f8 w szybkim binie.
  • Następnie funkcja edycji jest wywoływana w tym kawałku, aby zmodyfikować adres fd tego szybkiego bina tak, aby wskazywał na poprzednią funkcję __free_hook.
  • Następnie tworzony jest kawałek o rozmiarze 0x1f8, aby pobrać z szybkiego bina poprzedni nieużyteczny kawałek, więc tworzony jest kolejny kawałek o rozmiarze 0x1f8, aby uzyskać kawałek z szybkiego bina w __free_hook, który jest nadpisany adresem funkcji system.
  • I wreszcie zwalniany jest kawałek zawierający ciąg znaków /bin/sh\x00, wywołując funkcję usuwania, co powoduje wywołanie funkcji __free_hook, która wskazuje na system z /bin/sh\x00 jako parametrem.
  • CTF https://guyinatuxedo.github.io/33-custom_misc_heap/csaw19_traveller/index.html
  • Kolejny przykład nadużycia przepełnienia o 1B w celu skonsolidowania kawałków w nieuporządkowanym binie, uzyskania wycieku informacji o libc, a następnie przeprowadzenia ataku na szybki bin w celu nadpisania haka malloc adresem jednego gadżetu
Naucz się hakować AWS od zera do bohatera z htARTE (HackTricks AWS Red Team Expert)!

Inne sposoby wsparcia HackTricks: