Get the FREE Ultimate OpenClaw Setup Guide →

PWN Dynamic Analysis

npx machina-cli add skill allsmog/pwn-claude-plugin/dynamic-analysis --openclaw
Files (1)
SKILL.md
7.4 KB

PWN Dynamic Analysis

Overview

Dynamic analysis involves running the binary under a debugger to observe behavior, calculate offsets, identify crash points, and understand memory layouts at runtime. This phase uses GDB with pwndbg for efficient exploitation research.

Dynamic Analysis Goals

  1. Verify static analysis findings
  2. Calculate exact offsets using cyclic patterns
  3. Identify register control at crash
  4. Find ASLR/PIE base addresses
  5. Detect bad characters that break payloads
  6. Observe stack and heap layouts
  7. Test exploit payloads

Step 1: GDB Setup with pwndbg

Launch GDB

# Basic launch
gdb ./binary

# With arguments
gdb --args ./binary arg1 arg2

# Attach to running process
gdb -p $(pidof binary)

Essential pwndbg Commands

CommandPurpose
checksecShow binary protections
vmmapShow memory mappings
telescopeExamine stack with dereferencing
contextShow registers, stack, code
cyclic 200Generate cyclic pattern
cyclic -l 0x61616168Find offset from pattern
search -s "/bin/sh"Find string in memory
ropFind ROP gadgets
gotShow GOT entries
pltShow PLT entries

Step 2: Calculate Offset with Cyclic Pattern

Generate Pattern

Using pwntools:

from pwn import *
# Generate 200-byte cyclic pattern
print(cyclic(200))

Or in pwndbg:

pwndbg> cyclic 200

Find Offset from Crash

Run binary with pattern input, then check crash location:

pwndbg> run < <(cyclic 200)
# After crash, check RSP or fault address
pwndbg> cyclic -l $rsp
# Or for specific value
pwndbg> cyclic -l 0x6161616c

Pwntools Method

from pwn import *

io = process('./binary')
io.sendline(cyclic(200))
io.wait()

# Check core dump or use gdb.attach()
# core = Coredump('./core')
# offset = cyclic_find(core.rsp)

Step 3: Breakpoint Strategy

Common Breakpoints

# Function entry
b main
b vuln

# Specific address
b *0x401234

# Before dangerous function
b *gets@plt

# Before return
b *vuln+0x45  # Address of 'ret' instruction

# Conditional breakpoints
b *0x401234 if $rax == 0

Breakpoint on Library Functions

# Break on system() calls
b system
b execve

# Break on printf (format string analysis)
b printf
commands
    x/s $rdi    # Print format string (x64)
    continue
end

Step 4: Examine Memory

Stack Examination

# Telescope view (pwndbg)
telescope $rsp 20

# Raw examine
x/20gx $rsp     # 20 quadwords from RSP
x/40wx $esp     # 40 words from ESP (32-bit)

# Examine as string
x/s $rdi

# Examine buffer
x/64bx $rbp-0x40

Find Addresses

# Binary base (if PIE)
vmmap
# Look for binary mapping, base is start address

# Libc base
vmmap libc
# Or
info proc mappings

# Stack canary location
canary    # pwndbg command

Step 5: Bad Character Detection

Bad characters are bytes that break or mangle your payload during transmission or processing. Common bad chars include:

  • \x00 (null) - Terminates strings in C
  • \x0a (newline) - Terminates input in many protocols
  • \x0d (carriage return) - HTTP field terminator

Generate All Characters

# Generate all possible bytes (excluding null)
badchars = bytes(range(1, 256))
print(badchars.hex())

Test Bad Characters

from pwn import *

# All bytes except null
all_chars = bytes(range(1, 256))

io = process('./binary')
payload = b'A' * offset + all_chars
io.sendline(payload)

Identify Bad Characters in GDB

After crash, examine memory where payload landed:

# Find where chars start in memory
x/256bx $rsp

# Compare against expected sequence
# Look for truncation or mangled bytes

Common Bad Characters by Context

Protocol/ContextCommon Bad Chars
HTTP\x00, \x0a, \x0d, \x25, \x26, \x3d
Sockets\x00, \x0a, \x0d
strcpy/gets\x00
File paths\x00, \x2f

Pwntools Bad Char Helper

def find_bad_chars(io, send_func, recv_func, offset):
    """Test for bad characters by sending all bytes"""
    all_chars = bytes(range(1, 256))
    send_func(io, b'A' * offset + all_chars)
    received = recv_func(io)
    # Compare and identify missing/changed bytes

Step 6: Test Exploits

Pwntools GDB Integration

from pwn import *

context.binary = './binary'
context.terminal = ['tmux', 'splitw', '-h']

def conn():
    if args.GDB:
        return gdb.debug('./binary', '''
            b main
            b *vuln+0x45
            c
        ''')
    else:
        return process('./binary')

