Skip to content

SnailSploit/Snail-Url

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 

Repository files navigation

Snail-url

Async open-redirect hunter for red teams and appsec engineers. Crawls, harvests redirect-prone URLs, injects payloads, and confirms real open redirects via HTTP 30x, HTML meta refresh, and common JS redirects.

⚠️ Legal/Ethical: Use only on assets you own or are authorized to test. You are responsible for complying with all laws and terms of service.


Highlights

  • Fast & async (aiohttp) with per-host rate limiting
  • 🧭 Crawler fallback (scope-aware) to discover targets when you don’t have a URL list
  • 🧪 Payload strategy sets: basic, aggressive, stealth (and custom test domain)
  • 🔐 SAML / OIDC focus: RelayState, redirect_uri, returnTo, continue, etc.
  • 📤 Outputs: JSON, NDJSON, CSV + optional dump of unverified candidates
  • 🖥️ Pretty CLI: compact, padded tables that don’t overflow your terminal

Install

Local

git clone https://github.com/<you>/snail-url.git
cd snail-url
python3 -m venv .venv && source .venv/bin/activate
pip install --upgrade pip
pip install -e .

Docker

docker build -t snail-url:latest .
# mount current folder for saving results
docker run --rm -v "$(pwd)":/scan snail-url:latest \
  snail-url -d example.com --crawl --max-pages 2000 --json-out /scan/results.json

Quick start

Basic run (no crawl):

snail-url -d example.com --json-out results.json

Crawler fallback + aggressive payloads:

snail-url -d example.com \
  --crawl --max-pages 2000 \
  --payload-set aggressive \
  --include-subdomains \
  --samloidc \
  --pretty --max-col 100 \
  --json-out results.json --csv-out results.csv

Use a custom callback/test domain:

snail-url -d example.com --test-domain https://red.example/cb --json-out results.json

Scan a pre-collected list instead of crawling:

snail-url --in urls.txt --json-out results.json --pretty

Dump the unverified candidate list for manual review:

snail-url -d example.com --crawl --candidates-out candidates.txt

CLI

snail-url [-d DOMAIN] [--seed URL ...] [--in FILE] [--crawl]
          [--include-subdomains] [--respect-robots]
          [--max-pages N] [-c N] [--per-host N]
          [--payload-set {basic,aggressive,stealth}]
          [--test-domain URL]
          [--json-out FILE] [--ndjson-out FILE] [--csv-out FILE]
          [--candidates-out FILE] [--user-agent UA] [--samloidc]
          [--pretty] [--no-banner] [--max-col N]

Most useful flags

  • -d, --domain — target registrable domain (sets default scope/seed)
  • --seed — one or more starting URLs (repeatable)
  • --in — file with URLs to check (one per line)
  • --crawl — enable crawler fallback (async, scope-aware)
  • --include-subdomains — widen scope to subdomains
  • --max-pages — crawl budget (default: 2000)
  • -c, --concurrency — global concurrency (default: 40)
  • --per-host — per-host concurrency limit (default: 10)
  • --payload-setbasic | aggressive | stealth
  • --test-domain — destination injected into redirect params
  • --samloidc — prioritize SAML/OIDC keys (RelayState, redirect_uri, etc.)
  • --pretty, --max-col — tidy, padded table output
  • --json-out, --ndjson-out, --csv-out — choose one or many

What gets detected

  • HTTP redirects: 30x with Location pointing to your test domain
  • HTML Meta Refresh: e.g., <meta http-equiv="refresh" content="0;url=...">
  • JS redirects: location =, location.replace(), location.assign()

Redirect-ish parameters (partial list): redirect, redirect_uri, url, next, dest, destination, return, returnTo, continue, cb, RelayState, etc.

SAML/OIDC heuristics (when --samloidc):

  • Detects SAML-ish or OIDC-ish endpoints (/saml/..., /oauth*/authorize, /callback).
  • Elevates RelayState and redirect_uri for injection.

Output examples

JSON

[
  {
    "original": "https://app.example.com/redirect?redirect_uri=/dashboard",
    "confirmed": true,
    "param": "redirect_uri",
    "payload": "https://red.example/cb",
    "mutated": "https://app.example.com/redirect?redirect_uri=https%3A%2F%2Fred.example%2Fcb",
    "via": "http_redirect",
    "status": 302,
    "location": "https://red.example/cb"
  }
]

NDJSON

{"original":"https://...","confirmed":true,"param":"redirect","via":"html/js_redirect","status":200,...}

CSV (columns vary with data)

confirmed,param,original,mutated,via,status,location,payload
true,redirect_uri,https://...,https://...,http_redirect,302,https://red.example/cb,https://red.example/cb

How it works (high-level)

Seeds/URLs
   └─► Crawler (optional) ─► Harvester (redirect-ish params)
                              └─► Verifier (payload sets, no-follow)
                                   └─► Findings (JSON/NDJSON/CSV)
  • Crawler: async fetch, extracts links, respects scope, per-host RL.
  • Harvester: filters URLs with redirect-ish parameters.
  • Verifier: injects payloads → checks 30x Location, meta refresh, JS redirect.

Tuning & tips

  • Throughput: Bump -c but keep --per-host reasonable (8–12) to reduce server strain.
  • Noise: Use --payload-set stealth for low-touch passes; aggressive when you need depth.
  • Scope: Start narrow (-d) and add --include-subdomains if needed.
  • Crawler budget: Increase --max-pages for large estates; capture candidates via --candidates-out.
  • User-Agent: Customize with --user-agent for logs/attribution.

Troubleshooting

  • No findings but many candidates Targets might block external destinations; try different --payload-set or --test-domain.
  • Timeouts Reduce -c and --per-host; some WAFs throttle concurrency.
  • Messy terminal output Use --pretty --max-col 100 (table is padded & ellipsized). Use --no-banner to minimize whitespace.

Development

# lint/format as you like; basic tests included
pytest -q

Project layout:

snail_url/
  cli.py          # CLI entry
  crawler.py      # async crawler (scope-aware)
  harvester.py    # picks redirect-like URLs
  verifier.py     # injects payloads, confirms redirects
  payloads.py     # basic/aggressive/stealth generators
  saml_oidc.py    # SAML/OIDC heuristics
  ui.py           # pretty table output
  utils.py, constants.py, output.py

Roadmap

  • Optional archive sources (Wayback, GAU) as inputs
  • SARIF exporter for CI
  • Parameter mutation strategies by framework (Next.js, Spring, ASP.NET)
  • Allow/deny-lists per path/param

Contributing

PRs and issues welcome. Please include:

  • Clear repro steps (target pattern anonymized)
  • Before/after output snippets
  • Any performance/safety considerations

License

MIT © SnailSploit


Want me to drop this straight into your repo as README.md (and add status badges)? Say the word and I’ll prep a PR description and push-ready commit message.

About

Snail-Url is Yet another Wrapper for Open Redirect finding,

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages