Skip to content

styxabhor/Project-Lethe

Repository files navigation

Project Lethe Banner

Project Lethe

Project Lethe is a lightweight, dependency-free CLI for authorized WAF resilience and canonicalization testing. It combines deterministic payload mutation, safe HTTP discrepancy templates, single-request site profiling, and an optional AI planning/reporting layer.

Lethe is built for ethical hackers, bug bounty hunters, AppSec engineers, and students who need small, repeatable, explainable test sets for owned systems, labs, or explicitly authorized programs.

What It Is Not

Project Lethe is not an exploitation framework, scanner, target attacker, or payload pack. Generation commands do not send network traffic. The profile, fingerprint, and test commands do make requests, but only to targets you explicitly authorize through the scope guard (default-deny). Even when testing actively, generated variants always flow through deterministic allowlisted transformations.

Use it only where you have permission.

Features

  • Zero runtime dependencies; pure Python standard library.
  • Deterministic mutation engine with provenance, tags, depth, and chained techniques.
  • Default-deny authorization scope guard (hosts, wildcards, ports, CIDRs) for all active commands.
  • Active testing that injects variants at an authorized target and classifies each response as blocked, passed, rate-limited, challenged, or origin error.
  • Per-target oracle calibration, multi-sample baselines, and automatic bypass re-confirmation for trustworthy verdicts.
  • Reflection-context detection (HTML body/attribute/script/JSON) with a likely_exploitable flag.
  • Heuristic WAF/CDN fingerprinting (Cloudflare, Akamai, AWS, Imperva, Sucuri, ModSecurity, F5, and more) with technique suggestions.
  • n-day knowledge pack mapping WAF bypass classes to profiles/techniques, surfaced during fingerprinting.
  • Profiles for XSS, SQL-style strings, APIs, GraphQL, XML, redirects, headers, SSRF-style URLs, JSON, and generic normalization.
  • Vendor-tuned profiles (cloudflare, akamai, aws_waf, imperva, modsecurity, f5) that fingerprint recommends automatically.
  • Export variants as Nuclei templates or Burp BCheck scripts (--format nuclei|bcheck).
  • http-run executes HTTP/1.1 discrepancy templates over raw sockets against an authorized target.
  • schema ingests OpenAPI/Swagger or GraphQL and recommends type-aware profiles/contexts/tags.
  • proxy is a scope-gated HTTP mutation middleware: mutate live Burp/Intruder traffic in place, with optional HTTPS interception via a local CA.
  • Context-aware technique selection (--context html_body|html_attr|js_string|url|sql|...).
  • Novel charset/normalization transforms: NFKC compatibility homoglyphs, overlong UTF-8, and inconsistent partial encoding.
  • Engine-aware techniques and profiles: MySQL/MSSQL/Postgres SQLi, SSRF IP encodings, path-traversal slashes, and shell separators.
  • Oracle-guided discover engine that evolves and minimizes novel WAF bypasses.
  • Import requests straight from a curl command, raw HTTP, or a HAR file, marked with §INJECT§.
  • Local SQLite session store with lethe history, and integrity-hashed run manifests for evidence.
  • Versioned (schema_version) JSON/NDJSON output and documented exit codes.
  • Advanced novelty mode with bounded stacked mutations and seeded polymorphic padding.
  • AI safety planner returning allow, review, or block.
  • AI report analysis for triage-ready explanations without generating new payloads.
  • Built-in Gemini, OpenAI, Claude, Ollama, LM Studio, LocalAI, and OpenAI-compatible provider support.
  • Single-request site profiling with redacted bearer, cookie, and custom-header auth.
  • Short-lived local auth memory with TTL.
  • HTTP/1.1 discrepancy templates, bounded local-lab stress templates, and HTTP/2 downgrade translation templates.
  • explain and analyze commands for report-ready evidence.
  • Smooth STYX://PROJECT-LETHE terminal signature.
  • JSON, NDJSON, Markdown, raw template, and readable table output.

Install

Project Lethe is pure Python standard library, so it runs anywhere CPython 3.10+ runs — Linux, macOS, Windows, and containers — with no third-party runtime dependencies.

From source (any OS)

git clone https://github.com/styxabhor/Project-Lethe.git
cd Project-Lethe
python -m venv .venv
# Linux/macOS:
source .venv/bin/activate
# Windows (PowerShell):
.\.venv\Scripts\Activate.ps1
pip install -e .

With pipx (isolated, recommended for daily use)

pipx install .
# or, once published:
pipx install project-lethe

With Docker / containers

docker build -t project-lethe .
docker run --rm project-lethe generate -p '<waf-test>' --profile xss --limit 12
# mount a scope file and persist the session store:
docker run --rm -v "$PWD:/work" -w /work project-lethe \
  test https://example.com/s -p '<x>' --scope-file scope.txt --yes

