Relro

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

Relro

RELRO inamaanisha Relocation Read-Only na ni njia ya kuzuia inayotekelezwa na linker (ld) ambayo hufanya sehemu ndogo ya segmenti za data za ELF ziwe soma-tu baada ya relocations zote kutumika. Lengo ni kuzuia mshambuliaji kuandika juu ya maingizo katika GOT (Global Offset Table) au meza nyingine zinazohusiana na relocation ambazo zinarekebishwa wakati wa utekelezaji wa programu (mfano __fini_array).

Modern linkers implement RELRO by re–ordering the GOT (and a few other sections) so they live before the .bss and – most importantly – by creating a dedicated PT_GNU_RELRO segment that is remapped R–X right after the dynamic loader finishes applying relocations. Kwa hivyo, buffer overflows za kawaida katika .bss haziwezi tena kufikia GOT na arbitrary‐write primitives haiwezi kutumika kuandika juu ya function pointers zilizo ndani ya ukurasa ulio na ulinzi wa RELRO.

Kuna ngazi mbili za ulinzi ambazo linker inaweza kutoa:

Partial RELRO

  • Produced with the flag -Wl,-z,relro (or just -z relro when invoking ld directly).
  • Only the non-PLT part of the GOT (the part used for data relocations) is put into the read-only segment. Sections that need to be modified at run-time – most importantly .got.plt which supports lazy binding – remain writable.
  • Kwa sababu hiyo, primitive ya arbitrary write bado inaweza kuelekeza mtiririko wa utekelezaji kwa kuandika juu ya entry ya PLT (au kwa kufanya ret2dlresolve).
  • The performance impact is negligible and therefore almost every distribution has been shipping packages with at least Partial RELRO for years (it is the GCC/Binutils default as of 2016).

Full RELRO

  • Produced with both flags -Wl,-z,relro,-z,now (a.k.a. -z relro -z now). -z now forces the dynamic loader to resolve all symbols up-front (eager binding) so that .got.plt never needs to be written again and can safely be mapped read-only.
  • The entire GOT, .got.plt, .fini_array, .init_array, .preinit_array and a few additional internal glibc tables end up inside a read-only PT_GNU_RELRO segment.
  • Inakuongeza overhead inayoonekana wakati wa kuanzisha (relocations zote za dynamic zinashughulikiwa wakati wa kuanzisha) lakini hakuna overhead wakati wa utekelezaji.

Tangu 2023 baadhi ya distributions za kawaida zimebadilisha taratibu zao za kujenga kwa kucompile system tool-chain (na pakiti nyingi) kwa Full RELRO kwa default – kwa mfano Debian 12 “bookworm” (dpkg-buildflags 13.0.0) na Fedora 35+. Kama pentester, kwa hiyo unapaswa kutegemea kukutana na binaries ambapo kila entry ya GOT ni soma-tu.


How to Check the RELRO status of a binary

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

checksec (sehemu ya pwntools na usambazaji mwingi) huchambua vichwa vya ELF na kuchapisha kiwango cha ulinzi. Ikiwa huwezi kutumia checksec, tegemea readelf:

# 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
# Full RELRO → PT_GNU_RELRO *and* the DF_BIND_NOW flag
$ readelf -d ./vuln | grep BIND_NOW
0x0000000000000010 (FLAGS)              FLAGS: BIND_NOW

Ikiwa binary inakimbia (kwa mfano set-uid root helper), bado unaweza kuchunguza executable kupitia /proc/$PID/exe:

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

Kuwezesha RELRO wakati unajenga msimbo wako mwenyewe

# 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 inafanya kazi kwa GCC/clang (inapitishwa baada ya -Wl,) na ld moja kwa moja. Wakati unapotumia CMake 3.18+ unaweza kuomba Full RELRO kwa preset iliyojengwa ndani:

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")

Mbinu za Kupitisha

RELRO levelTypical primitivePossible exploitation techniques
None / PartialArbitrary write1. Andika juu ya .got.plt entry na pivot execution.
2. ret2dlresolve – craft fake Elf64_Rela & Elf64_Sym in a writable segment and call _dl_runtime_resolve.
3. Andika juu ya function pointers katika .fini_array / atexit() list.
FullGOT ni kwa kusoma tu1. Tafuta other writable code pointers (C++ vtables, __malloc_hook < glibc 2.34, __free_hook, callbacks in custom .data sections, JIT pages).
2. Tumia vibaya relative read primitives ili leak libc na kufanya SROP/ROP into libc.
3. Ingiza shared object haribifu via DT_RPATH/LD_PRELOAD (ikiwa environment iko under attacker control) au ld_audit.
4. Exploit format-string au partial pointer overwrite ili kutenganisha control-flow bila kugusa GOT.

💡 Hata kwa Full RELRO the GOT of loaded shared libraries (e.g. libc itself) is only Partial RELRO because those objects are already mapped when the loader applies relocations. Ikiwa utapata arbitrary write primitive inayoweza kulenga ukurasa wa shared object mwingine bado unaweza pivot execution kwa kuandika juu libc’s GOT entries au stack ya __rtld_global, mbinu inayotumika mara kwa mara katika changamoto za kisasa za CTF.

Mfano halisi wa kupitisha (2024 CTF – pwn.college “enlightened”)

Changamoto ililetwa na Full RELRO. Exploit ilitumia off-by-one kubadilisha ukubwa wa heap chunk, leaked libc with tcache poisoning, na hatimaye iliandika juu __free_hook (nje ya RELRO segment) na one-gadget kupata code execution. Hakukuwa na GOT write iliyohitajika.


Utafiti wa hivi karibuni & udhaifu (2022-2025)

  • glibc hook removal (2.34 → present) – malloc/free hooks zilitolewa kutoka katika libc kuu na kuhamishiwa kwenye hiari libc_malloc_debug.so, zikiondoa primitive ya kawaida ya bypass ya Full‑RELRO; exploits za kisasa lazima zilenga pointers nyingine zinazoweza kuandikwa.
  • GNU ld RELRO page‑alignment fix (binutils 2.39+/2.41) – mdudu wa linker 30612 ulisababisha bait za mwisho za PT_GNU_RELRO kushirikiana ukurasa unaoweza kuandikwa kwenye mifumo yenye ukurasa wa 64 KiB; binutils za sasa zinapanga RELRO kwa max-page-size, zikifunga ile “RELRO gap”.

References

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