skills/binary-exploitation/common-binary-protections-and-bypasses/relro/SKILL.md
Analyze RELRO (Relocation Read-Only) protections in ELF binaries, check protection status, and understand bypass techniques. Use this skill whenever the user mentions binary protections, ELF analysis, GOT (Global Offset Table), relocation, checksec, readelf, binary exploitation, or security hardening. Trigger for any questions about Partial RELRO, Full RELRO, -z relro, -z now, BIND_NOW, or how to check/enable RELRO in compiled binaries.
npx skillsauth add abelrguezr/hacktricks-skills relro-analysisInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
This skill helps you understand, check, and work with RELRO (Relocation Read-Only) protections in ELF binaries.
# Check RELRO status (requires checksec/pwntools)
checksec --file ./binary
# Check RELRO with readelf (always available)
readelf -l ./binary | grep GNU_RELRO
readelf -d ./binary | grep BIND_NOW
# Compile with Full RELRO
gcc -fPIE -pie -Wl,-z,relro,-z,now -o binary source.c
RELRO (Relocation Read-Only) is a linker mitigation that makes the GOT (Global Offset Table) and related sections read-only after relocations are applied. This prevents attackers from overwriting function pointers via buffer overflows or arbitrary write primitives.
| Level | Flags | GOT Protection | Bypass Possible |
|-------|-------|----------------|------------------|
| None | (default, old) | Writable | Yes - direct GOT overwrite |
| Partial | -Wl,-z,relro | Non-PLT GOT only | Yes - .got.plt still writable |
| Full | -Wl,-z,relro,-z,now | Entire GOT read-only | Harder - need other primitives |
Key insight: Full RELRO requires -z now (eager binding) so .got.plt never needs runtime writes and can be made read-only.
checksec --file ./vuln
Output interpretation:
RELRO: Full → Complete protectionRELRO: Partial → GOT.plt still writableRELRO: No → No protection# Check for PT_GNU_RELRO segment
readelf -l ./binary | grep GNU_RELRO
# Check for BIND_NOW flag (indicates Full RELRO)
readelf -d ./binary | grep BIND_NOW
Interpretation:
GNU_RELRO present + BIND_NOW absent = Partial RELROGNU_RELRO present + BIND_NOW present = Full RELROGNU_RELRO absent = No RELRO# For a running process (e.g., setuid binary)
readelf -l /proc/$(pgrep process_name)/exe | grep GNU_RELRO
# Full RELRO with PIE and other hardenings
gcc -fPIE -pie -Wl,-z,relro,-z,now -Wl,--as-needed -D_FORTIFY_SOURCE=2 source.c -o binary
# Breakdown:
# -fPIE -pie → Position Independent Executable
# -Wl,-z,relro → Create PT_GNU_RELRO segment
# -Wl,-z,now → Eager binding (no lazy loading)
# -Wl,--as-needed → Only link required libraries
# -D_FORTIFY_SOURCE=2 → Buffer overflow protection
set(CMAKE_EXE_LINKER_FLAGS "-Wl,-z,relro,-z,now")
set(CMAKE_SHARED_LINKER_FLAGS "-Wl,-z,relro,-z,now")
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
LDFLAGS += -Wl,-z,relro,-z,now
CFLAGS += -fPIE
LDFLAGS += -pie
.got.plt entry to redirect function callsElf64_Rela and Elf64_Rsym to call _dl_runtime_resolve.fini_array, .init_array, or atexit() handlers__malloc_hook (glibc < 2.34), __free_hook, custom .data sectionsEven with Full RELRO, shared libraries like libc have only Partial RELRO because they're already mapped when the loader applies relocations. If you have an arbitrary write primitive targeting another shared object's pages, you can still pivot execution by overwriting libc's GOT entries.
2024 CTF - pwn.college "enlightened"
__free_hook (outside RELRO segment) with one-gadget| Change | Impact |
|--------|--------|
| glibc 2.34+ - malloc/free hooks moved to libc_malloc_debug.so | Common Full RELRO bypass primitive removed |
| binutils 2.39+ - RELRO page alignment fix (bug 30612) | Closed "RELRO gap" on 64KB page systems |
| Debian 12, Fedora 35+ - Full RELRO default | Expect Full RELRO in most modern binaries |
You're missing -z now. Use both flags: -Wl,-z,relro,-z,now
Yes, but you need different primitives:
__free_hook or similarYes, always. Modern distributions ship with Full RELRO by default. It's a fundamental hardening measure with minimal cost.
testing
How to perform a House of Lore (small bin attack) heap exploitation. Use this skill whenever the user mentions heap exploitation, small bin attacks, fake chunks, glibc heap vulnerabilities, or needs to insert fake chunks into small bins for arbitrary read/write. Trigger for CTF challenges involving heap corruption, glibc 2.31+ exploitation, or when the user needs to bypass malloc sanity checks using fake chunk linking.
testing
How to perform House of Force heap exploitation attacks. Use this skill whenever the user mentions heap exploitation, House of Force, top chunk manipulation, arbitrary memory allocation, malloc manipulation, or wants to allocate chunks at specific addresses. Also trigger for CTF challenges involving heap overflows, top chunk size overwrites, or when the user needs to calculate evil_size for heap attacks. Make sure to use this skill for any binary exploitation task involving glibc heap manipulation, even if they don't explicitly say "House of Force".
tools
How to perform House of Einherjar heap exploitation to allocate memory at arbitrary addresses. Use this skill whenever the user mentions heap exploitation, glibc heap attacks, arbitrary memory allocation, off-by-one overflow exploitation, tcache poisoning, fast bin attacks, or any CTF challenge involving heap manipulation. This is essential for binary exploitation tasks where you need to control malloc() return addresses.
testing
How to identify, analyze, and exploit heap overflow vulnerabilities in binary exploitation challenges and real-world scenarios. Use this skill whenever the user mentions heap overflows, memory corruption, heap grooming, tcache poisoning, fast-bin attacks, or any heap-related vulnerability in CTF challenges, binary analysis, or security research. This skill covers heap overflow fundamentals, exploitation techniques, heap grooming strategies, and real-world CVE analysis.