Binary Analysis
Initial Reconnaissance
File Identification
file target # File type, architecture
checksec target # Security mitigations
readelf -h target # ELF header details
readelf -S target # Sections
readelf -l target # Program headers (segments)
Security Mitigations Explained
| Check |
Meaning |
Exploit Impact |
| NX enabled |
Stack not executable |
Need ROP/ret2libc |
| Canary found |
Stack cookie present |
Need leak or bypass |
| PIE enabled |
Code at random address |
Need code leak |
| Full RELRO |
GOT read-only |
Can't overwrite GOT |
| Partial RELRO |
GOT writable |
GOT overwrite possible |
Static Analysis
Disassembly
# Intel syntax disassembly
objdump -M intel -d target > target.asm
# With source (if debug symbols)
objdump -M intel -d -S target
# Specific section
objdump -M intel -d -j .text target
String Analysis
strings target # ASCII strings
strings -a target # All sections
strings -t x target # With offsets
strings -e l target # 16-bit LE strings
Symbol Information
nm target # Symbol table
nm -D target # Dynamic symbols
readelf --syms target # Detailed symbols
Import/Export Analysis
readelf -r target # Relocations (imports)
readelf --dyn-syms target # Dynamic symbols
objdump -T target # Dynamic symbol table
Dynamic Analysis
GDB/pwndbg Commands
# Breakpoints
b *main # Break at main
b *0x401234 # Break at address
# Execution
r # Run
r < input.txt # Run with input
c # Continue
si # Step instruction
ni # Next instruction (skip calls)
# Memory examination
x/20gx $rsp # 20 qwords at RSP
x/s 0x401234 # String at address
telescope $rsp 20 # Smart stack view
# Info
info registers # All registers
info proc mappings # Memory map
vmmap # pwndbg memory map
checksec # Security features
# Search
search -s "/bin/sh" # Find string
search -p 0x401234 # Find pointer
Tracing
# System calls
strace ./target
strace -f ./target # Follow forks
strace -e open,read,write ./target
# Library calls
ltrace ./target
ltrace -e malloc+free ./target
Address Calculation
With PIE Disabled
elf = ELF('./target')
main = elf.symbols['main'] # Direct address
puts_plt = elf.plt['puts'] # PLT entry
puts_got = elf.got['puts'] # GOT entry
With PIE Enabled
# Need to leak code address first
leaked_main = u64(leak.ljust(8, b'\x00'))
elf.address = leaked_main - elf.symbols['main']
# Now all addresses are correct
Libc Calculation
libc = ELF('./libc.so.6')
# After leaking puts address
libc.address = leaked_puts - libc.symbols['puts']
system = libc.symbols['system']
binsh = next(libc.search(b'/bin/sh'))
Common Patterns in Disassembly
Function Prologue
push rbp
mov rbp, rsp
sub rsp, 0x40 ; Local variables
Canary Check
mov rax, [fs:0x28] ; Load canary
mov [rbp-0x8], rax ; Save on stack
...
mov rax, [rbp-0x8] ; Retrieve
xor rax, [fs:0x28] ; Compare
je .ok
call __stack_chk_fail ; Mismatch
Vulnerable strcpy
lea rdi, [rbp-0x40] ; Buffer (64 bytes)
mov rsi, [user_input] ; No size limit!
call strcpy