Pular para o conteúdo

Ropper

Overview

Ropper is a comprehensive binary analysis framework for finding Return-Oriented Programming (ROP), Jump-Oriented Programming (JOP), and Syscall-Oriented Programming (SOP) gadgets in compiled binaries. It facilitates exploit development, binary patching, and security research by identifying reusable code sequences that can be chained together to bypass protections like ASLR and DEP (Data Execution Prevention).

Installation

# Install via pip
pip install ropper

# Install with all dependencies
pip install ropper[all]

# From source (GitHub)
git clone https://github.com/sashs/Ropper
cd Ropper
python setup.py install

# Verify installation
ropper --version
which ropper

# Check dependencies
ropper --check-deps

Core Concepts

ROP (Return-Oriented Programming):

  • Chains sequences ending with ret instructions
  • Overwrites return addresses to execute gadget sequences
  • Bypasses code execution restrictions

JOP (Jump-Oriented Programming):

  • Uses jmp instructions instead of ret
  • More flexible than ROP in some architectures
  • Harder to detect in some systems

SOP (Syscall-Oriented Programming):

  • Chains syscall instructions
  • Direct system call execution without libc
  • Powerful for privilege escalation

Basic Usage

CommandPurpose
ropper -f binaryLoad binary and analyze
ropper --file binarySame as above
ropper -f binary -iInteractive mode
ropper -f binary --listList all gadgets found
ropper --helpDisplay help information
ropper --versionShow version

Loading and Inspecting Binaries

# Load single binary
ropper -f /bin/bash

# Specify architecture explicitly
ropper -f binary --arch=x86_64

# Load with options
ropper -f binary -r --inst-count 3

# Load and jump to interactive mode
ropper -f binary -i

Gadget Finding

CommandPurpose
ropper -f binary --search "pop rdi"Find specific gadget
ropper -f binary -s "mov rax"Short form search
ropper -f binary --inst-count 2Limit gadget size (2 instructions)
ropper -f binary --inst-count 3Slightly larger gadgets
ropper -f binary --inst-count 1Single-instruction gadgets

Practical Gadget Searches

# Pop rdi; ret (common x64 argument setting)
ropper -f binary -s "pop rdi; ret"

# Pop rsi; ret
ropper -f binary -s "pop rsi; ret"

# Set rax to syscall number (execve = 59 on x64)
ropper -f binary -s "mov rax, 0x3b"

# Syscall gadgets
ropper -f binary -s "syscall"

# xor rax, rax (clear register)
ropper -f binary -s "xor rax, rax"

# Write to memory
ropper -f binary -s "mov [rdi], rax"

Advanced Search Patterns

# Regex search
ropper -f binary -s "pop r.* ret" --filter="x64"

# Search with constraints
ropper -f binary -s "pop rdi" --quality high

# Search across sections
ropper -f binary -s "pop rsi" --all

# Search in specific section
ropper -f binary -s "pop rax" -o .text

Gadget Chain Building

# Find gadgets for specific register manipulation
ropper -f binary --search "pop rdi; ret" --chain "exec"
ropper -f binary --search "pop rsi; ret"
ropper -f binary --search "pop rdx; ret"

# Build complete ROP chain
ropper -f binary --chain "exec" /bin/sh

Interactive Mode

# Start interactive shell
ropper -f binary -i

# Available in interactive mode:
# search <pattern> - Search gadgets
# list - Display all gadgets
# file <binary> - Load different binary
# help - Show commands
# quit - Exit

Interactive Mode Commands

CommandPurpose
search pop rdiFind “pop rdi” gadgets
listShow loaded gadgets
file /path/to/binaryLoad binary
hexDisplay hex dump
asmAssemble instructions
disasmDisassemble bytes
semanticSemantic gadget search
opcodeFind by opcode
# Find gadgets that perform specific operations
ropper -f binary --semantic "rax=0"  # Zero out rax
ropper -f binary --semantic "rdi=rsi" # Copy rsi to rdi
ropper -f binary --semantic "rax=rdi" # Copy rdi to rax

# Complex semantics
ropper -f binary --semantic "rax=rdi+rsi"
ropper -f binary --semantic "rdi=[rsi]"

ROP Chain Generation

# Generate exec chain
ropper -f binary --chain "exec" /bin/sh

# Generate write chain
ropper -f binary --chain "write" <address> <data>

# Mprotect chain (mark memory executable)
ropper -f binary --chain "mprotect"

# Read chain
ropper -f binary --chain "read"

Binary Information

CommandPurpose
ropper -f binary --infoDisplay binary information
ropper -f binary --checksecCheck security features
ropper -f binary --sectionsList sections
ropper -f binary --importsShow imported functions
ropper -f binary --symbolsDisplay symbols

Security Checks

# Check exploit mitigations
ropper -f binary --checksec

# Look for ASLR indicators
ropper -f binary --info | grep -i aslr

# Identify position-independent code
ropper -f binary --info | grep -i pie

# Check for stack canary
ropper -f binary --info | grep -i canary

Output and Export

CommandPurpose
ropper -f binary --list --export jsonExport to JSON
ropper -f binary --list --export pythonExport Python code
ropper -f binary --list --export rawRaw gadget output
ropper -f binary --list > gadgets.txtSave to file

JSON Export Example

ropper -f binary --list --export json > gadgets.json

