# Unsorted Bin Attack {{#include ../../banners/hacktricks-training.md}} ## Taarifa za Msingi For more information about what is an unsorted bin check this page: {{#ref}} bins-and-memory-allocations.md {{#endref}} Unsorted lists zinaweza kuandika anwani ya `unsorted_chunks (av)` katika anwani ya `bk` ya chunk. Kwa hiyo, ikiwa mshambuliaji anaweza **kubadilisha anwani ya pointer `bk`** katika chunk ndani ya unsorted bin, angeweza kuwa na uwezo wa **kuandika anwani hiyo mahali popote** ambayo inaweza kusaidia ku-leak anwani za Glibc au kuruka utetezi fulani. Kwa msingi, shambulio hili huruhusu **kuweka namba kubwa kwenye anwani yoyote**. Namba kubwa hii ni anwani, ambayo inaweza kuwa anwani ya heap au anwani ya Glibc. Lengo la jadi lilikuwa **`global_max_fast`** kuruhusu kuunda fast bin bins zenye ukubwa mkubwa (na kutoka unsorted bin attack kwenda fast bin attack). - Modern note (glibc ≥ 2.39): `global_max_fast` became an 8‑bit global. Blindly writing a pointer there via an unsorted-bin write will clobber adjacent libc data and will not reliably raise the fastbin limit anymore. Prefer other targets or other primitives when running against glibc 2.39+. See "Modern constraints" below and consider combining with other techniques like a [large bin attack](large-bin-attack.md) or a [fast bin attack](fast-bin-attack.md) once you have a stable primitive. > [!TIP] > T> Kuangalia mfano uliotolewa katika [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) na kutumia 0x4000 na 0x5000 badala ya 0x400 na 0x500 kama chunk sizes (ili kuepuka Tcache) inawezekana kuona kwamba **siku za hivi karibuni** hitilafu **`malloc(): unsorted double linked list corrupted`** inachochewa. > > Hivyo, shambulio hili la unsorted bin sasa (miongoni mwa ukaguzi mwingine) pia linahitaji kuwa na uwezo wa kurekebisha double linked list ili kupitisha ukaguzi `victim->bk->fd == victim` au `victim->fd == av (arena)`, ambayo inamaanisha kwamba anwani tunayotaka kuandika lazima iwe na anwani ya fake chunk katika nafasi yake ya `fd` na kwamba `fd` ya fake chunk inarejea kwa arena. > [!CAUTION] > Kumbuka kwamba shambulio hili linaharibu unsorted bin (na hivyo small na large pia). Kwa hivyo sasa tunaweza tu **kutumia allocations kutoka fast bin** (programu ngumu zaidi inaweza kufanya allocations nyingine na ku-crash), na ili kuchochea hili lazima **tufanye allocation ya ukubwa uleule au programu ita-crash.** > > Kumbuka kwamba kuandika juu ya **`global_max_fast`** kunaweza kusaidia katika kesi hii kwa kuamini kuwa fast bin itashughulikia allocations zote nyingine hadi exploit itakapokamilika. Msimbo kutoka kwa [**guyinatuxedo**](https://guyinatuxedo.github.io/31-unsortedbin_attack/unsorted_explanation/index.html) unaelezea vizuri sana, ingawa ukibadilisha mallocs kuomba memory kubwa vya kutosha ili zisimalizike kwenye Tcache utaona kuwa hitilafu iliyotajwa hapo juu inaonekana ikizuia mbinu hii: **`malloc(): unsorted double linked list corrupted`** ### Jinsi uandishi unavyotokea kwa kweli - Uandishi wa unsorted-bin huchochewa wakati wa `free` wakati chunk iliyofunguliwa inaingizwa kwenye kichwa cha unsorted list. - Wakati wa kuingiza, allocator hufanya `bck = unsorted_chunks(av); fwd = bck->fd; victim->bk = bck; victim->fd = fwd; fwd->bk = victim; bck->fd = victim;` - Ikiwa unaweza kuweka `victim->bk` kuwa `(mchunkptr)(TARGET - 0x10)` kabla ya kuita `free(victim)`, taarifa ya mwisho itafanya uandishi: `*(TARGET) = victim`. - Baadaye, wakati allocator inashughulikia unsorted bin, ukaguzi wa uadilifu utathibitisha (miongoni mwa mambo mengine) kwamba `bck->fd == victim` na `victim->fd == unsorted_chunks(av)` kabla ya unlinking. Kwa sababu uingizaji tayari uliandika `victim` ndani ya `bck->fd` (TARGET yetu), ukaguzi huu unaweza kutimizwa ikiwa uandishi ulifanikiwa. ## Modern constraints (glibc ≥ 2.33) Ili kutumia unsorted‑bin writes kwa kuaminika kwenye glibc ya sasa: - Tcache interference: kwa sizes zinazopungua katika tcache, frees zinaelekezwa huko na hazitoghushi unsorted bin. Aidha: - fanya maombi yenye sizes > MAX_TCACHE_SIZE (≥ 0x410 kwenye 64‑bit kwa default), au - jaza tcache bin inayolingana (entries 7) ili frees nyingine zifikie global bins, au - ikiwa mazingira yanaweza kudhibitiwa, zima tcache (mfano, GLIBC_TUNABLES glibc.malloc.tcache_count=0). - Integrity checks on the unsorted list: kwenye njia inayofanya allocation inayotazama unsorted bin, glibc hukagua (imepunguzwa): - `bck->fd == victim` na `victim->fd == unsorted_chunks(av)`; vinginevyo inakata na `malloc(): unsorted double linked list corrupted`. - Hii inamaanisha anwani unayolenga lazima kustahimili maandishi mawili: kwanza `*(TARGET) = victim` wakati wa free; baadaye, wakati chunk inapoondolewa, `*(TARGET) = unsorted_chunks(av)` (allocator anarudisha `bck->fd` kwa kichwa cha bin). Chagua malengo ambapo kulazimisha tu thamani kubwa isiyo-nya ni muhimu. - Typical stable targets in modern exploits - Hali ya programu au global inayotenda "large" values kama flags/limits. - Indirect primitives (mfano, kuandaa kwa ajili ya [fast bin attack]({{#ref}}fast-bin-attack.md{{#endref}}) inayofuata au ku-pivot kwa write‑what‑where baadaye). - Epuka `__malloc_hook`/`__free_hook` kwenye glibc mpya: zilitolewa kwenye 2.34. Epuka `global_max_fast` kwenye ≥ 2.39 (angalia nota ifuatayo). - About `global_max_fast` on recent glibc - On glibc 2.39+, `global_max_fast` is an 8‑bit global. The classic trick of writing a heap pointer into it (to enlarge fastbins) no longer works cleanly and is likely to corrupt adjacent allocator state. Prefer other strategies. ## Minimal exploitation recipe (modern glibc) Goal: achieve a single arbitrary write of a heap pointer to an arbitrary address using the unsorted‑bin insertion primitive, without crashing. - Layout/grooming - Allocate A, B, C with sizes large enough to bypass tcache (e.g., 0x5000). C prevents consolidation with the top chunk. - Corruption - Overflow from A into B’s chunk header to set `B->bk = (mchunkptr)(TARGET - 0x10)`. - Trigger - `free(B)`. At insertion time the allocator executes `bck->fd = B`, therefore `*(TARGET) = B`. - Continuation - If you plan to continue allocating and the program uses the unsorted bin, expect the allocator to later set `*(TARGET) = unsorted_chunks(av)`. Both values are typically large and may be enough to change size/limit semantics in targets that only check for "big". Pseudocode skeleton: ```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] > • Ikiwa huwezi kupita tcache kwa ukubwa, jaza tcache bin kwa ukubwa uliyoichagua (7 frees) kabla ya kuifree corrupted chunk ili free iende kwenye unsorted. > • Ikiwa programu inakatika mara moja kwenye allocation inayofuata kutokana na unsorted-bin checks, angalia tena kwamba `victim->fd` bado ni sawa na bin head na kwamba `TARGET` yako inashikilia pointer kamili ya `victim` baada ya uandishi wa kwanza. ## Unsorted Bin Infoleak Attack Hii kwa kweli ni dhana rahisi. Chunks katika unsorted bin zitakuwa na pointers. Chunk ya kwanza katika unsorted bin itakuwa na viungo vya **`fd`** na **`bk`** **vinavyorejelea sehemu ya main arena (Glibc)**.\ Kwa hiyo, ikiwa unaweza **kuweka chunk ndani ya unsorted bin na kuisoma** (use after free) au **kuiallocate tena bila kuandika juu angalau moja ya pointers** kisha **kuisoma**, unaweza kupata **Glibc info leak**. A attack sawa [**attack used in this writeup**](https://guyinatuxedo.github.io/33-custom_misc_heap/csaw18_alienVSsamurai/index.html), ilikuwa kutumia muundo wa chunks 4 (A, B, C na D - D iko tu kuzuia consolidation na top chunk) hivyo overflow ya null byte kwenye B ilitumika kufanya C kuonyesha kuwa B haikutumika. Pia, kwenye B `prev_size` ilibadilishwa hivyo ukubwa, badala ya kuwa ukubwa wa B, ulikuwa A+B.\ Kisha C ilifutwa, na ikaunganishwa na A+B (lakini B bado ilikuwa inatumika). Chunk mpya ya ukubwa A ilitengenezwa kisha libc leaked addresses ziliandikwa ndani ya B kutoka pale zilipoleak. ## References & Other examples - [**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) - Lengo ni kuchapisha (overwrite) global variable na thamani kubwa kuliko 4869 ili iwezekane kupata flag na PIE haijatumiwa. - Inawezekana kutengeneza chunks za ukubwa wowote na kuna heap overflow kwa ukubwa unaohitajika. - Shambulio linaanza kwa kuunda chunks 3: chunk0 kwa kutumia overflow, chunk1 itakayofanywa overflow na chunk2 ili top chunk isiyoungane na zile zilizotangulia. - Kisha, chunk1 inafree-uliwa na chunk0 inaoverflow hadi `bk` pointer ya chunk1 ionyeshe: `bk = magic - 0x10` - Kisha, chunk3 inaitwa na kuallocate kwa ukubwa sawa na chunk1, ambayo itasababisha unsorted bin attack na kubadilisha thamani ya global variable, kuruhusu kupata flag. - [**https://guyinatuxedo.github.io/31-unsortedbin_attack/0ctf16_zerostorage/index.html**](https://guyinatuxedo.github.io/31-unsortedbin_attack/0ctf16_zerostorage/index.html) - Function ya merge ni vulnerabile kwa sababu iwapo index zote mbili zinazopitishwa ni sawa itafanya realloc juu yake na kisha free lakini ikarejesha pointer kwa eneo lililofutwa ambalo linaweza kutumika. - Kwa hiyo, **chunks 2 ziliundwa**: **chunk0** ambayo itachanganywa na yenyewe na chunk1 ili kuzuia consolidation na top chunk. Kisha, function ya **merge** inaitwa na chunk0 mara mbili ambayo itasababisha use after free. - Kisha, function ya **`view`** inaitwa na index 2 (ambayo ni index ya chunk ya use after free), ambayo ita**leak** anwani ya libc. - Kwa kuwa binary ina ulinzi wa kuzuia malloc sizes ndogo kuliko **`global_max_fast`** hivyo hakuna fastbin inayotumiwa, unsorted bin attack itatumika kuchapisha `global_max_fast`. - Kisha, inawezekana kuita function ya edit kwa index 2 (pointer ya use after free) na kubadilisha `bk` pointer ili iendelee kuonyesha kwa `p64(global_max_fast-0x10)`. Kisha, kuunda chunk mpya kutatumia address ya free iliyoharibiwa (0x20) na **kusababisha unsorted bin attack** ikichapisha `global_max_fast` kuwa thamani kubwa sana, ikiruhusu sasa kuunda chunks katika fast bins. - Sasa shambulio la **fast bin** linafanywa: - Kwanza iligundulika kwamba inawezekana kufanya kazi na fast **chunks za size 200** katika eneo la **`__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 : 0x0000000000000000 0x0000000000000000
0x7ff1e9e6077f <_IO_stdfile_2_lock+15>: 0x0000000000000000 0x0000000000000000
- Ikiwa tunafanikiwa kupata fast chunk ya size 0x200 katika eneo hili, itakuwa uwezekano wa kuchapisha function pointer itakayotekelezwa.
- Kwa hili, chunk mpya ya size `0xfc` inaundwa na merged function inaitwa nayo mara mbili, kwa njia hii tunapata pointer kwa freed chunk ya size `0xfc*2 = 0x1f8` katika fast bin.
- Kisha, function ya edit inaitwa kwenye chunk hii kubadilisha anwani ya **`fd`** ya fast bin hii ili iwekelee kwenye `__free_hook`.
- Kisha, chunk ya size `0x1f8` inaundwa ili kurejesha kutoka fast bin chunk isiyotumika, kisha chunk nyingine ya size `0x1f8` inaundwa kupata fast bin chunk katika **`__free_hook`** ambayo inachapishwa na anwani ya function ya **`system`**.
- Na hatimaye chunk yenye string `/bin/sh\x00` inafree-uliwa kwa kutumia function ya delete, kutekeleza **`__free_hook`** ambayo sasa inaonyesha system na `/bin/sh\x00` kama parameta.
- **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)
- Mfano mwingine wa kutumia overflow ya 1B kuunganisha chunks katika unsorted bin na kupata libc infoleak na kisha kufanya fast bin attack kubadilisha malloc hook kwa one gadget address
- [**Robot Factory. BlackHat MEA CTF 2022**](https://7rocky.github.io/en/ctf/other/blackhat-ctf/robot-factory/)
- Tunaweza tu kuallocate chunks za size kubwa kuliko `0x100`.
- Chapisha `global_max_fast` kwa kutumia Unsorted Bin attack (inafanya kazi 1/16 mara kutokana na ASLR, kwa sababu tunahitaji kubadilisha bit 12, lakini lazima tubadilishe bit 16).
- Fast Bin attack kubadilisha array ya global ya chunks. Hii inatoa primitive ya arbitrary read/write, ambayo inaruhusu kubadilisha GOT na kuweka function fulani ili ianze kuonyesha `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}}