Hacktricks-skills binary-exploitation-methodology
A comprehensive methodology for binary exploitation, covering stack overflows, ROP chains, shellcode injection, and bypassing protections like ASLR, PIE, NX, and canaries. Use this skill whenever the user mentions binary exploitation, CTF challenges, buffer overflows, ROP, shellcode, ELF analysis, or any security research involving binary vulnerabilities. Trigger this skill for any task involving reverse engineering, vulnerability analysis, or exploit development on compiled binaries.
git clone https://github.com/abelrguezr/hacktricks-skills
skills/binary-exploitation/basic-stack-binary-exploitation-methodology/basic-stack-binary-exploitation-methodology/SKILL.MDBinary Exploitation Methodology
A structured approach to analyzing and exploiting binary vulnerabilities, particularly stack-based buffer overflows and related techniques.
When to Use This Skill
Use this methodology when:
- Analyzing a binary for vulnerabilities
- Developing exploits for CTF challenges
- Researching buffer overflow vulnerabilities
- Bypassing security protections (ASLR, PIE, NX, canaries)
- Planning exploitation strategies for compiled binaries
Phase 1: Binary Analysis
1.1 Gather ELF Information
Before attempting exploitation, understand the binary's structure:
# Basic binary info file <binary> readelf -h <binary> # Check for PIE readelf -d <binary> | grep -i type # Check for stack canaries readelf -s <binary> | grep -i __stack_chk # Check for NX (non-executable stack) readelf -l <binary> | grep GNU_STACK # Check for ASLR readelf -d <binary> | grep FLAGS
1.2 Identify Protections
| Protection | Check Method | Impact |
|---|---|---|
| PIE | shows type | Addresses are randomized |
| Canary | in symbols | Stack overflow detection |
| NX | GNU_STACK without E flag | Stack is non-executable |
| ASLR | FLAGS | Memory addresses randomized |
Phase 2: Vulnerability Identification
2.1 Common Vulnerability Types
Stack Overflows
- Overwriting return pointer (EIP/RIP)
- Overwriting EBP/RBP to control ESP/RSP
- May require integer overflow to trigger
Arbitrary Write Vulnerabilities
- Format string bugs (printf family)
- Array indexing issues
- Buffer overflow to Write-What-Where via ROP
2.2 Analysis Tools
Use these tools to identify vulnerabilities:
- GDB with GEF/PEDA for debugging
- pwntools for exploit development
- radare2/ghidra for reverse engineering
- checksec for protection analysis
Phase 3: Exploitation Goals
Goal 1: Call an Existing Function (ret2win)
Scenario: A
win() function exists that grants access
Without PIE and Canary:
[buffer][padding][return_address -> win_function]
With PIE: Need to leak an address first to calculate base
With Canary: Need to leak or bypass the canary value
Setting Function Parameters:
- Use ROP chain if enough gadgets exist
- Use SROP (sigreturn-oriented programming) to control registers
- Use ret2csu/ret2vdso gadgets for register control
Goal 2: Remote Code Execution (RCE)
Via Shellcode
Prerequisites: NX disabled or bypassed
Without ASLR and NX:
[shellcode][padding][return_address -> shellcode_location]
With ASLR: Use ret2esp/ret2reg to jump to stack
With NX: Use ROP to call
mprotect() and make memory executable
Via Syscalls (ret2syscall)
Use case: Call
execve() to run arbitrary commands
Requirements:
- Find gadgets to set syscall parameters
- Bypass ASLR/PIE to use ROP gadgets
- Consider SROP for ret2execve
Via libc (ret2libc)
Use case: Call
system("/bin/sh") from libc
Scenarios:
| ASLR | PIE | Binary uses system() | Approach |
|---|---|---|---|
| No | No | Any | Static addresses work |
| Yes | No | Yes | Leak GOT entry, calculate libc base |
| Yes | No | No | Use ret2dlresolve or leak addresses |
| Yes | Yes | Any | Leak 2 addresses, calculate libc base |
ret2libc payload structure:
[padding][return_to_system][fake_return][pointer_to_/bin/sh]
Goal 3: Stack Pivoting
Use case: Off-by-one overflows or alternate EIP control
Technique: Control ESP/RSP through EBP/RBP chain
Phase 4: Eternal Loops
When a single exploitation attempt isn't enough, create loops:
4.1 ROP Chain to Main
Write the address of
main() or the vulnerable function in the ROP chain to re-execute the vulnerability.
4.2 GOT Entry Modification
Overwrite
exit GOT entry to point back to the vulnerable function.
4.3 .fini_array Abuse
Store two functions in
.fini_array:
- Function to call the vulnerability again
- Function to call
(which re-executes__libc_csu_fini
).fini_array
Phase 5: Protection Bypasses
5.1 Bypassing ASLR
Methods:
- Leak a libc/binary address and calculate base
- Use information disclosure vulnerabilities
- Brute force (only for 32-bit or small address space)
5.2 Bypassing PIE
Methods:
- Leak any function address to calculate base
- Use GOT entries (not affected by PIE)
5.3 Bypassing NX
Methods:
- ROP chain to
to make memory executablemprotect() - Use existing executable memory (code reuse)
- Find gadgets that don't require shellcode
5.4 Bypassing Canary
Methods:
- Leak canary via format string or info disclosure
- Overwrite canary before it's checked
- Use vulnerabilities that don't trigger canary check
Phase 6: Exploit Development Workflow
Step 1: Fuzz and Identify
from pwn import * # Find offset to return address offset = cyclic_find(pwn.cyclic(1000)) # Test for vulnerabilities process = process('./binary') process.sendline(cyclic(1000)) process.wait()
Step 2: Leak Addresses (if needed)
# Leak libc address via GOT libc_addr = u64(process.read(8).ljust(8, b'\x00')) libc_base = libc_addr - libc.symbols['function_name']
Step 3: Build Payload
payload = flat([ cyclic(offset), # Fill to return address libc.symbols['system'], # Call system 0, # Fake return next(libc.search(b'/bin/sh')) # /bin/sh address ])
Step 4: Test and Refine
- Test locally first
- Handle timing issues
- Account for different environments
Common Pitfalls
- Endianness: Remember x86 is little-endian
- Bad characters: Avoid null bytes, newlines in shellcode
- Alignment: Some gadgets require stack alignment
- Timing: Race conditions in multi-process scenarios
- Environment differences: Test on target architecture
Quick Reference
ROP Chain Structure
[padding][ret][ret][ret][...][final_ret]
ret2libc Structure
[padding][system_addr][fake_ret][/bin/sh_addr]
Shellcode Structure
[nop_sled][shellcode][padding][return_to_shellcode]
Next Steps
After identifying the vulnerability type and protections:
- Choose the appropriate exploitation goal
- Select the technique based on protection status
- Develop and test the exploit
- Refine for reliability
Remember: Each binary is unique. Adapt this methodology to the specific protections and constraints you encounter.