Optional shell completion

pip install -e ".[completion]"
# bash:
eval "$(register-python-argcomplete lethe)"

Confirm:

lethe --version
lethe --help
lethe examples

Notes for Windows

Native Windows works out of the box. If a cloned .venv was created on Linux (it contains bin/ instead of Scripts/), recreate it with py -m venv .venv. The auth cache and session store fall back gracefully when POSIX file permissions are unavailable.

Quick Start

Generate a small XSS-context test set:

lethe generate --payload '<waf-test data-id="123">' --profile xss --limit 12

Markdown output for notes:

lethe generate \
  --payload '<waf-test data-id="123">' \
  --profile xss \
  --limit 12 \
  --format markdown

The banner appears automatically only for interactive table output. Force or disable it explicitly:

lethe generate --payload '<test>' --banner
lethe generate --payload '<test>' --no-banner

Explain And Analyze

Use explain to show exactly how a deterministic transformation changed a payload:

lethe explain --payload '<waf-test>' --technique html_hex_entities

Explain a chain:

lethe explain \
  --payload '<waf-test>' \
  --technique html_hex_entities \
  --technique url_encode_reserved

Use analyze when you need triage-ready wording: normalization hypotheses, evidence notes, validation guidance, remediation, and a character-level diff.

lethe analyze \
  --payload '<waf-test>' \
  --technique html_hex_entities \
  --technique url_encode_reserved \
  --profile xss \
  --format markdown

Analyze a copied/generated variant:

lethe analyze \
  --payload '<waf-test>' \
  --mutated '%3Cwaf-test%3E' \
  --format markdown

Add optional AI narrative while keeping the model constrained to explanation only:

lethe analyze \
  --payload '<waf-test>' \
  --technique html_hex_entities \
  --ai-provider ollama \
  --ai-model qwen3:8b \
  --format markdown

Demo the AI flow without an API key:

lethe analyze \
  --payload '<waf-test>' \
  --technique html_hex_entities \
  --ai-command 'python examples/mock_ai_analysis.py' \
  --format markdown

Advanced Generation

Stack multiple mutation layers:

lethe generate \
  --payload '<waf-test>' \
  --profile xss \
  --stack 3 \
  --limit 75

Stack depth is capped at 4 by default. For local labs, allow bounded deeper stacks up to 6:

lethe generate --payload '<test>' --stack 5 --allow-deep-stack --limit 100

Explore novelty-oriented parser, Unicode, entity, recursive, and canonicalization techniques:

lethe generate --payload '<waf-test>' --explore --format json

Preview the resolved plan:

lethe generate --payload '<waf-test>' --explore --stack 3 --dry-run --format json

Add bounded polymorphic padding variants:

lethe generate \
  --payload '<waf-test>' \
  --profile xss \
  --limit 40 \
  --polymorphic 10 \
  --poly-seed report-001 \
  --format markdown

Active Testing (authorized targets only)

Lethe can close the loop: generate variants, send them at a target you are authorized to test, and classify each response. Every active command is gated by a default-deny scope guard — nothing is sent unless the target matches an explicit scope rule.

Identify the WAF first:

lethe fingerprint https://example.com/ --scope example.com

When a WAF is detected, Lethe suggests a vendor-tuned profile (for example --profile cloudflare) and the relevant knowledge-pack entries. Vendor profiles bundle the canonicalization tricks each vendor tends to be weak to.

Export to automation tools

Move variants straight into your existing automation as Nuclei templates or Burp BCheck scripts:

lethe generate -p '<waf-test>' --profile xss --format nuclei --param q --output lethe.yaml
lethe generate -p '<waf-test>' --profile xss --format bcheck --output lethe.bcheck

These are ready-to-edit starting templates — tune the matchers/target before use.

Plan a test (no traffic is sent without --yes):

lethe test https://example.com/search \
  --payload '<script>alert(1)</script>' \
  --profile xss \
  --scope example.com \
  --limit 25

Confirm authorization and actually send:

lethe test https://example.com/search \
  --payload '<script>alert(1)</script>' \
  --profile xss \
  --scope example.com \
  --rate 5 \
  --concurrency 4 \
  --yes \
  --format json

Each variant is classified as blocked, passed, rate_limited, challenged, origin_error, or inconclusive, with a confidence score and the signals used. A passed verdict means the variant reached the origin — a candidate bypass.

Trustworthy verdicts

For results you can rely on, add calibration, multi-sample baselines, and re-confirmation:

