House of Roman

Tip

Leer en oefen AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Leer en oefen GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Leer en oefen Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Ondersteun HackTricks

Basiese Inligting

Dit was ’n baie interessante tegniek wat RCE moontlik gemaak het sonder ’n leak via fake fastbins, die unsorted_bin-aanval en relative overwrites. Dit is egter gepatch.

Toepasbaarheid in 2026

  • glibc window: Werk betroubaar op 2.23–2.27 (die how2heap PoC het 2.23–2.25 getoets). Starting 2.28, die “additional checks for unsorted bin integrity” patch maak die unsorted‑bin write onbetroubaar, so sukses daal skerp. Vanaf 2.34 is __malloc_hook/__free_hook verwyder, wat die oorspronklike teiken onbruikbaar maak. Gebruik dit slegs op ou libc’s (of custom builds wat die hooks behou) of vir CTF challenges wat ’n ou libc saamlewer.
  • Tcache era (≥2.26): Tcache sal jou 0x70 allocations opvreet en die fastbin/unsorted primitives stop. Deaktiveer dit (setenv("GLIBC_TUNABLES","glibc.malloc.tcache_count=0",1);) voor enige allocation of vul elke 0x70 tcache bin met 7 frees om dit leeg te maak.
  • Safe-linking: Dit geld vir tcache/fastbin in ≥2.32, maar House of Roman benodig slegs partial pointer overwrite of a libc address already present in fd/bk, so safe-linking help die verdediger nie hier nie (die aanvaller forgeer nooit ’n nuwe pointer nie). Die werklike stopper is die verwydering van die hooks en die unsorted-bin checks.

Kode

Doel

  • RCE deur relative pointers te misbruik

Vereistes

  • Wysig fastbin en unsorted bin pointers
  • 12 bits van randomness moet deur brute force gekraak word (0.02% kans) om te werk

Aanvalstappe

Deel 1: Fastbin Chunk points to __malloc_hook

Skep verskeie chunks:

  • fastbin_victim (0x60, offset 0): UAF chunk wat later gebruik word om die heap pointer te wysig sodat dit na die LibC-waarde wys.
  • chunk2 (0x80, offset 0x70): Vir goeie uitlijning
  • main_arena_use (0x80, offset 0x100)
  • relative_offset_heap (0x60, offset 0x190): relatiewe offset op die ‘main_arena_use’ chunk

Dan free(main_arena_use) wat hierdie chunk in die unsorted lys sal plaas en ’n pointer na main_arena + 0x68 in beide die fd en bk pointers sal kry.

Nou word ’n nuwe chunk fake_libc_chunk(0x60) toegeken omdat dit die pointers na main_arena + 0x68 in fd en bk sal bevat.

Dan word relative_offset_heap en fastbin_victim vrygestel.

/*
Current heap layout:
0x0:   fastbin_victim       - size 0x70
0x70:  alignment_filler     - size 0x90
0x100: fake_libc_chunk      - size 0x70 (contains a fd ptr to main_arena + 0x68)
0x170: leftover_main        - size 0x20
0x190: relative_offset_heap - size 0x70

bin layout:
fastbin:  fastbin_victim -> relative_offset_heap
unsorted: leftover_main
*/
  • fastbin_victim het ’n fd wat na relative_offset_heap wys
  • relative_offset_heap is ’n offset vanaf fake_libc_chunk, wat ’n pointer na main_arena + 0x68 bevat
  • Deur die laaste byte van fastbin_victim.fd te verander laat fastbin_victim na main_arena + 0x68 wys.

Vir die voorafgaande stappe moet die aanvaller in staat wees om die fd-pointer van fastbin_victim te wysig.

Dan is main_arena + 0x68 nie so interessant nie, so laat ons dit wysig sodat die pointer na __malloc_hook wys.

