Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Smuggler 🔍 A T-Reqs Grammar-based HTTP/1.x request-smuggling fuzzer for Nim
Based on bahruzjabiyev/t-reqs (CCS 2021 T-Reqs paper)

nimble install smuggler

API reference
Github Actions Github Actions

😍 Key Features

  • Grammar-based request generation: define a context-free grammar for HTTP requests (request line, headers, CL/TE framing, whitespace/case variants) and generate valid + adversarial requests from a reproducible seed.
  • Mutation engine (paper §4.3/§4.4):
    • String mutations: byte-level (bit flips, insert/delete/replace, cross-over splice) seeded per iteration.
    • Tree mutations: grammar-aware symbol insert / replace / delete on the generated parse tree (e.g. repeated method, missing protocol version) — the structural mutations that find non-CL/TE vectors.
  • Request-smuggling detection:
    • In-process CL/TE oracle: parses a request strictly by Content-Length and strictly by Transfer-Encoding and reports disagreement (a desync candidate), no network needed.
    • Response-pairing (two-request technique): drives a live target with the attack followed by a tagged probe and detects swallowed probes / ghost responses.
  • Raw-socket keep-alive delivery: speaks plain HTTP/1.0/1.1 over TCP, so it works against any target (powpow, nginx, a proxy, ...) with no HTTP-client dependency.
  • Standalone CLI: smuggler -g grammar.cfg -t host:port -n N -s seed.
  • Self-contained: portable core requires only the Nim standard library (no clang/libFuzzer); works on Linux, macOS and Windows.

What is it for?

Smuggler hunts for HTTP request smuggling (CL.TE / TE.CL). When a front-end and a back-end server disagree about where a request body ends, an attacker can "smuggle" a request past the front-end. The tool finds requests that make the two interpretations diverge and validates them against a live target.

Inspired by bahruzjabiyev/t-reqs (CCS 2021, paper): this is a self-contained Nim implementation.

Usage

CLI

# in-process CL/TE oracle: flag desync candidates, no network
smuggler -g configs/request-line.cfg -n 10000 -p

# fuzz a live HTTP server (two-request response-pairing)
smuggler -g configs/headers.cfg -t 127.0.0.1:9000 -n 1000 -s 0

# apply 2 tree mutations + 1 string mutation per request
smuggler -g configs/body.cfg -t 127.0.0.1:9000 -n 1000 -T 2 -m 1

# help
smuggler -h

Bundled grammars (per-request-component, mirroring the paper's experiments): configs/request-line.cfg, configs/headers.cfg (all 67 standard headers), configs/body.cfg (chunked, LF-terminated chunk extensions, HTTP/1.0+chunked).

Options: -g/--grammar, -t/--target host:port, -n/--count, -s/--seed, -m/--mutations (string), -T/--tree (tree mutations), -p/--probe (oracle only), -v/--verbose.

As a library

import smuggler

# load a grammar, generate a request, mutate it
let g = parseGrammarFile("configs/request-line.cfg")
let req = generate(g, seed = 42)          # raw HTTP request bytes
var mutated = toBytes(req)
mutateRequest(mutated, seed = 42, mutations = 3)
let raw = toString(mutated)

# in-process desync oracle (no network)
if isDesyncCandidate(raw):
  echo "CL/TE disagreement: ", raw.escape()

# live two-request test
let c = open("127.0.0.1", 9000)
let r = pairTest(c, raw, tag = "abc123")
echo classify(r)                          # detNormal / detProbeSwallowed / detGhostResponse
c.close()

Grammar format

Rules use = or the paper's ::= separator; terminal strings may be double-quoted (e.g. "HTTP/1.1", " /_URI_ ", "Content-Length: <cl>\r\n"), and a rule may span multiple lines (indented continuation, or a line following one that ends with |). A production is a sequence of symbols: <name> expands to another rule, _TOKEN_ is an injected value slot, everything else is a literal (\r / \n escapes supported). | separates alternatives, "" is the empty production. The first rule is the start rule.

<start> = <request>

<request> = <request-line><headers><body>
<request-line> = <method> <ws> <uri> <ws> HTTP/1.1 <crlf>
<method> = GET | POST | PUT | DELETE | HEAD
<ws> = _WS_
<uri> = /_PATH_
<crlf> = \r\n

<headers> = Host: <host> <crlf> <framing-headers><crlf>
<host> = _HOST_
<framing-headers> = "" | <cl-header> | <te-header> | <cl-header><te-header> | <te-header><cl-header>
<cl-header> = Content-Length: <cl> <crlf>
<te-header> = Transfer-Encoding: <te> <crlf>
<cl> = _CL_
<te> = _TE_

<body> = "" | <value>
<value> = _VALUE_

Token slots are injected from built-in pools tuned for smuggling / parser edge cases (content-lengths including 9223372036854775808, chunk sizes, whitespace and case variants, odd hosts/paths, ...). Ship a grammar like the one above and run smuggler against your server or proxy.

Modules

Module Purpose
smuggler/grammar CFG grammar model + file parser (=/::=, quotes, continuations)
smuggler/generate seed-driven generation, parse trees, render, tree mutations
smuggler/mutate string mutation + cross-over splice
smuggler/send non-blocking keep-alive socket delivery + response reader
smuggler/detect CL/TE oracle + response-pairing desync detection

Roadmap

  • Grammar-format compatibility with the T-Reqs paper (::=, quoted terminals, multi-line rules)
  • Tree-level (grammar-aware) mutation of parsed requests
  • Per-component grammars (request line / headers / body) incl. the paper's LF-chunk and HTTP/1.0+chunked vectors
  • Coverage-guided adapters: nim-drchaos / libFuzzer targets for structured fuzzing of HTTP parsers
  • Differential fuzzing against multiple targets (feedback-provider mode)

❤ Contributions & Support

OpenCode Switch to Open-Source LLMs via OpenCode GO, choosing from a variety of powerful models such as DeepSeek, Qwen, Kimi, GLM-5, MiniMax, MiMo. 🍕 Use our referral link to get started!

🎩 License

MIT license. Made by Humans from OpenPeeps.
Copyright OpenPeeps & Contributors — All rights reserved.

About

Smuggler – A T-Reqs Grammar-based HTTP/1.x request-smuggling fuzzer for Nim

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

Generated from openpeeps/pistachio