mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['src/binary-exploitation/libc-heap/unsorted-bin-attack.md']
This commit is contained in:
parent
65bde4a8c7
commit
747d1fbbb6
@ -1,55 +1,113 @@
|
||||
# Atak na Niezorganizowany Koszyk
|
||||
# Unsorted Bin Attack
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Podstawowe Informacje
|
||||
## Podstawowe informacje
|
||||
|
||||
Aby uzyskać więcej informacji o tym, czym jest unsorted bin sprawdź tę stronę:
|
||||
|
||||
Aby uzyskać więcej informacji na temat tego, czym jest niezorganizowany koszyk, sprawdź tę stronę:
|
||||
|
||||
{{#ref}}
|
||||
bins-and-memory-allocations.md
|
||||
{{#endref}}
|
||||
|
||||
Niezorganizowane listy mogą zapisać adres do `unsorted_chunks (av)` w adresie `bk` kawałka. Dlatego, jeśli atakujący może **zmodyfikować adres wskaźnika `bk`** w kawałku wewnątrz niezorganizowanego koszyka, może być w stanie **zapisać ten adres w dowolnym adresie**, co może być pomocne do wycieku adresów Glibc lub obejścia niektórych zabezpieczeń.
|
||||
Unsorted lists mogą zapisać adres `unsorted_chunks (av)` w polu `bk` chunku. Dlatego, jeśli atakujący potrafi **zmodyfikować adres wskaźnika `bk`** w chunku znajdującym się w unsorted bin, może być w stanie **zapisać ten adres pod dowolnym adresem**, co może pomóc w leakowaniu adresów Glibc lub obejściu pewnych zabezpieczeń.
|
||||
|
||||
Tak więc, w zasadzie, ten atak pozwala na **ustawienie dużej liczby w dowolnym adresie**. Ta duża liczba to adres, który może być adresem sterty lub adresem Glibc. Typowym celem jest **`global_max_fast`**, aby umożliwić tworzenie koszyków szybkich o większych rozmiarach (i przejście z ataku na niezorganizowany koszyk do ataku na koszyk szybki).
|
||||
Tak więc w praktyce ten atak pozwala **ustawić dużą wartość pod dowolnym adresem**. Ta duża wartość to adres, który może być adresem heap lub Glibc. Tradycyjnym celem było **`global_max_fast`**, aby umożliwić tworzenie fast binów o większych rozmiarach (i przejście z unsorted bin attack do fast bin attack).
|
||||
|
||||
- Uwaga (glibc ≥ 2.39): `global_max_fast` stał się globalem 8‑bitowym. Bezmyślne zapisanie tam wskaźnika przez unsorted‑bin write nadpisze sąsiednie dane libc i nie podniesie niezawodnie limitu fastbin. Lepiej wybierać inne cele lub inne prymitywy przy atakowaniu glibc 2.39+. Zobacz "Modern constraints" poniżej i rozważ łączenie z innymi technikami, jak [large bin attack](large-bin-attack.md) lub [fast bin attack](fast-bin-attack.md), gdy masz stabilny prymityw.
|
||||
|
||||
> [!TIP]
|
||||
> Zobaczenie przykładu podanego w [https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted_bin_attack/#principle](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted_bin_attack/#principle) i użycie 0x4000 i 0x5000 zamiast 0x400 i 0x500 jako rozmiarów kawałków (aby uniknąć Tcache) pozwala zobaczyć, że **obecnie** błąd **`malloc(): unsorted double linked list corrupted`** jest wyzwalany.
|
||||
> T> Przejrzenie przykładu podanego w [https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted_bin_attack/#principle](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted_bin_attack/#principle) i użycie 0x4000 oraz 0x5000 zamiast 0x400 i 0x500 jako rozmiarów chunków (aby uniknąć Tcache) pokazuje, że **dziś** wywoływany jest błąd **`malloc(): unsorted double linked list corrupted`**.
|
||||
>
|
||||
> Dlatego ten atak na niezorganizowany koszyk teraz (wśród innych kontroli) również wymaga możliwości naprawienia podwójnie powiązanej listy, aby to było obejście `victim->bk->fd == victim` lub nie `victim->fd == av (arena)`, co oznacza, że adres, w którym chcemy zapisać, musi mieć adres fałszywego kawałka w swojej pozycji `fd`, a fałszywy kawałek `fd` wskazuje na arenę.
|
||||
> W związku z tym ten unsorted bin attack obecnie (oprócz innych sprawdzeń) wymaga także naprawienia listy dwukierunkowej, żeby obejść `victim->bk->fd == victim` lub `victim->fd == av (arena)`, co oznacza, że adres, pod który chcemy zapisać, musi mieć adres fałszywego chunku w swoim polu `fd`, oraz że `fd` fałszywego chunku wskazuje na arena.
|
||||
|
||||
> [!CAUTION]
|
||||
> Zauważ, że ten atak psuje niezorganizowany koszyk (stąd mały i duży również). Dlatego możemy teraz **używać tylko alokacji z szybkiego koszyka** (bardziej złożony program może wykonać inne alokacje i się zawiesić), a aby to wyzwolić, musimy **alokować ten sam rozmiar, inaczej program się zawiesi.**
|
||||
> Uwaga, ten atak korumpuje unsorted bin (a więc także small i large). Możemy więc teraz tylko **używać alokacji z fast bin** (bardziej złożony program może wykonywać inne alokacje i się zawiesić), i aby wywołać to musimy **alokować tę samą wielkość, w przeciwnym razie program się rozbije.**
|
||||
>
|
||||
> Zauważ, że nadpisanie **`global_max_fast`** może pomóc w tym przypadku, ufając, że szybki koszyk będzie w stanie zająć się wszystkimi innymi alokacjami, aż do zakończenia eksploatu.
|
||||
> Nadpisanie **`global_max_fast`** może w tym przypadku pomóc, zakładając, że fast bin poradzi sobie ze wszystkimi innymi alokacjami do czasu zakończenia exploitu.
|
||||
|
||||
Kod z [**guyinatuxedo**](https://guyinatuxedo.github.io/31-unsortedbin_attack/unsorted_explanation/index.html) wyjaśnia to bardzo dobrze, chociaż jeśli zmodyfikujesz mallocy, aby alokować pamięć wystarczająco dużą, aby nie skończyć w Tcache, możesz zobaczyć, że wcześniej wspomniany błąd pojawia się, uniemożliwiając tę technikę: **`malloc(): unsorted double linked list corrupted`**
|
||||
Kod od [**guyinatuxedo**](https://guyinatuxedo.github.io/31-unsortedbin_attack/unsorted_explanation/index.html) wyjaśnia to bardzo dobrze, chociaż jeśli zmodyfikujesz mallocy tak, by alokowały pamięć na tyle dużą, żeby nie kończyć w Tcache, można zobaczyć wspomniany wcześniej błąd zapobiegający tej technice: **`malloc(): unsorted double linked list corrupted`**
|
||||
|
||||
## Atak na Wycieki Informacji z Niezorganizowanego Koszyka
|
||||
### Jak zapis faktycznie zachodzi
|
||||
|
||||
To w rzeczywistości bardzo podstawowa koncepcja. Kawałki w niezorganizowanym koszyku będą miały wskaźniki. Pierwszy kawałek w niezorganizowanym koszyku będzie miał **`fd`** i **`bk`** linki **wskazujące na część głównej areny (Glibc)**.\
|
||||
Dlatego, jeśli możesz **umieścić kawałek wewnątrz niezorganizowanego koszyka i go odczytać** (użycie po zwolnieniu) lub **ponownie go alokować bez nadpisywania przynajmniej 1 z wskaźników**, aby następnie **odczytać** go, możesz uzyskać **wyciek informacji Glibc**.
|
||||
- Unsorted‑bin write jest wyzwalany przy `free`, gdy zwolniony chunk jest wstawiany na początek unsorted listy.
|
||||
- Podczas wstawiania alokator wykonuje: `bck = unsorted_chunks(av); fwd = bck->fd; victim->bk = bck; victim->fd = fwd; fwd->bk = victim; bck->fd = victim;`
|
||||
- Jeśli możesz ustawić `victim->bk` na `(mchunkptr)(TARGET - 0x10)` przed wywołaniem `free(victim)`, to ostatnie przypisanie wykona zapis: `*(TARGET) = victim`.
|
||||
- Później, kiedy alokator przetwarza unsorted bin, sprawdzenia integralności potwierdzą (m.in.), że `bck->fd == victim` oraz `victim->fd == unsorted_chunks(av)` zanim wykona unlink. Ponieważ podczas wstawiania już zapisano `victim` w `bck->fd` (naszym `TARGET`), te sprawdzenia mogą zostać spełnione jeśli zapis się powiódł.
|
||||
|
||||
Podobny [**atak użyty w tym opisie**](https://guyinatuxedo.github.io/33-custom_misc_heap/csaw18_alienVSsamurai/index.html) polegał na nadużywaniu struktury 4 kawałków (A, B, C i D - D jest tylko po to, aby zapobiec konsolidacji z górnym kawałkiem), więc użyto przepełnienia bajtu zerowego w B, aby sprawić, że C wskazywał, że B był nieużywany. Ponadto w B zmodyfikowano dane `prev_size`, aby rozmiar zamiast być rozmiarem B był A+B.\
|
||||
Następnie C został zwolniony i skonsolidowany z A+B (ale B wciąż był używany). Nowy kawałek o rozmiarze A został alokowany, a następnie adresy wycieków libc zostały zapisane w B, skąd zostały wycieknięte.
|
||||
## Ograniczenia w nowych wersjach (glibc ≥ 2.33)
|
||||
|
||||
## Odniesienia i Inne Przykłady
|
||||
Aby używać unsorted‑bin writes niezawodnie na aktualnym glibc:
|
||||
|
||||
- Tcache interference: dla rozmiarów mieszczących się w tcache, free są przekierowywane tam i nie trafiają do unsorted bin. Można:
|
||||
- robić żądania o rozmiarach > MAX_TCACHE_SIZE (≥ 0x410 na 64‑bit domyślnie), lub
|
||||
- zapełnić odpowiadający bin tcache (7 wpisów), tak aby kolejne free trafiły do global bins, lub
|
||||
- jeśli środowisko jest kontrolowane, wyłączyć tcache (np. GLIBC_TUNABLES glibc.malloc.tcache_count=0).
|
||||
- Sprawdzenia integralności na unsorted list: na ścieżce alokacji, która bada unsorted bin, glibc sprawdza (uproszczone):
|
||||
- `bck->fd == victim` oraz `victim->fd == unsorted_chunks(av)`; w przeciwnym razie przerywa działanie z `malloc(): unsorted double linked list corrupted`.
|
||||
- To oznacza, że adres, który atakujesz, musi tolerować dwa zapisy: najpierw `*(TARGET) = victim` w czasie free; później, gdy chunk jest usuwany, `*(TARGET) = unsorted_chunks(av)` (alokator nadpisuje `bck->fd` z powrotem adresem głowy binu). Wybierz cele, gdzie wymuszenie dużej, niezerowej wartości jest użyteczne.
|
||||
- Typowe stabilne cele we współczesnych exploitach:
|
||||
- stan aplikacji lub globalny stan traktujący "duże" wartości jako flagi/limity,
|
||||
- pośrednie prymitywy (np. przygotowanie do późniejszego [fast bin attack]({{#ref}}fast-bin-attack.md{{#endref}}) lub pivot dla kolejnego write‑what‑where).
|
||||
- Unikaj `__malloc_hook`/`__free_hook` w nowych glibc: zostały usunięte w 2.34. Unikaj `global_max_fast` w wersjach ≥ 2.39 (zob. powyżej).
|
||||
|
||||
- O `global_max_fast` w nowszym glibc
|
||||
- W glibc 2.39+ `global_max_fast` jest globalem 8‑bitowym. Klasyczny trik zapisania wskaźnika heap tam (by powiększyć fastbins) już nie działa czysto i prawdopodobnie skazi sąsiedni stan alokatora. Lepiej stosować inne strategie.
|
||||
|
||||
## Minimalny przepis na eksploatację (nowoczesny glibc)
|
||||
|
||||
Cel: uzyskać pojedynczy arbitralny zapis wskaźnika heap na dowolny adres przy użyciu prymitywu wstawiania unsorted‑bin, bez wywoływania crasha.
|
||||
|
||||
- Layout/grooming
|
||||
- Alokuj A, B, C o rozmiarach wystarczająco dużych, by ominąć tcache (np. 0x5000). C zapobiega konsolidacji z top chunk.
|
||||
- Corruption
|
||||
- Overflow z A do nagłówka chunku B, aby ustawić `B->bk = (mchunkptr)(TARGET - 0x10)`.
|
||||
- Trigger
|
||||
- `free(B)`. W czasie wstawiania alokator wykona `bck->fd = B`, więc `*(TARGET) = B`.
|
||||
- Kontynuacja
|
||||
- Jeśli planujesz kontynuować alokacje i program używa unsorted bin, spodziewaj się, że alokator później ustawi `*(TARGET) = unsorted_chunks(av)`. Obie wartości zwykle są duże i mogą wystarczyć do zmiany semantyki rozmiaru/limitów w celach, które tylko sprawdzają "duże".
|
||||
|
||||
Szkielet pseudokodu:
|
||||
```c
|
||||
// 64-bit glibc 2.35–2.38 style layout (tcache bypass via large sizes)
|
||||
void *A = malloc(0x5000);
|
||||
void *B = malloc(0x5000);
|
||||
void *C = malloc(0x5000); // guard
|
||||
|
||||
// overflow from A into B’s metadata (prev_size/size/.../bk). You must control B->bk.
|
||||
*(size_t *)((char*)B - 0x8) = (size_t)(TARGET - 0x10); // write fake bk
|
||||
|
||||
free(B); // triggers *(TARGET) = B (unsorted-bin insertion write)
|
||||
```
|
||||
> [!NOTE]
|
||||
> • Jeśli nie możesz ominąć tcache za pomocą rozmiaru, zapełnij tcache bin dla wybranego rozmiaru (7 frees) przed zwolnieniem uszkodzonego chunku, aby free trafił do unsorted.
|
||||
> • Jeśli program natychmiast przerywa wykonanie przy następnej alokacji z powodu unsorted-bin checks, sprawdź ponownie, czy `victim->fd` wciąż równa się bin head oraz czy twój `TARGET` zawiera dokładny pointer do `victim` po pierwszym zapisie.
|
||||
|
||||
## Unsorted Bin Infoleak Attack
|
||||
|
||||
To w istocie bardzo podstawowa koncepcja. Chunks w unsorted bin będą zawierać wskaźniki. Pierwszy chunk w unsorted bin będzie faktycznie miał linki **`fd`** i **`bk`** **wskazujące na część main arena (Glibc)**.\
|
||||
W związku z tym, jeśli możesz **umieścić chunk w unsorted bin i go odczytać** (use after free) lub **alokować go ponownie bez nadpisania przynajmniej jednego z wskaźników**, a następnie go **odczytać**, możesz uzyskać **Glibc info leak**.
|
||||
|
||||
Podobny [**atak użyty w tym writeupie**](https://guyinatuxedo.github.io/33-custom_misc_heap/csaw18_alienVSsamurai/index.html) polegał na nadużyciu struktury 4 chunków (A, B, C i D — D służy tylko do zapobieżenia konsolidacji z top chunk), więc null byte overflow w B został użyty, by sprawić, że C będzie wskazywać, że B jest nieużywany. Dodatkowo w B pole `prev_size` zostało zmodyfikowane tak, że rozmiar zamiast być rozmiarem B był A+B.\
|
||||
Następnie C został zwolniony i skonsolidowany z A+B (ale B nadal był używany). Przydzielono nowy chunk o rozmiarze A, a potem do B zapisano libc leaked addresses, skąd następnie je odczytano.
|
||||
|
||||
## Referencje i inne przykłady
|
||||
|
||||
- [**https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted_bin_attack/#hitcon-training-lab14-magic-heap**](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 możliwe było uzyskanie flagi, a PIE nie jest włączone.
|
||||
- Możliwe jest generowanie kawałków o dowolnych rozmiarach i występuje przepełnienie sterty o pożądanym rozmiarze.
|
||||
- Atak zaczyna się od stworzenia 3 kawałków: chunk0 do nadużywania przepełnienia, chunk1 do przepełnienia i chunk2, aby górny kawałek nie konsolidował poprzednich.
|
||||
- Następnie chunk1 jest zwalniany, a chunk0 jest przepełniany, aby wskaźnik `bk` chunk1 wskazywał na: `bk = magic - 0x10`
|
||||
- Następnie chunk3 jest alokowany o tym samym rozmiarze co chunk1, co wyzwoli atak na niezorganizowany koszyk i zmodyfikuje wartość zmiennej globalnej, umożliwiając uzyskanie flagi.
|
||||
- Celem jest nadpisanie zmiennej globalnej wartością większą niż 4869, aby możliwe było zdobycie flagi i PIE nie jest włączone.
|
||||
- Możliwe jest wygenerowanie chunków o dowolnych rozmiarach i istnieje heap overflow o żądanym rozmiarze.
|
||||
- Atak zaczyna się od stworzenia 3 chunków: chunk0 do nadużycia overflow, chunk1 który ma być overflowowany oraz chunk2, aby top chunk nie skonsolidował poprzednich.
|
||||
- Następnie chunk1 jest zwalniany, a chunk0 jest overflowowany tak, że `bk` wskazywane przez chunk1 pokazuje na: `bk = magic - 0x10`
|
||||
- Potem alokowany jest chunk3 o tym samym rozmiarze co chunk1, co wywoła unsorted bin attack i zmodyfikuje wartość zmiennej globalnej, umożliwiając zdobycie flagi.
|
||||
- [**https://guyinatuxedo.github.io/31-unsortedbin_attack/0ctf16_zerostorage/index.html**](https://guyinatuxedo.github.io/31-unsortedbin_attack/0ctf16_zerostorage/index.html)
|
||||
- Funkcja scalania jest podatna, ponieważ jeśli oba przekazane indeksy są takie same, to zostanie ponownie alokowana i następnie zwolniona, ale zwracając wskaźnik do tego zwolnionego obszaru, który można wykorzystać.
|
||||
- Dlatego **tworzone są 2 kawałki**: **chunk0**, który zostanie scalony z samym sobą, oraz chunk1, aby zapobiec konsolidacji z górnym kawałkiem. Następnie **funkcja scalania jest wywoływana z chunk0** dwukrotnie, co spowoduje użycie po zwolnieniu.
|
||||
- Następnie **funkcja `view`** jest wywoływana z indeksem 2 (który jest indeksem kawałka używanego po zwolnieniu), co **wycieka adres libc**.
|
||||
- Ponieważ binarka ma zabezpieczenia, aby alokować tylko rozmiary większe niż **`global_max_fast`**, więc żaden szybki koszyk nie jest używany, zostanie użyty atak na niezorganizowany koszyk, aby nadpisać zmienną globalną `global_max_fast`.
|
||||
- Następnie możliwe jest wywołanie funkcji edytowania z indeksem 2 (wskaźnik używany po zwolnieniu) i nadpisanie wskaźnika `bk`, aby wskazywał na `p64(global_max_fast-0x10)`. Następnie, tworząc nowy kawałek, użyje wcześniej skompromitowanego adresu zwolnionego (0x20), co **wyzwoli atak na niezorganizowany koszyk**, nadpisując `global_max_fast`, co jest bardzo dużą wartością, umożliwiając teraz tworzenie kawałków w szybkich koszykach.
|
||||
- Teraz przeprowadzany jest **atak na szybki koszyk**:
|
||||
- Przede wszystkim odkryto, że możliwe jest pracowanie z szybkimi **kawałkami o rozmiarze 200** w lokalizacji **`__free_hook`**:
|
||||
- Funkcja merge jest podatna, ponieważ jeśli oba przekazane indeksy są takie same, to następuje realloc na tym indeksie, a potem jego free, ale zwracany jest pointer do tej zwolnionej regionu, który można wykorzystać.
|
||||
- W związku z tym **tworzone są 2 chunky**: **chunk0**, który zostanie scalony sam ze sobą, oraz chunk1 żeby zapobiec konsolidacji z top chunk. Następnie **merge function jest wywoływana dla chunk0** dwukrotnie, co spowoduje use after free.
|
||||
- Potem wywoływana jest funkcja **`view`** z indeksem 2 (który odpowiada use after free chunkowi), co spowoduje **leak libc address**.
|
||||
- Ponieważ binarka ma zabezpieczenia, które pozwalają mallocować tylko rozmiary większe niż **`global_max_fast`**, więc nie używa się fastbinów — zastosowany zostanie unsorted bin attack, aby nadpisać zmienną globalną `global_max_fast`.
|
||||
- Następnie można wywołać funkcję edycji z indeksem 2 (pointer use after free) i nadpisać wskaźnik `bk`, aby wskazywał na `p64(global_max_fast-0x10)`. Potem stworzenie nowego chunku użyje wcześniej skompromitowanego adresu free (0x20) i **wywoła unsorted bin attack**, nadpisując `global_max_fast` na bardzo dużą wartość, co pozwoli teraz tworzyć chunki w fast binach.
|
||||
- Teraz wykonywany jest **fast bin attack**:
|
||||
- Najpierw odkryto, że można pracować z fast **chunkami o rozmiarze 200** w lokalizacji **`__free_hook`**:
|
||||
- <pre class="language-c"><code class="lang-c">gef➤ p &__free_hook
|
||||
$1 = (void (**)(void *, const void *)) 0x7ff1e9e607a8 <__free_hook>
|
||||
gef➤ x/60gx 0x7ff1e9e607a8 - 0x59
|
||||
@ -58,16 +116,20 @@ gef➤ x/60gx 0x7ff1e9e607a8 - 0x59
|
||||
0x7ff1e9e6076f <list_all_lock+15>: 0x0000000000000000 0x0000000000000000
|
||||
0x7ff1e9e6077f <_IO_stdfile_2_lock+15>: 0x0000000000000000 0x0000000000000000
|
||||
</code></pre>
|
||||
- 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`, a funkcja scalania 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 koszyku.
|
||||
- Następnie funkcja edytowania jest wywoływana w tym kawałku, aby zmodyfikować adres **`fd`** tego szybkiego koszyka, aby wskazywał na poprzednią funkcję **`__free_hook`**.
|
||||
- Następnie tworzony jest kawałek o rozmiarze `0x1f8`, aby odzyskać z szybkiego koszyka poprzedni bezużyteczny kawałek, więc tworzony jest kolejny kawałek o rozmiarze `0x1f8`, aby uzyskać kawałek szybkiego koszyka w **`__free_hook`**, który jest nadpisywany adresem funkcji **`system`**.
|
||||
- A na koniec kawałek zawierający ciąg `/bin/sh\x00` jest zwalniany, wywołując funkcję usuwania, co wyzwala funkcję **`__free_hook`**, która wskazuje na system z `/bin/sh\x00` jako parametrem.
|
||||
- Jeśli uda się uzyskać fast chunk o rozmiarze 0x200 w tej lokalizacji, będzie można nadpisać wskaźnik funkcji, który zostanie wykonany.
|
||||
- W tym celu tworzony jest nowy chunk o rozmiarze `0xfc` i funkcja merge jest wywoływana z tym wskaźnikiem dwukrotnie — w ten sposób uzyskujemy pointer do zwolnionego chunku o rozmiarze `0xfc*2 = 0x1f8` w fast binie.
|
||||
- Potem wywoływana jest funkcja edycji na tym chunku, aby zmodyfikować adres **`fd`** tego fast binu tak, aby wskazywał na poprzedni **`__free_hook`**.
|
||||
- Następnie alokowany jest chunk o rozmiarze `0x1f8`, aby pobrać ze fast binu poprzedni nieużyteczny chunk, a potem kolejny chunk o rozmiarze `0x1f8`, aby otrzymać fast bin chunk w **`__free_hook`**, który jest nadpisywany adresem funkcji **`system`**.
|
||||
- I w końcu chunk zawierający string `/bin/sh\x00` jest zwalniany przez wywołanie funkcji delete, wywołując **`__free_hook`**, które teraz wskazuje na system z `/bin/sh\x00` jako parametrem.
|
||||
- **CTF** [**https://guyinatuxedo.github.io/33-custom_misc_heap/csaw19_traveller/index.html**](https://guyinatuxedo.github.io/33-custom_misc_heap/csaw19_traveller/index.html)
|
||||
- Inny przykład nadużywania przepełnienia 1B do konsolidacji kawałków w niezorganizowanym koszyku i uzyskania wycieku informacji libc, a następnie przeprowadzenia ataku na szybki koszyk w celu nadpisania wskaźnika malloc z adresem jednego gadżetu.
|
||||
- Kolejny przykład nadużycia 1B overflow, aby skonsolidować chunki w unsorted bin i uzyskać libc infoleak, a następnie przeprowadzić fast bin attack w celu nadpisania malloc hook adresem one gadget.
|
||||
- [**Robot Factory. BlackHat MEA CTF 2022**](https://7rocky.github.io/en/ctf/other/blackhat-ctf/robot-factory/)
|
||||
- Możemy alokować tylko kawałki o rozmiarze większym niż `0x100`.
|
||||
- Nadpisanie `global_max_fast` za pomocą ataku na niezorganizowany koszyk (działa 1/16 razy z powodu ASLR, ponieważ musimy zmodyfikować 12 bitów, ale musimy zmodyfikować 16 bitów).
|
||||
- Atak na szybki koszyk w celu modyfikacji globalnej tablicy kawałków. To daje dowolną prymitywę odczytu/zapisu, co pozwala na modyfikację GOT i ustawienie niektórej funkcji, aby wskazywała na `system`.
|
||||
- Możemy alokować tylko chunki o rozmiarze większym niż `0x100`.
|
||||
- Nadpisanie `global_max_fast` przy użyciu Unsorted Bin attack (działa 1/16 razy z powodu ASLR, ponieważ trzeba zmodyfikować 12 bitów, ale trzeba zmodyfikować 16 bitów).
|
||||
- Fast Bin attack, aby zmodyfikować globalną tablicę chunków. To daje arbitralny read/write primitive, co pozwala na modyfikację GOT i ustawienie pewnej funkcji, by wskazywała na `system`.
|
||||
|
||||
## References
|
||||
|
||||
- Glibc malloc unsorted-bin integrity checks (example in 2.33 source): https://elixir.bootlin.com/glibc/glibc-2.33/source/malloc/malloc.c
|
||||
- `global_max_fast` and related definitions in modern glibc (2.39): https://elixir.bootlin.com/glibc/glibc-2.39/source/malloc/malloc.c
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
Loading…
x
Reference in New Issue
Block a user