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.
Scanned 5/31/2026
Install via CLI
openskills install majiayu000/claude-skill-registry---
name: boofuzz
description: 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.
---
# 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
No comments yet. Be the first to comment!