Binary Exploitation

Binary Protections & Bypasses

Overview of binary security protections including NX, stack canaries, PIE, RELRO, and ASLR along with techniques to bypass each protection.

Contents

Binary Protections & Bypasses

Sources: HackTricks - Protections | Crypto-Cat Binary Exploitation 101


Quick Check: checksec

checksec --file=./binary
    Arch:     amd64-64-little
    RELRO:    Full RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      PIE enabled

Protection: NX / DEP (No-Execute)

What: Stack/heap marked non-executable. Can’t run shellcode on the stack.

Bypass:

  • ROP (Return Oriented Programming) — chain gadgets from executable .text section
  • ret2libc — call existing functions like system()
  • mprotect() via ROP → make a region executable, then jump to shellcode
# Compile WITHOUT NX (for practice)
gcc -z execstack vuln.c -o vuln

Protection: ASLR (Address Space Layout Randomization)

What: Randomizes base addresses of stack, heap, libraries on each execution. Kernel-level.

Bypass:

  • Leak addresses — use format strings, puts/printf of GOT entries
  • Brute force — on 32-bit, only ~12 bits of entropy (4096 possibilities)
  • Partial overwrite — overwrite only lowest 1-2 bytes (which don’t change)
  • ret2plt — PLT addresses are fixed when PIE is off
  • Ret2vsyscall — vsyscall page is at a fixed address on older kernels
# Check ASLR status
cat /proc/sys/kernel/randomize_va_space
# 0=off, 1=partial, 2=full

# Disable ASLR
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space

Protection: PIE (Position Independent Executable)

What: Randomizes the base address of the binary itself (not just libraries).

Bypass:

  • Leak binary address — partial overwrite, format string leak
  • Brute force — 32-bit has limited entropy
  • Partial overwrite — last 12 bits (3 hex chars) are always the same
# Compile WITHOUT PIE
gcc -no-pie vuln.c -o vuln

Protection: Stack Canary

What: Random value placed between local variables and saved return address. Checked before function return — if modified, program calls __stack_chk_fail.

Bypass:

  • Crypto-Cat: Bypassing Canaries
  • Leak canary via format string (%p, %x) or other info leak
  • Brute force byte-by-byte (fork-based servers share same canary)
  • Overwrite __stack_chk_fail GOT → redirect to continue execution
  • Thread canary — canary stored in TLS, can sometimes be overwritten via heap
# Brute force canary (fork-based server)
canary = b'\x00'  # Canaries start with null byte
for i in range(7):
    for byte in range(256):
        p = remote(host, port)
        payload = b'A' * offset + canary + bytes([byte])
        p.send(payload)
        response = p.recv(timeout=1)
        if b"stack smashing" not in response:
            canary += bytes([byte])
            break
        p.close()

Protection: RELRO (Relocation Read-Only)

What: Controls writability of GOT.

LevelGOT Writable?Exploit Impact
No RELROYesGOT overwrite easy
Partial RELROYes (GOT still writable)GOT overwrite works
Full RELRONo (GOT is read-only)Cannot overwrite GOT — target .fini_array, __malloc_hook, __free_hook, etc.

Bypass Full RELRO:

  • Overwrite __malloc_hook or __free_hook (older glibc)
  • Overwrite .fini_array
  • Overwrite return address on stack (if you can find it)
  • Overwrite function pointers in data sections

Protection: Fortify Source

What: Compile-time replacement of unsafe functions (strcpy__strcpy_chk) with bounds-checked versions.

Bypass: Hard — these are compile-time checks. Find other vulns.


Protection: CET & Shadow Stack

What: Hardware-assisted (Intel CET). Maintains a shadow copy of return addresses. Any mismatch = crash.

Bypass:

  • JOP (Jump Oriented Programming) instead of ROP
  • Very difficult to bypass when properly implemented

Core Dumps for Debugging

# Enable core dumps
ulimit -c unlimited

# Permanent (add to /etc/security/limits.conf)
* soft core unlimited

# Analyze core dump
gdb /path/to/binary /path/to/core

Summary Cheat Sheet

ProtectionCheckBypass Strategy
NXchecksecROP, ret2libc
ASLRcat /proc/sys/kernel/randomize_va_spaceLeak → calculate base
PIEchecksecLeak binary addr, partial overwrite
CanarychecksecLeak or brute-force
Full RELROchecksecTarget hooks/fini_array instead of GOT

References