Unsorted Bin Attack

Reading time: 11 minutes

tip

Jifunze na fanya mazoezi ya AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Jifunze na fanya mazoezi ya GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Jifunze na fanya mazoezi ya Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks

Maelezo ya Msingi

Kwa taarifa zaidi kuhusu what is an unsorted bin angalia ukurasa huu:

Bins & Memory Allocations

Unsorted lists zinaweza kuandika anwani ya unsorted_chunks (av) katika anwani ya bk ya chunk. Kwa hivyo, ikiwa attacker anaweza kubadilisha anwani ya pointer ya bk katika chunk ndani ya unsorted bin, anaweza kuwa na uwezo wa kuandika anwani hiyo kwenye anwani yoyote ambayo inaweza kusaidia ku-leak anwani za Glibc au kupitisha baadhi ya ulinzi.

Kimsingi, shambulio hili huruhusu kuweka namba kubwa kwenye anwani yoyote. Namba hii kubwa ni anwani, ambayo inaweza kuwa anwani ya heap au anwani ya Glibc. Lengo la jadi lilikuwa global_max_fast ili kuwezesha kuunda fast bins zenye ukubwa mkubwa (na kusonga kutoka unsorted bin attack hadi fast bin attack).

  • Modern note (glibc ≄ 2.39): global_max_fast imekuwa globali ya 8‑bit. Kuandika pointer pale bila kujali kupitia unsorted‑bin write kutaharibu data za libc jirani na haitainua kwa uhakika kikomo cha fastbin tena. Chagua malengo mengine au primitives nyingine unapokimbia dhidi ya glibc 2.39+. Angalia "Modern constraints" hapa chini na fikiria kuunganisha na mbinu nyingine kama large bin attack au fast bin attack ukipata primitive thabiti.

tip

Kuangalia mfano uliotolewa katika https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted_bin_attack/#principle na kutumia 0x4000 na 0x5000 badala ya 0x400 na 0x500 kama sizes za chunk (kuepuka Tcache) inaonyesha kuwa sasa kosa malloc(): unsorted double linked list corrupted linaibuliwa.

Kwa hivyo, shambulio hili la unsorted bin sasa (pamoja na ukaguzi mwingine) pia linahitaji uwezo wa kurekebisha double linked list ili kuepuka ukaguzi huo victim->bk->fd == victim au victim->fd == av (arena), ambayo ina maana anwani tunayotaka kuandika lazima iwe na anwani ya fake chunk katika nafasi yake ya fd na kwamba fd ya fake chunk inazingatia arena.

caution

Kumbuka kwamba shambulio hili linaharibu unsorted bin (na hivyo ndogo na kubwa pia). Kwa hivyo tunaweza tu kutumia allocations kutoka fast bin sasa (programu ngumu zaidi inaweza kufanya allocations nyingine na ku-crash), na kuamsha hili lazima tunallocate ukubwa ule huo au programu ita-crash.

Kumbuka kwamba kuandika juu ya global_max_fast kunaweza kusaidia katika kesi hii ukitegemea kuwa fast bin itashughulikia allocations nyingine zote hadi exploit itakapokamilika.

Msimbo kutoka kwa guyinatuxedo unaelezea vizuri sana, ingawa ikiwa utakusanya mallocs ili kuwasilisha memory kubwa vya kutosha ili tusifikie Tcache utaona kwamba kosa lililotajwa hapo juu linaibuka na kuzuia mbinu hii: malloc(): unsorted double linked list corrupted

Jinsi uandishi unavyotokea kwa kweli

  • The unsorted-bin write inafanywa wakati wa free wakati chunk iliyofunguliwa inaingizwa kuwa kichwa cha unsorted list.
  • During insertion, the allocator performs 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 itakaposhughulikia unsorted bin, ukaguzi wa integriti utathibitisha (pamoja na mambo mengine) kwamba bck->fd == victim na victim->fd == unsorted_chunks(av) kabla ya unlinking. Kwa sababu insertion tayari iliandika victim ndani ya bck->fd (TARGET yetu), ukaguzi huu unaweza kukidhiwa kama uandishi ulifanikiwa.

Modern constraints (glibc ≄ 2.33)

