Agent skill

boofuzz

Protocol fuzzer script development using boofuzz framework. Use when creating network protocol fuzzers, defining protocol PDUs (Protocol Data Units), writing mutation-based fuzzing scripts, or contributing to the boofuzz project. Covers binary protocol definitions, session management, crash detection, and reporting findings.

Stars 163
Forks 31

Install this agent skill to your Project

npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/data/Boofuzz-Fuzzer

SKILL.md

boofuzz Protocol Fuzzer Development

Protocol Definition Hierarchy

Session → Request (message) → Block (chunk) → Primitive (element)

Prefer the object-oriented style over static functions for new code:

python
from boofuzz import Request, Block, String, Byte, Static, Group, Size

req = Request("Protocol-Message", children=(
    Block("Header", children=(
        Byte("opcode", default_value=0x01),
        Size("length", block_name="Payload", length=2),
    )),
    Block("Payload", children=(
        String("data", default_value="test"),
    )),
))

Naming Conventions

Element Convention Example
Request Protocol-Action format "iSCSI-Login-Request", "MQTT-CONNECT"
Block Protocol terminology "BHS", "Data-Segment", "Fixed-Header"
Primitive Spec field names "opcode", "data_segment_length", "client_id"

Always provide name= parameter for debugging and logging.

Essential Primitives

python
# Fixed values (not fuzzed)
Static("magic", default_value=b"\x00\x01")

# Fuzzable bytes/strings
Byte("flags", default_value=0x00)
Bytes("payload", default_value=b"\x00" * 16, size=16)
String("username", default_value="admin")

# Length fields (auto-calculated)
Size("length", block_name="body", length=4, endian=BIG_ENDIAN)

# Opcodes/enums
Group("command", values=[b"\x01", b"\x02", b"\x03"])

# Checksums
Checksum("crc", block_name="data", algorithm="crc32")

Binary Protocol Pattern

For protocols with fixed headers (iSCSI, MQTT, etc.):

python
from boofuzz import (
    Request, Block, Byte, Bytes, Size, Static, Group,
    BIG_ENDIAN, LITTLE_ENDIAN
)

def define_pdu():
    return Request("Protocol-PDU", children=(
        Block("fixed_header", children=(
            Byte("type", default_value=0x10),
            # Variable length encoding if needed
        )),
        Block("variable_header", children=(
            Size("length", block_name="payload", length=2, endian=BIG_ENDIAN),
            Bytes("session_id", default_value=b"\x00" * 4, size=4),
        )),
        Block("payload", children=(
            String("data", default_value=""),
        )),
    ))

Session Setup

python
from boofuzz import Session, Target, TCPSocketConnection

session = Session(
    target=Target(
        connection=TCPSocketConnection(host="192.168.1.100", port=3260)
    ),
    web_port=26000,           # Web UI
    keep_web_open=True,
    crash_threshold_element=3, # Failures before restart
)

# Register requests
session.connect(s_get("login"))
session.connect(s_get("login"), s_get("command"))  # login → command

# Run
session.fuzz()

Callbacks for Stateful Protocols

python
def pre_send_callback(target, fuzz_data_logger, session, sock):
    """Execute before each test case - establish session state."""
    # Send valid login, store session token, etc.
    pass

def post_test_case_callback(target, fuzz_data_logger, session, sock):
    """Execute after each test case - check for anomalies."""
    pass

session = Session(
    target=target,
    pre_send_callbacks=[pre_send_callback],
    post_test_case_callbacks=[post_test_case_callback],
)

Code Style (for contributions)

Format with Black before committing:

bash
pip install black
black your_fuzzer.py

Run full checks:

bash
pip install tox
tox

Use # fmt: off / # fmt: on sparingly for protocol byte layouts.

File Organisation

Directory Purpose
/examples/ Complete runnable scripts with CLI
/request_definitions/ Reusable protocol modules (no main())

For standalone fuzzers, target /examples/.

Script Structure

python
#!/usr/bin/env python3
"""
Protocol Name Fuzzer

Brief description of target and approach.
Protocol reference: [RFC/spec URL]
"""

from boofuzz import (...)
import argparse

# Constants from spec
PROTO_PORT = 1234
OPCODE_FOO = 0x01

def define_message_type():
    """Define Protocol Message PDU per RFC section X.Y."""
    # ...

def main():
    parser = argparse.ArgumentParser(description="Protocol Fuzzer")
    parser.add_argument("-t", "--target", required=True, help="Target host")
    parser.add_argument("-p", "--port", type=int, default=PROTO_PORT)
    args = parser.parse_args()
    
    session = Session(...)
    # Register messages
    session.fuzz()

if __name__ == "__main__":
    main()

Monitoring Targets

Build targets with AddressSanitizer for memory bug detection:

bash
# Example for C projects
export CFLAGS="-fsanitize=address -g"
export LDFLAGS="-fsanitize=address"
./configure && make

Monitor during fuzzing:

bash
# ASAN output
grep -E "AddressSanitizer|ERROR|SUMMARY" target.log

# Process crashes
dmesg -w | grep -i segfault

Results Analysis

Results stored in ./boofuzz-results/*.db (SQLite):

bash
# Web UI
boo open boofuzz-results/run-YYYY-MM-DD_HH-MM-SS.db

Query crashes:

python
import sqlite3
conn = sqlite3.connect('boofuzz-results/run-*.db')
cursor = conn.cursor()
cursor.execute("""
    SELECT name, type, timestamp FROM cases 
    WHERE type LIKE '%fail%' OR type LIKE '%crash%'
""")

Reporting Findings

See references/disclosure.md for vulnerability disclosure templates and responsible reporting guidelines.

Quick Reference

Common pitfalls:

  • Missing name= on primitives makes debugging difficult
  • Forgetting endian=BIG_ENDIAN for network protocols
  • Not handling stateful protocols (login before commands)
  • Size fields referencing non-existent block names

Didn't find tool you were looking for?

Be as detailed as possible for better results