lethe test https://example.com/search -p '<script>' --scope example.com --yes \
  --baseline-samples 3 \
  --calibrate \
  --confirm-bypass
  • --calibrate sends a few benign and known-malicious probes first to learn the target's own block/benign signature, instead of relying on generic markers.
  • --baseline-samples N medians over N benign requests so a flaky origin does not poison verdicts.
  • --confirm-bypass re-sends each apparent bypass; anything that does not reproduce is downgraded to inconclusive.

Exploitability, not just bypass

Lethe reports where a reflected payload landed — html_text, html_attribute, script_block, json_string, and so on — and flags likely_exploitable when the context is plausibly executable. A payload reflected in an HTML body is a real finding; one reflected inside a JSON string usually is not.

Scope rules accept exact hosts, wildcards, ports, and CIDRs, from flags or a file:

# scope.txt
*.example.com
api.example.com:8443
10.0.0.0/8
!admin.example.com   # '!' denies, and deny always wins

lethe test https://shop.example.com/q --payload '<x>' --scope-file scope.txt --yes

A host rule without a port (example.com) matches any port; a rule with a port (api.example.com:8443) matches that port only, where the URL's implicit port is resolved from its scheme (https = 443, http = 80).

Inject into a query parameter (default), a header, or a request body:

lethe test https://example.com/api --payload '<x>' --scope example.com \
  --inject body --content-type application/json --param input --yes

lethe test https://example.com/ --payload '<x>' --scope example.com \
  --inject header --param X-Search --yes

Route through Burp/ZAP, and fail CI when a bypass is found:

lethe test https://example.com/search --payload '<x>' --scope example.com \
  --proxy http://127.0.0.1:8080 --fail-on-bypass --yes

lethe test exits 0 normally, 3 when --fail-on-bypass is set and at least one variant passes, and 2 on a scope or setup error.

Import a request from curl or Burp

Paste a curl command or a raw HTTP request and mark the injection point with §INJECT§. Lethe figures out whether to inject into the query, a header, or the body:

lethe test --payload '<script>alert(1)</script>' --scope example.com --yes \
  --curl "curl 'https://example.com/search?q=§INJECT§' -H 'X-Auth: token'"

lethe test --payload '<x>' --scope example.com --yes --request-file req.txt

If no §INJECT§ marker is present, the --inject/--param selection is used.

Context-aware technique selection

Restrict generation to techniques that make sense where the payload lands:

lethe test https://example.com/search --payload '<x>' --scope example.com \
  --context html_attr --yes

lethe generate --payload '<x>' --context js_string
lethe techniques --context url
lethe contexts

Discover novel bypasses

When a static technique set is fully blocked, let the oracle-guided loop evolve toward a bypass and minimize it to the smallest working chain:

lethe discover https://example.com/search \
  --payload '<script>alert(1)</script>' \
  --profile xss \
  --scope example.com \
  --rounds 3 \
  --stop-on-bypass \
  --yes

Each round sends a population of candidate chains, keeps the survivors (anything not blocked), and evolves the next generation. A passed chain is a candidate bypass of that WAF config; discovered chains are reduced to a minimal primitive. Novel chains (not seen before) are flagged. --fail-on-bypass makes it exit 3.

n-day knowledge feeds

Lethe ships an inert knowledge pack that maps WAF/canonicalization bypass classes to profiles and techniques. It is data, never executed.

lethe feeds                      # browse all entries
lethe feeds --vendor Cloudflare  # entries relevant to a detected WAF
lethe feeds --tag unicode
lethe feeds --search traversal --format json

lethe fingerprint automatically annotates a detected WAF with related entries. Point LETHE_FEEDS at your own curated JSON pack, or refresh from a trusted source you control:

lethe feeds --update https://feeds.example.com/lethe-pack.json

Fetched content is validated as JSON and stored locally; it is never executed.

Sessions and history

Persist runs and findings to a local SQLite store for later review and evidence:

lethe test https://example.com/search --payload '<x>' --scope example.com \
  --yes --save --session hackerone-prod

lethe history                 # list recent runs
lethe history 3 --format json # findings for run #3

The store lives at ~/.cache/project-lethe/sessions.db by default (override with LETHE_STORE).

You can also pin scope in .lethe.toml so you never forget the guard:

[lethe]
scope_allow = ["*.example.com"]
scope_deny = ["admin.example.com"]

Site Profiling

Profile one authorized URL:

lethe profile https://example.com/account --format json --output site-profile.json

Lethe records response context such as content type, security headers, forms, input names, cookie names, technology hints, and recommended profiles/tags.

Optional reflection check with a harmless canary:

lethe profile https://example.com/search --reflect

Use a saved profile during generation:

lethe generate --payload '<waf-test>' --site-profile site-profile.json --limit 12

For authenticated routes, prefer environment variables:

export LETHE_TOKEN='redacted-token-here'
export LETHE_COOKIE='session=redacted'