Ili kutumia unsorted‑bin writes kwa uhakika kwenye glibc ya sasa:

  • Tcache interference: kwa sizes zinazopingana na tcache, frees zinaelekezwa huko na hazitagusa unsorted bin. Au
  • fanya requests za sizes > MAX_TCACHE_SIZE (≄ 0x410 kwa 64‑bit kwa default), au
  • jaza tcache bin inayohusiana (entries 7) ili frees za ziada zifikie global bins, au
  • kama mazingira yanaweza kudhibitiwa, zima tcache (mfano, GLIBC_TUNABLES glibc.malloc.tcache_count=0).
  • Integrity checks kwenye unsorted list: kwenye njia inayofuata ya allocation inayotazama unsorted bin, glibc inakagua (simplified):
  • bck->fd == victim na victim->fd == unsorted_chunks(av); vinginevyo inakata na malloc(): unsorted double linked list corrupted.
  • Hii ina maana anwani unayolenga lazima ivumilie uandishi mara mbili: kwanza *(TARGET) = victim wakati wa free; baadaye, wakati chunk inapoondolewa, *(TARGET) = unsorted_chunks(av) (allocator anaandika tena bck->fd kurudi kichwani mwa bin). Chagua malengo ambapo kulazimisha tu thamani kubwa isiyokuwa sifuri ni muhimu.
  • Malengo ya kawaida thabiti katika exploits za kisasa
  • State ya programu au global inayotumiwa kama "large" values kama flags/limits.
  • Indirect primitives (mfano, kuandaa kwa ajili ya [fast bin attack](Fast Bin Attack) inayofuata au kupindisha uandishi mwingine wa write‑what‑where).
  • Epuka __malloc_hook/__free_hook kwenye glibc mpya: ziliondolewa katika 2.34. Epuka global_max_fast kwenye ≄ 2.39 (ona nota ifuatayo).

Kuhusu global_max_fast kwenye glibc za karibuni

  • Katika glibc 2.39+, global_max_fast ni globali ya 8‑bit. Mbinu ya kawaida ya kuandika pointer ya heap humo (kuongeza fastbins) haifanyi kazi safi tena na ina uwezekano wa kuharibu state ya allocator jirani. Tumia mikakati mingine.

Minimal exploitation recipe (modern glibc)

Lengo: pata uandishi mmoja wa anwani ya heap kwenye anwani yoyote ukitumia unsorted‑bin insertion primitive, bila kuleta crash.

  • Layout/grooming
  • Allocate A, B, C kwa sizes kubwa vya kutosha kuepuka tcache (mfano, 0x5000). C inazuia consolidation na top chunk.
  • Corruption
  • Overflow kutoka A hadi header ya chunk ya B ili seti B->bk = (mchunkptr)(TARGET - 0x10).
  • Trigger
  • free(B). Wakati wa insertion allocator itatekeleza bck->fd = B, hivyo *(TARGET) = B.
  • Continuation
  • Ikiwa unapanga kuendelea na kuallocate na programu inatumia unsorted bin, tarajia allocator baadaye kuweka *(TARGET) = unsorted_chunks(av). Thamani zote mbili kwa kawaida ni kubwa na zinaweza kutosha kubadilisha semantics za size/limit kwenye malengo ambayo yanangalia tu "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 kupitisha tcache kwa ukubwa, jaza tcache bin kwa ukubwa ulioteuliwa (7 frees) kabla ya kuachilia chunk iliyoharibika ili free iende kwenye unsorted. • Ikiwa programu inakataza 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 halisi ya victim baada ya uandishi wa kwanza.

Unsorted Bin Infoleak Attack

Hii ni dhana rahisi kabisa. Chunks katika unsorted bin zitakuwa na pointers. Chunk ya kwanza katika unsorted bin itakuwa na viungo vya fd na bk vinavyoelekeza kwenye sehemu ya main arena (Glibc).
Kwa hiyo, ikiwa unaweza kuweka chunk ndani ya unsorted bin na kui-soma (use after free) au kuui-allocate tena bila kuandika juu ya angalau moja ya pointers kisha kusoma hiyo chunk, unaweza kupata Glibc info leak.

A shambulio sawa kilichotumika katika writeup hii, kilitumia muundo wa chunks 4 (A, B, C na D - D ilikuwepo tu kuzuia consolidation na top chunk) hivyo overflow ya null byte katika B ilitumika kufanya C kuonyesha kuwa B haikutumika. Pia, ndani ya B data ya prev_size ilibadilishwa hivyo ukubwa badala ya kuwa ukubwa wa B ulikuwa A+B.
Kisha C ilifunguliwa (deallocated), na ikaunganishwa na A+B (lakini B bado ilikuwa inatumika). Chunk mpya ya ukubwa A ili-allocatewa na kisha libc leaked addresses ziliandikwa ndani ya B kutoka palipozoleak.