# Parse JSON with jq
cat gadgets.json | jq '.gadgets[] | select(.asm | contains("pop rdi"))'

Filtering Results

# Filter by architecture
ropper -f binary --arch=x86_64 -s "pop rdi"

# Filter by instruction count
ropper -f binary -s "pop" --inst-count 1

# Quality filtering
ropper -f binary -s "pop rdi" --quality medium

# Address range filtering
ropper -f binary -s "pop rdi" --range="0x400000-0x410000"

Exploit Development Workflow

Step 1: Identify Function Prologue/Epilogue

# Find function prologues
ropper -f binary -s "push rbp; mov rbp, rsp"

# Find returns
ropper -f binary -s "ret"

Step 2: Find Argument-Setting Gadgets

# First argument (rdi in x64)
ropper -f binary -s "pop rdi; ret"

# Second argument (rsi in x64)
ropper -f binary -s "pop rsi; ret"

# Third argument (rdx in x64)
ropper -f binary -s "pop rdx; ret"

Step 3: Locate System Calls

# Find syscall instruction
ropper -f binary -s "syscall"

# Alternative: int 0x80 for 32-bit
ropper -f binary -s "int 0x80"

Step 4: Build Chain

# Example: execve("/bin/sh", NULL, NULL)
ropper -f binary --chain "exec" /bin/sh

Multi-Binary Analysis

# Load multiple binaries
ropper -f binary1 -f binary2 -s "pop rdi"

# Compare gadgets across binaries
ropper -f binary1 -s "pop rdi" > gadgets1.txt
ropper -f binary2 -s "pop rdi" > gadgets2.txt
diff gadgets1.txt gadgets2.txt

Advanced Techniques

Searching by Opcode

# Find byte patterns
ropper -f binary --opcode "5f c3"  # pop rdi; ret

# Partial opcode search
ropper -f binary --opcode "5f"     # pop rdi

Branch Gadgets

# Conditional jumps
ropper -f binary -s "je"
ropper -f binary -s "jne"
ropper -f binary -s "jz"
ropper -f binary -s "jmp"

Load/Store Gadgets

# Memory writes
ropper -f binary -s "mov [rdi], rax"

# Memory reads
ropper -f binary -s "mov rax, [rdi]"

# Indirect writes
ropper -f binary -s "mov [rdi], rsi"

Common Gadget Patterns

x86-64 System Call Pattern

# Find the syscall number setup
ropper -f binary -s "mov rax, 0x3b"  # execve syscall

# Stack setup
ropper -f binary -s "mov rsi, 0"
ropper -f binary -s "mov rdx, 0"

# Syscall
ropper -f binary -s "syscall"

x86 (32-bit) Patterns

# Arguments via stack
ropper -f binary -s "push" --arch=x86

# Call instruction
ropper -f binary -s "call" --arch=x86

# System call
ropper -f binary -s "int 0x80" --arch=x86

Performance Optimization

# Cache gadgets (faster subsequent searches)
ropper -f binary --cache

# Clear cache if needed
ropper -f binary --clear-cache

# Limit search to text section
ropper -f binary -s "pop rdi" -o .text

# Quick scan (fewer gadgets found)
ropper -f binary --fast -s "pop"

Exploit Script Generation

# Generate Python ROP builder template
ropper -f binary --chain "exec" /bin/sh --export python

# Manual chain building (example in Python):
# rop = ROP(binary)
# rop.call('execve', ['/bin/sh', NULL, NULL])
# payload = rop.build()

Integration with Other Tools

With GDB

# Find gadget addresses
ropper -f binary -s "pop rdi; ret"

# Set breakpoint in GDB
gdb binary
(gdb) break *0x<gadget_address>
(gdb) run <args>

With Pwntools

#!/usr/bin/env python3
from pwntools import *

binary = ELF('./binary')

# Find gadgets programmatically
rop = ROP(binary)
rop.rdi = 0x400000
rop.call('execve', ['/bin/sh', 0, 0])
payload = rop.build()

With Radare2

# Compare with radare2 analysis
r2 binary
> /r pop rdi  # Search in radare2

# Export from ropper
ropper -f binary -s "pop rdi" > ropper_gadgets.txt

Troubleshooting

# Binary not loading
ropper -f binary --verbose

# Architecture detection issues
ropper -f binary --arch=x86_64  # Specify manually

# Too many results
ropper -f binary -s "pop" --inst-count 1  # Limit size

# Slow scanning
ropper -f binary --fast  # Quick mode

Best Practices

  • Always verify gadget offsets before use (ASLR makes them dynamic)
  • Test ROP chains on target system before deployment
  • Document all gadget chains and their purposes
  • Use semantic analysis for complex chains
  • Combine multiple sources (PLT, imports, linked libraries)
  • Account for gadget variability across system updates
  • Use instruction pointer validation when available
  • Use only on systems you own or have explicit authorization to test
  • ROP chains are commonly used in legitimate security research
  • Document all findings responsibly
  • Follow responsible disclosure practices
  • Maintain operational security during exploit development
  • Pwntools - Python library for PWN/exploitation
  • GDB - Debugger for gadget validation
  • Radare2 - Advanced binary analysis
  • Capstone - Disassembly framework
  • objdump - Binary inspection
  • readelf - ELF file analysis
  • strace - System call tracer