Relro
Tip
AWS हैकिंग सीखें और अभ्यास करें:
HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें:HackTricks Training GCP Red Team Expert (GRTE)
Azure हैकिंग सीखें और अभ्यास करें:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks का समर्थन करें
- सदस्यता योजनाओं की जांच करें!
- हमारे 💬 Discord समूह या टेलीग्राम समूह में शामिल हों या हमें Twitter 🐦 @hacktricks_live** पर फॉलो करें।**
- हैकिंग ट्रिक्स साझा करें और HackTricks और HackTricks Cloud गिटहब रिपोजिटरी में PRs सबमिट करें।
Relro
RELRO का मतलब Relocation Read-Only है और यह linker (ld) द्वारा लागू की गई एक mitigation है जो ELF के कुछ data segments को सारी relocations लागू होने के बाद read-only बना देता है। उद्देश्य यह है कि attacker उन entries को overwrite न कर सके जो execution के दौरान dereference किए जाते हैं — जैसे GOT (Global Offset Table) या अन्य relocation-संबंधित tables (उदा. __fini_array)।
Modern linkers RELRO को लागू करते हैं GOT (और कुछ अन्य sections) को re–order करके ताकि वे .bss से पहले रहें और — सबसे महत्वपूर्ण — एक समर्पित PT_GNU_RELRO segment बनाकर जिसे dynamic loader relocations लागू करने के तुरंत बाद R–X के रूप में remap कर देता है। परिणामस्वरूप, .bss में सामान्य buffer overflows अब GOT तक नहीं पहुँच पाते और arbitrary‐write primitives का उपयोग RELRO-protected पेज के अंदर मौजूद function pointers को overwrite करने के लिए नहीं किया जा सकता।
Linker दो स्तर की सुरक्षा निकाल सकता है:
Partial RELRO
- यह flag
-Wl,-z,relro(या सीधेldचलाते समय सिर्फ-z relro) के साथ बनाया जाता है। - केवल non-PLT हिस्सा of the GOT (data relocations के लिए उपयोग होने वाला हिस्सा) read-only segment में डाला जाता है। जिन sections को run-time पर संशोधित करने की ज़रूरत होती है — सबसे महत्वपूर्ण .got.plt जो lazy binding को support करता है — वे writable ही रहते हैं।
- इसलिए, एक arbitrary write primitive अभी भी execution flow को redirect कर सकता है PLT entry को overwrite करके (या ret2dlresolve करके)।
- प्रदर्शन पर प्रभाव नगण्य है और इसलिए लगभग हर distribution वर्षों से कम से कम Partial RELRO के साथ packages दे रहा है (यह 2016 के बाद से GCC/Binutils का default है)।
Full RELRO
- यह दोनों flags के साथ बनाया जाता है
-Wl,-z,relro,-z,now(a.k.a.-z relro -z now)।-z nowdynamic loader को बाध्य करता है कि वह सभी symbols पहले से resolve कर दे (eager binding), ताकि .got.plt को दोबारा लिखने की ज़रूरत न पड़े और इसे सुरक्षित रूप से read-only map किया जा सके। - पूरा GOT, .got.plt, .fini_array, .init_array, .preinit_array और कुछ अतिरिक्त internal glibc tables अंततः एक read-only
PT_GNU_RELROsegment में चले जाते हैं। - measurable start-up overhead जोड़ता है (सभी dynamic relocations launch पर process होते हैं) पर कोई run-time overhead नहीं होता।
Since 2023 कई mainstream distributions ने system tool-chain (और अधिकांश packages) को डिफ़ॉल्ट रूप से Full RELRO by default के साथ compile करना शुरू कर दिया है — जैसे Debian 12 “bookworm” (dpkg-buildflags 13.0.0) और Fedora 35+। इसलिए एक pentester के रूप में आपको उम्मीद करनी चाहिए कि आप ऐसे binaries पाएँगे जिनमें हर GOT entry read-only होगी।
किसी binary में RELRO की स्थिति कैसे जांचें
$ checksec --file ./vuln
[*] '/tmp/vuln'
Arch: amd64-64-little
RELRO: Full
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)
checksec (part of pwntools और कई वितरणों) ELF हेडर्स को पार्स करता है और सुरक्षा स्तर प्रिंट करता है। यदि आप checksec का उपयोग नहीं कर सकते हैं, तो 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
यदि बाइनरी चल रही है (उदा. set-uid root helper), तो आप अभी भी executable को via /proc/$PID/exe निरीक्षण कर सकते हैं:
readelf -l /proc/$(pgrep helper)/exe | grep GNU_RELRO
RELRO को सक्षम करना जब आप अपना कोड कंपाइल कर रहे हों
# 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 दोनों के लिए काम करता है GCC/clang (जो -Wl, के बाद पास किया जाता है) और सीधे ld पर। जब आप CMake 3.18+ का उपयोग कर रहे हों तो आप बिल्ट-इन प्रीसेट के साथ Full RELRO का अनुरोध कर सकते हैं:
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")
बायपास तकनीकें
| RELRO level | Typical primitive | Possible exploitation techniques |
|---|---|---|
| None / Partial | Arbitrary write | 1. .got.plt एंट्री को ओवरराइट करके execution pivot करें। 2. ret2dlresolve – writable segment में नकली Elf64_Rela & Elf64_Sym बनाकर _dl_runtime_resolve को कॉल करें।3. .fini_array / atexit() सूची में मौजूद function pointers को ओवरराइट करें। |
| Full | GOT is read-only | 1. किसी अन्य writable code pointers की तलाश करें (C++ vtables, __malloc_hook < glibc 2.34, __free_hook, custom .data सेक्शन में callbacks, JIT pages)।2. relative read primitives को abuse करके libc को प्राप्त करें और SROP/ROP into libc करें। 3. अगर environment attacker‑controlled है तो DT_RPATH/ LD_PRELOAD के जरिए rogue shared object inject करें या ld_audit का उपयोग करें।4. format-string या partial pointer overwrite का उपयोग करके GOT को छुए बिना control-flow बदलें। |
💡 Full RELRO होने के बावजूद, loaded shared libraries (जैसे libc स्वयं) का GOT अक्सर only Partial RELRO होता है क्योंकि loader द्वारा relocations लागू किए जाने पर वे objects पहले से ही mapped होते हैं। यदि आपके पास ऐसा arbitrary write primitive है जो किसी अन्य shared object के pages को टार्गेट कर सकता है, तो आप अभी भी libc के GOT entries या
__rtld_globalstack को ओवरराइट करके execution pivot कर सकते हैं — यह तकनीक आधुनिक CTF चुनौतियों में अक्सर एक्सप्लॉइट की जाती है।
वास्तविक दुनिया का बायपास उदाहरण (2024 CTF – pwn.college “enlightened”)
Challenge Full RELRO के साथ आया था। Exploit ने एक off-by-one का उपयोग करके heap chunk के size को भ्रष्ट किया, libc को leaked किया tcache poisoning से, और अंततः __free_hook (RELRO segment के बाहर) को एक one-gadget से ओवरराइट करके code execution प्राप्त किया। किसी भी GOT write की आवश्यकता नहीं थी।
हाल का रिसर्च और कमजोरियाँ (2022-2025)
- glibc hook removal (2.34 → present) – malloc/free hooks को मुख्य libc से optional
libc_malloc_debug.soमें निकाला गया, जिससे एक सामान्य Full‑RELRO bypass primitive हट गया; modern exploits को अब अन्य writable pointers को लक्षित करना होगा। - GNU ld RELRO page‑alignment fix (binutils 2.39+/2.41) – linker bug 30612 के कारण
PT_GNU_RELROके अंतिम bytes 64 KiB page सिस्टम्स पर एक writable page साझा करते थे; वर्तमान binutils RELRO कोmax-page-sizeके अनुरूप align करता है, जिससे वह “RELRO gap” बंद हो गया।
References
Tip
AWS हैकिंग सीखें और अभ्यास करें:
HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें:HackTricks Training GCP Red Team Expert (GRTE)
Azure हैकिंग सीखें और अभ्यास करें:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks का समर्थन करें
- सदस्यता योजनाओं की जांच करें!
- हमारे 💬 Discord समूह या टेलीग्राम समूह में शामिल हों या हमें Twitter 🐦 @hacktricks_live** पर फॉलो करें।**
- हैकिंग ट्रिक्स साझा करें और HackTricks और HackTricks Cloud गिटहब रिपोजिटरी में PRs सबमिट करें।