References & Other examples

  • https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted_bin_attack/#hitcon-training-lab14-magic-heap
  • Lengo ni kuandika juu global variable na thamani kubwa kuliko 4869 ili iwezekane kupata flag na PIE haijawekwa.
  • Inawezekana kutengeneza chunks za ukubwa wowote na kuna heap overflow kwa ukubwa unaotakiwa.
  • Shambulio linaanza kwa kuunda chunks 3: chunk0 ili kutumika kwa overflow, chunk1 itakayezidiwa (to be overflowed) na chunk2 ili top chunk isiunge pamoja na zilizotangulia.
  • Kisha, chunk1 inaachiliwa na chunk0 inafinywa hadi bk pointer ya chunk1 inavyoonyesha: bk = magic - 0x10
  • Kisha, chunk3 ina-allocatewa kwa ukubwa sawa na chunk1, ambayo itachochea unsorted bin attack na itabadilisha thamani ya global variable, ikifanya iwezekane kupata flag.
  • https://guyinatuxedo.github.io/31-unsortedbin_attack/0ctf16_zerostorage/index.html
  • Kazi ya merge ina vunjao kwa sababu ikiwa index zote mbili zilizoingizwa ni ile ile itafanya realloc juu yake kisha kuifree lakini ikirudisha pointer kwa eneo hilo lililofunguliwa ambalo linaweza kutumika.
  • Kwa hivyo, chunks 2 zinaundwa: chunk0 ambayo itaunganishwa 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 pointer ya use after free), ambayo itafanya leak ya anwani ya libc.
  • Kwa kuwa binary ina ulinzi wa ku-malloc tu sizes zaidi ya global_max_fast hivyo hakuna fastbin inayotumika, unsorted bin attack itatumika kuandika juu global variable global_max_fast.
  • Kisha, inawezekana kuita function ya edit na index 2 (pointer ya use after free) na kuandika juu bk pointer kuifanya iendelee kwa p64(global_max_fast-0x10). Kisha, kuunda chunk mpya kutatumia address ya freed iliyodanganywa (0x20) kutatrigger unsorted bin attack na kuandika juu global_max_fast kuwa thamani kubwa sana, kuruhusu sasa kuunda chunks kwenye fast bins.
  • Sasa shambulio la fast bin linatekelezwa:
  • Kwanza iligundulika inawezekana kufanya kazi na fast chunks za ukubwa 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 <list_all_lock+15>: 0x0000000000000000 0x0000000000000000 0x7ff1e9e6077f <_IO_stdfile_2_lock+15>: 0x0000000000000000 0x0000000000000000

  • Ikiwa tunaweza kupata fast chunk ya size 0x200 katika eneo hili, itakuwa inaweza kuandika juu function pointer ambayo itatekelezwa
  • Kwa hili, chunk mpya ya size 0xfc inaundwa na merged function inaitwa na pointer hiyo mara mbili, kwa njia hii tunapata pointer kwa chunk iliyofunguliwa ya size 0xfc*2 = 0x1f8 katika fast bin.
  • Kisha, function ya edit inaitwa katika chunk hii ili kubadilisha anwani ya fd ya fast bin hii kuielekeza kwenye __free_hook.
  • Kisha, chunk ya size 0x1f8 inaundwa ili kurejesha kutoka fast bin chunk iliyokuwa haina maana hivyo chunk nyingine ya size 0x1f8 inaundwa kupata fast bin chunk katika __free_hook ambayo inaandika juu na anwani ya system.
  • Na hatimaye chunk lenye string /bin/sh\x00 linafrees kwa kuitwa delete function, kuchochea __free_hook ambayo inabeba system na /bin/sh\x00 kama parameter.
  • CTF https://guyinatuxedo.github.io/33-custom_misc_heap/csaw19_traveller/index.html
  • Mfano mwingine wa kutumia 1B overflow kuunganisha chunks katika unsorted bin na kupata libc infoleak kisha kutekeleza fast bin attack kuandika juu malloc hook na one gadget address
  • Robot Factory. BlackHat MEA CTF 2022
  • Tunaweza tu kuallocate chunks za size zaidi ya 0x100.
  • Kufanya overwrite ya global_max_fast kwa kutumia Unsorted Bin attack (inafanya kazi 1/16 kwa sababu ya ASLR, kwa sababu tunahitaji kubadilisha 12 bits, lakini lazima tubadilishe 16 bits).
  • Fast Bin attack kubadilisha global array ya chunks. Hii inatoa primitive ya arbitrary read/write, ambayo inaruhusu kubadilisha GOT na kuweka function fulani 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

tip

Jifunze na fanya mazoezi ya AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Jifunze na fanya mazoezi ya GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Jifunze na fanya mazoezi ya Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks