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
- Angalia mpango wa usajili!
- Jiunge na š¬ kikundi cha Discord au kikundi cha telegram au tufuatilie kwenye Twitter š¦ @hacktricks_live.
- Shiriki mbinu za hacking kwa kuwasilisha PRs kwa HackTricks na HackTricks Cloud repos za github.
Maelezo ya Msingi
Kwa taarifa zaidi kuhusu what is an unsorted bin angalia ukurasa huu:
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 kuitafree(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
navictim->fd == unsorted_chunks(av)
kabla ya unlinking. Kwa sababu insertion tayari iliandikavictim
ndani yabck->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
navictim->fd == unsorted_chunks(av)
; vinginevyo inakata namalloc(): 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 tenabck->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. Epukaglobal_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 itatekelezabck->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:
// 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 variableglobal_max_fast
. - Kisha, inawezekana kuita function ya edit na index 2 (pointer ya use after free) na kuandika juu
bk
pointer kuifanya iendelee kwap64(global_max_fast-0x10)
. Kisha, kuunda chunk mpya kutatumia address ya freed iliyodanganywa (0x20) kutatrigger unsorted bin attack na kuandika juuglobal_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 size0xfc*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 size0x1f8
inaundwa kupata fast bin chunk katika__free_hook
ambayo inaandika juu na anwani yasystem
. - 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
- Angalia mpango wa usajili!
- Jiunge na š¬ kikundi cha Discord au kikundi cha telegram au tufuatilie kwenye Twitter š¦ @hacktricks_live.
- Shiriki mbinu za hacking kwa kuwasilisha PRs kwa HackTricks na HackTricks Cloud repos za github.