lethe profile https://example.com/account \
  --bearer-token-env LETHE_TOKEN \
  --cookie-env LETHE_COOKIE \
  --header 'X-Program-Scope: authorized' \
  --format json \
  --output site-profile.json

Auth Memory

Save auth material temporarily for repeated authorized profiling:

lethe auth save hackerone-prod \
  --bearer-token-env LETHE_TOKEN \
  --cookie-env LETHE_COOKIE \
  --ttl 30m

lethe profile https://example.com/account --auth-ref hackerone-prod
lethe auth list
lethe auth clear hackerone-prod

The cache is stored outside the repo at ~/.cache/project-lethe/auth.json by default, written with 0600 permissions when supported, and capped at 2 hours unless --allow-long-ttl is used.

HTTP Templates

Generate safe request-shape templates for WAF/backend parser comparison:

lethe http-plan --host example.com --path /search --param q=safe --format raw

Include HTTP/2-to-HTTP/1.1 downgrade templates:

lethe http-plan \
  --host example.com \
  --path /search \
  --param q=safe \
  --include-http2 \
  --format raw

These templates cover harmless canary checks for :path versus path, :authority versus host, duplicate pseudo-header rejection, lowercase-header enforcement, and TE/content-length downgrade consistency.

Execute the HTTP/1.1 templates against an authorized target (raw sockets, so duplicate headers and HPP go out exactly as crafted; HTTP/2 text templates are skipped):

lethe http-run https://example.com/search --scope example.com --yes

API Schema Ingestion

Feed Lethe an OpenAPI/Swagger or GraphQL introspection file to get type-aware profile, context, and technique recommendations per endpoint and parameter:

lethe schema swagger.json
lethe schema swagger.json --format json

String fields get encoding/Unicode folds, path parameters get path normalization, and so on — so you focus mutations where they matter.

Mutation Proxy

Run a scope-gated HTTP proxy that mutates live traffic in place. Point Burp's upstream proxy at it and every forwarded request has the chosen mutation applied to a parameter (or a §INJECT§ marker):

lethe proxy --listen 127.0.0.1:8081 \
  --param q \
  --technique unicode_compat_bypass \
  --scope example.com \
  --yes

It enforces scope (in-scope targets only). For HTTP targets it works out of the box. For HTTPS interception, install the optional extra and add --https:

pip install "project-lethe[mitm]"

lethe proxy --listen 127.0.0.1:8081 \
  --param q --technique unicode_compat_bypass \
  --scope example.com --https --yes

On first run Lethe generates a local CA under ~/.cache/project-lethe/mitm/ and prints its path; trust that CA cert in your browser/Burp so the intercepted TLS validates. Lethe mints a per-host leaf certificate on demand and still verifies the upstream server normally — it only terminates TLS on the client side. Only in-scope hosts are intercepted.

Include bounded local-lab stress templates:

lethe http-plan \
  --host example.com \
  --path /search \
  --include-stress \
  --max-padding 1024 \
  --regex-length 64 \
  --format markdown

Lethe does not transmit these templates.

AI Planning

Create .lethe.toml:

[ai]
provider = "gemini"
model = "gemini-2.5-flash"
api_key_env = "GEMINI_API_KEY"

Keep real API keys in environment variables:

export GEMINI_API_KEY='redacted-key-here'

Ask AI for a safety/context plan:

lethe plan --payload '<waf-test>' --site-profile site-profile.json

Use AI planning during generation:

lethe generate --payload '<waf-test>' --site-profile site-profile.json --ai

Local/free provider example:

[ai]
provider = "ollama"
model = "llama3.2"

Supported providers: gemini, openai, claude, ollama, lmstudio, localai, and openai-compatible.

Config

Copy the example:

cp .lethe.toml.example .lethe.toml
lethe config

Ignore local config for one command:

lethe --no-config generate --payload '<test>'

Project Signature

STYX://PROJECT-LETHE [trace online]
canon.map=armed | mode=authorized-lab | output=clean
sig=Avinash K A//styxabhor

Safety

Good places to use Lethe:

  • Your own local lab.
  • Systems you administer.
  • Bug bounty scopes that explicitly allow this type of testing.
  • Defensive parser/canonicalization validation.

Bad places to use Lethe:

  • Random third-party targets.
  • Credential attacks.
  • Service exhaustion.
  • Claims of impact without authorized target evidence.

See SECURITY.md for the full policy.

Kali Linux Usage

For detailed instructions on using Lethe within Kali Linux, see KALI_USAGE.md.

Changelog

See CHANGELOG.md for notable changes per release.

License

MIT. See LICENSE.

About

AI-driven WAF resilience planner and payload mutation engine. Zero dependencies

Topics

Resources

License

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors