Relro

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

Relro

RELRO staan vir Relocation Read-Only en dit is 'n versagting wat deur die linker (ld) geĂŻmplementeer word wat 'n substel van die ELF se datasegmente lees-alleen maak nadat alle herlokasies toegepas is. Die doel is om 'n aanvaller te stop om inskrywings in die GOT (Global Offset Table) of ander herlokasie-verwante tabelle wat tydens programuitvoering gedereferensieer word (bv. __fini_array) te oorskry.

Moderne linkers implementeer RELRO deur die GOT (en 'n paar ander afdelings) te herorden sodat hulle voor die .bss woon en – die belangrikste – deur 'n toegewyde PT_GNU_RELRO segment te skep wat R–X herkaarteer reg na die dinamiese laaier klaar is met die toepassing van herlokasies. Gevolglik kan tipiese buffer oorgroeis in die .bss nie meer die GOT bereik nie en arbitrĂȘre skryfprimitiewe kan nie gebruik word om funksie-aanwysers wat binne 'n RELRO-beskermde bladsy sit, te oorskry nie.

Daar is twee vlakke van beskerming wat die linker kan uitreik:

Gedeeltelike RELRO

  • Geproduseer met die vlag -Wl,-z,relro (of net -z relro wanneer ld direk aangeroep word).
  • Slegs die nie-PLT deel van die GOT (die deel wat vir dataskakelings gebruik word) word in die lees-alleen segment geplaas. Afdelings wat tydens uitvoering gewysig moet word – die belangrikste is .got.plt wat luie binding ondersteun – bly skryfbaar.
  • As gevolg hiervan kan 'n arbitrĂȘre skryf primitiewe steeds die uitvoeringsvloei herlei deur 'n PLT-inskrywing te oorskry (of deur ret2dlresolve uit te voer).
  • Die prestasie-impak is verwaarloosbaar en daarom het byna elke verspreiding al jare lank pakkette met ten minste Gedeeltelike RELRO gestuur (dit is die GCC/Binutils standaard sedert 2016).

Volledige RELRO

  • Geproduseer met albei vlae -Wl,-z,relro,-z,now (ook bekend as -z relro -z now). -z now dwing die dinamiese laaier om alle simbole vooraf op te los (gretige binding) sodat .got.plt nooit weer geskryf hoef te word nie en veilig lees-alleen kan wees.
  • Die hele GOT, .got.plt, .fini_array, .init_array, .preinit_array en 'n paar addisionele interne glibc tabelle eindig binne 'n lees-alleen PT_GNU_RELRO segment.
  • Voeg meetbare opstart oorhoofse koste by (alle dinamiese herlokasies word by die bekendstelling verwerk) maar geen uitvoering oorhoofse koste nie.

Sedert 2023 het verskeie hoofstroom verspreidings oorgeskakel na die kompilering van die stelsels hulpmiddel-ketting (en die meeste pakkette) met Volledige RELRO as standaard – bv. Debian 12 “bookworm” (dpkg-buildflags 13.0.0) en Fedora 35+. As 'n pentester moet jy dus verwag om binaries te teĂ«kom waar elke GOT-inskrywing lees-alleen is.


Hoe om die RELRO-status van 'n binĂȘre te kontroleer

bash
$ checksec --file ./vuln
[*] '/tmp/vuln'
Arch:     amd64-64-little
RELRO:    Full
Stack:    Canary found
NX:       NX enabled
PIE:      No PIE (0x400000)

checksec (deel van pwntools en baie verspreidings) ontleed ELF koppe en druk die beskermingsvlak. As jy nie checksec kan gebruik nie, vertrou op readelf:

bash
# Partial RELRO → PT_GNU_RELRO is present but BIND_NOW is *absent*
$ readelf -l ./vuln | grep -E "GNU_RELRO|BIND_NOW"
GNU_RELRO      0x0000000000600e20 0x0000000000600e20
bash
# Full RELRO → PT_GNU_RELRO *and* the DF_BIND_NOW flag
$ readelf -d ./vuln | grep BIND_NOW
0x0000000000000010 (FLAGS)              FLAGS: BIND_NOW

As die binĂȘre loop (bv. 'n set-uid root helper), kan jy steeds die uitvoerbare lĂȘer inspekteer via /proc/$PID/exe:

bash
readelf -l /proc/$(pgrep helper)/exe | grep GNU_RELRO

Aktivering van RELRO wanneer jy jou eie kode saamstel

bash
# GCC example – create a PIE with Full RELRO and other common hardenings
$ gcc -fPIE -pie -z relro -z now -Wl,--as-needed -D_FORTIFY_SOURCE=2 main.c -o secure

-z relro -z now werk vir beide GCC/clang (gegee na -Wl,) en ld direk. Wanneer jy CMake 3.18+ gebruik, kan jy Volle RELRO met die ingeboude voorinstelling versoek:

cmake
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON) # LTO
set(CMAKE_ENABLE_EXPORTS OFF)
set(CMAKE_BUILD_RPATH_USE_ORIGIN ON)
set(CMAKE_EXE_LINKER_FLAGS "-Wl,-z,relro,-z,now")

Bypass Tegnieke

RELRO vlakTipiese primitieweMoglike uitbuitingstegnieke
Geen / GedeeltelikWillekeurige skrywe1. Oorskry .got.plt inskrywing en draai uitvoering om.
2. ret2dlresolve – vervaardig vals Elf64_Rela & Elf64_Sym in 'n skryfbare segment en bel _dl_runtime_resolve aan.
3. Oorskry funksie-aanwysers in .fini_array / atexit() lys.
VolGOT is lees-slegs1. Soek ander skryfbare kode-aanwysers (C++ vtables, __malloc_hook < glibc 2.34, __free_hook, terugroepe in pasgemaakte .data afdelings, JIT bladsye).
2. Misbruik relatiewe lees primitiewe om libc te lek en SROP/ROP in libc uit te voer.
3. Spuit 'n rogue gedeelde objek via DT_RPATH/LD_PRELOAD (as omgewing deur die aanvaller beheer word) of ld_audit.
4. Exploit formaat-string of gedeeltelike aanwyser oorskrywing om die beheerstroom te lei sonder om die GOT aan te raak.

💡 Selfs met Vol RELRO is die GOT van gelaaide gedeelde biblioteke (bv. libc self) slegs Gedeeltelik RELRO omdat daardie objekte reeds gemap is wanneer die laaier herlokasies toepas. As jy 'n willekeurige skrywe primitiewe verkry wat 'n ander gedeelde objek se bladsye kan teiken, kan jy steeds uitvoering draai deur libc se GOT inskrywings of die __rtld_global stapel oor te skryf, 'n tegniek wat gereeld in moderne CTF-uitdagings benut word.

Werklike wĂȘreld omseil voorbeeld (2024 CTF – pwn.college “verlig”)

Die uitdaging is gestuur met Vol RELRO. Die uitbuiting het 'n off-by-one gebruik om die grootte van 'n heap stuk te korrupteer, libc gelekt met tcache poisoning, en uiteindelik __free_hook (buite die RELRO segment) oorgeskryf met 'n een-gadget om kode-uitvoering te verkry. Geen GOT skrywe was nodig nie.


Onlangse navorsing & kwesbaarhede (2022-2025)

  • glibc 2.40 de-precates __malloc_hook / __free_hook (2025) – Meeste moderne heap uitbuitings wat hierdie simbole misbruik het nou die noodsaak om na alternatiewe vektore soos rtld_global._dl_load_jump of C++ uitsonderingstabelle te draai. Omdat haken buite RELRO leef, verhoog hul verwydering die moeilikheidsgraad van Vol-RELRO omseilings.
  • Binutils 2.41 “max-page-size” regstelling (2024) – 'n Fout het toegelaat dat die laaste paar bytes van die RELRO segment 'n bladsy met skryfbare data op sommige ARM64 boude deel, wat 'n klein RELRO gaping gelaat het wat na mprotect geskryf kon word. Upstream belyn nou PT_GNU_RELRO met bladsygrense, wat daardie randgeval uitskakel.

Verwysings

  • Binutils dokumentasie – -z relro, -z now en PT_GNU_RELRO
  • “RELRO – Vol, Gedeeltelik en Omseil Tegnieke” – blogpos @ wolfslittlered 2023

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