io = conn()
# Exploit code...

Manual GDB Testing

# Set up input file
pwndbg> shell echo -n 'AAAAAAAA...' > /tmp/payload

# Run with payload
pwndbg> run < /tmp/payload

# Or use Python
pwndbg> run < <(python3 -c "print('A'*72 + '\x34\x12\x40\x00\x00\x00\x00\x00')")

Step 7: ASLR and PIE Analysis

Disable ASLR for Testing

# System-wide (requires root)
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space

# Per-process in GDB
set disable-randomization on

Leak PIE Base

With format string:

# Leak return address from stack
payload = b'%p ' * 20
io.sendline(payload)
leak = io.recvline()
# Parse to find code address, subtract known offset

Leak Libc Base

# Leak GOT entry (contains libc address)
puts_got = elf.got['puts']
# Use arbitrary read to leak puts@got
# libc_base = leaked_puts - libc.symbols['puts']

GDB Scripts for pwndbg

Project .gdbinit Template

# Disable ASLR
set disable-randomization on

# Load binary
file ./binary

# Common breakpoints
b main
b vuln

# Define useful commands
define hook-stop
    context
end

# Print useful info on run
define pwn-info
    checksec
    got
    vmmap
end

Output Format

## Dynamic Analysis

### Findings
- Offset to RIP: 72 bytes (confirmed via cyclic)
- RSP control: Full (can place ROP chain)
- Stack canary: Not present
- ASLR: Enabled (need leak for libc)
- PIE: Disabled (binary at 0x400000)

### Debug Session

pwndbg> cyclic -l $rsp Finding cyclic pattern of 8 bytes: b'haaaaaaa' (hex: 0x6161616161616168) Found at offset 72


### Implications
- 72-byte padding confirmed
- Direct ROP to fixed addresses possible
- For ret2libc: need to leak libc address first

### Next Steps
1. Find ROP gadgets for ret2libc
2. Construct leak payload (puts GOT)
3. Calculate libc base from leak
4. Build system("/bin/sh") payload

Quick Reference

# Pwntools offset finder
from pwn import *
io = process('./binary')
io.sendline(cyclic(200))
io.wait()
# Check crash, find offset with cyclic_find()
# Quick crash analysis
r < <(cyclic 200)
cyclic -l $rsp

Additional Resources

References

  • references/pwndbg-commands.md - Complete pwndbg command reference
  • references/gdb-scripting.md - Advanced GDB scripting for exploitation

Scripts

  • scripts/gdb-template.gdb - Project .gdbinit template

Source

git clone https://github.com/allsmog/pwn-claude-plugin/blob/main/pwn-htb/skills/dynamic-analysis/SKILL.mdView on GitHub

Overview

Dynamic analysis involves running the binary under a debugger to observe behavior, calculate offsets, identify crash points, and understand memory layouts at runtime. This skill uses GDB with pwndbg to guide exploitation research and bad-character detection.

How This Skill Works

It provides a repeatable workflow: launch GDB with pwndbg, inspect memory with pwndbg commands like vmmap, telescope, and context, and use cyclic patterns to locate offsets. It also covers attaching to running processes and performing crash analysis to determine faulting locations and base addresses.

When to Use It

  • Debug a binary with GDB/pwndbg and attach to a running process
  • Calculate exact offsets using cyclic patterns to determine payload length
  • Identify crash points by inspecting registers and stack during execution
  • Detect and test bad characters that can corrupt payloads
  • Observe memory layouts, ASLR/PIE bases, and protections during runtime

Quick Start

  1. Step 1: Launch GDB with pwndbg against the target binary (gdb ./binary, or gdb --args ./binary args, or gdb -p $(pidof binary))
  2. Step 2: Generate a cyclic pattern to determine the offset (pwntools or pwndbg cyclic) and crash the binary to locate the offset from $rsp
  3. Step 3: Test for bad characters by sending a payload containing all bytes 1-255 and observe any termination or corruption

Best Practices

  • Start with static findings and verify them dynamically under GDB
  • Use pwndbg commands like checksec, vmmap, telescope, and context for insight
  • Generate and verify cyclic patterns to locate offsets and test with pwntools
  • Strategically place breakpoints (entry points, dangerous calls) and inspect on hit
  • Iterate payload testing, including bad-character testing, to ensure robustness

Example Use Cases

  • Debug a vulnerable binary to determine the exact offset for a buffer overflow
  • Attach to a running process and analyze a live crash to identify the faulting address
  • Detect bad characters by sending a full range of bytes and observing where transmission fails
  • Find ASLR/PIE base addresses using vmmap and proc mappings for reliable exploitation
  • Validate exploit payloads by stepwise dynamic analysis with pwndbg and GDB

Frequently Asked Questions

Add this skill to your agents
Sponsor this space

Reach thousands of developers