Let wel dat __memalign_hook gewoonlik met 0x7f begin en daarvoor zeros het, dus is dit moontlik om dit te vervals as ’n waarde in die 0x70 fast bin. Omdat die laaste 4 bits van die adres random is, is daar 2^4=16 moontlikhede vir die waarde om uiteindelik te wys waar ons belangstel. Daarom word hier ’n BF attack uitgevoer sodat die chunk eindig soos: 0x70: fastbin_victim -> fake_libc_chunk -> (__malloc_hook - 0x23).

(For more info about the rest of the bytes check the explanation in the how2heap example). As die brute force misluk, stort die program net (herbegin totdat dit werk).

Dan word 2 mallocs uitgevoer om die 2 aanvanklike fast bin chunks te verwyder en ’n derde een word toegeken om ’n chunk in __malloc_hook te kry.

malloc(0x60);
malloc(0x60);
uint8_t* malloc_hook_chunk = malloc(0x60);

Deel 2: Unsorted_bin attack

Vir meer inligting kan jy kyk:

Unsorted Bin Attack

Maar basies laat dit toe om main_arena + 0x68 na enige ligging te skryf wat in chunk->bk gespesifiseer is. Vir die aanval kies ons __malloc_hook. Daarna, nadat ons dit oorskryf het, sal ons ’n relatiewe overskryf gebruik om na ’n one_gadget te wys.

Hiervoor begin ons ’n chunk kry en dit in die unsorted bin sit:

uint8_t* unsorted_bin_ptr = malloc(0x80);
malloc(0x30); // Don't want to consolidate

puts("Put chunk into unsorted_bin\n");
// Free the chunk to create the UAF
free(unsorted_bin_ptr);

Gebruik ’n UAF in hierdie chunk om unsorted_bin_ptr->bk na die adres van __malloc_hook te wys (we brute forced this previously).

Caution

Let wel dat hierdie aanval die unsorted bin korrupteer (dus ook small en large). Daarom kan ons nou slegs use allocations from the fast bin now (ʼn meer komplekse program mag ander allocations doen en crash), en om dit te trigger moet ons alloc the same size or the program will crash.

So, to trigger the write of main_arena + 0x68 in __malloc_hook we perform after setting __malloc_hook in unsorted_bin_ptr->bk we just need to do: malloc(0x80)

Stap 3: Stel __malloc_hook na system

In stap een het ons beheer gehad oor ’n chunk wat __malloc_hook bevat (in die veranderlike malloc_hook_chunk) en in die tweede stap het ons daarin geslaag om main_arena + 0x68 daar te skryf.

Nou misbruik ons ’n partial overwrite in malloc_hook_chunk om die libc-adres wat ons daar geskryf het (main_arena + 0x68) te gebruik om op ’n one_gadget adres te wys.

Hier is waar dit nodig is om bruteforce 12 bits of randomness (meer info in die how2heap example).

Uiteindelik, sodra die korrekte adres oorskryf is, roep malloc aan en trigger die one_gadget.

Moderne wenke & variante

  • Unsorted-bin hardening (2.28+): Die ekstra integriteitskontroles op unsorted chunks (size sanity + list linkage) maak die klassieke unsorted‑bin write broos. Om _int_malloc te oorleef, moet jy fd/bk skakels konsekwent hou en groottes geloofwaardig laat voorkom, wat gewoonlik sterker primitives as ’n eenvoudige partial overwrite vereis.
  • Hook removal (2.34+): Met __malloc_hook weg, pas die primitive aan om op enige beskryfbare GOT/global te land wat jy later kan hergebruik (bv. overskryf exit@GOT in non-PIE binaries) of pivot na ’n House of Pie styl top‑chunk hijack om top te beheer in plaas van ’n hook.
  • Any‑address fastbin alloc (romanking98 writeup): Die tweede deel wys hoe om die 0x71 freelist te herstel en die unsorted‑bin write te gebruik om ’n fastbin toewysing oor __free_hook te kry, dan plaas system("/bin/sh") en trigger dit via free() op libc‑2.24 (pre-hook removal).

Verwysings

Tip

Leer en oefen AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Leer en oefen GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Leer en oefen Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Ondersteun HackTricks