A Rust-based TCP/HTTP fuzzing and load-testing suite.
It consists of two main components:
mamrot: The client-side fuzzer that sends randomized HTTP requests to a target.mamrotd: A server-side daemon that accepts connections and sends randomized/fuzzed HTTP responses.
The client connects to a target server and sends semi-randomized HTTP requests to stress-test or fuzz the target.
cargo run --bin mamrot --release -- --target <HOST> --port <PORT> [OPTIONS]-t, --target <TARGET>: Target host.-p, --port <PORT>: Target port (default: 80).--headers <HEADERS>: Path to headers file (default: request_headers.txt).--wordlist <WORDLIST>: Path to wordlist file (default: wordlist.txt).--timeout <TIMEOUT>: Request timeout in milliseconds (default: 120).-c, --concurrency <CONCURRENCY>: Max concurrent connections (default: 600).--seed-log <FILE>: Path to the binary seed log file (default: seeds.bin).--seed-buffer-size <SIZE>: Number of seeds to keep in the ring buffer (default: 1,000,000).--replay <SEED>: Replay a specific batch using the provided 64-bit seed (prints to stdout).--replay-file <FILE>: Replay/Loop all seeds from a binary log file against the target.
The server daemon listens for incoming TCP connections. Upon receiving any data, it responds with a randomized HTTP response (including random status codes, versions, and fuzzed headers) before closing the connection. This is useful for testing HTTP clients' resilience to malformed or unexpected server responses.
cargo run --bin mamrotd --release -- --port <PORT> [OPTIONS]-p, --port <PORT>: Port to listen on (default: 80).-b, --bind <BIND>: Address to bind to (default:::for dual-stack IPv4/IPv6).--headers <HEADERS>: Path to headers file (default: response_headers.txt).--wordlist <WORDLIST>: Path to wordlist file (default: wordlist.txt).--seed-log <FILE>: Path to the binary seed log file (default: seeds.bin).--seed-buffer-size <SIZE>: Number of seeds to keep in the ring buffer (default: 1,000,000).--replay-file <FILE>: Load seeds from a file to generate deterministic "random" responses in a loop.--timeout <TIMEOUT>: Delay (sleep) before closing the connection in milliseconds (default: 10).
| Component | Role | Function | Key Use Case |
|---|---|---|---|
mamrot |
Client | Generates fuzzed Requests | Fuzzing web servers, load balancers, proxies. |
mamrotd |
Server | Generates fuzzed Responses | Fuzzing HTTP clients, scrapers, crawlers. |
Both components share the same core fuzzing logic (Cube struct) to generate randomized headers and values, ensuring consistent fuzzing patterns whether acting as a client or a server.
Both mamrot and mamrotd log the random seed used for every interaction to a binary ring buffer file (default seeds.bin). This allows you to replay the exact same sequence of traffic if you detect a crash or anomaly.
The seed log is a raw binary file containing 64-bit unsigned integers (u64). To read it, use the od command:
od -t u8 -A n -w8 -v seeds.binThis will output one decimal seed per line.
To check how many valid seeds are stored and calculate the ring buffer usage:
# Calculate usage
export FILE=seeds.bin
USED=$(od -t u8 -A n -w8 -v $FILE | grep -v "^\s*0$" | wc -l)
TOTAL=$(( $(stat -c %s $FILE) / 8 ))
echo "Usage: $USED / $TOTAL seeds ($((USED * 100 / TOTAL))%)"Once you have identified a seed (e.g., 67908340935210883), you can replay that specific batch:
cargo run --bin mamrot --release -- --target <HOST> --replay 67908340935210883This will output the raw HTTP requests generated by that seed to stdout without sending them to the target.
To "loop" the fuzzing session using previously generated seeds:
cargo run --bin mamrot --release -- --target <HOST> --replay-file seeds.binYou can also make the server deterministic by loading a seed file. The server will cycle through the seeds in the file for each incoming connection, generating the exact same sequence of "random" responses as recorded previously.
cargo run --bin mamrotd --release -- --port 80 --replay-file seeds.binIf you need to isolate a specific seed that causes a crash from a large seeds.bin file, you can split the file into smaller chunks.
Important: The file format relies on 8-byte alignment. You must split the file in multiples of 8 bytes.
Using split with power-of-2 sizes (like 1M, 32M) ensures alignment:
# Split into 64MB chunks
split -b 64M seeds.bin chunk_
# Replay the first chunk
cargo run --bin mamrot --release -- --target <HOST> --replay-file chunk_aaIf chunk_aa causes the crash, split it further:
split -b 32M chunk_aa subchunk_Repeat until you isolate the small set of seeds causing the issue.