Repo: github.com/YusufAlMahmeed/cataract . Star it and keep an eye on the GitHub page for updates. Bug reports, feature ideas, and suggestions are welcome: open an issue on the repo.

Cataract is actively maintained, so this page describes how it works rather than any one release. For the current flags, defaults, and release history, the repository and its changelog are always the source of truth.

What it is#

Cataract is a small Bash tool for authorized web penetration testing. Its one-liner:

Tiered, recursive, multi-target web enumeration for authorized web penetration testing.

It automates the tedious part of content discovery, deciding which wordlist, when, by cascading through escalating tiers of wordlists with feroxbuster while an nmap full-port scan runs in the background. The name is the idea: results fall through tiers like water down a cataract.

Why#

On a typical web engagement you start with a small wordlist, then reach for a bigger one, then a bigger one still, restarting the scan each time and juggling nmap on the side. Cataract turns that manual escalation into one flow: it runs a tier, pauses so you can decide whether the next (larger) tier is worth it, and keeps nmap and per-target logging organized while you work.

The tiers#

The cascade climbs from quick-and-common to broad-and-thorough:

  1. dirb/common.txt
  2. dirb/big.txt
  3. SecLists raft-medium-directories.txt
  4. SecLists raft-large-directories.txt

Tiers 3 and 4 use the directories lists, not the files lists: directory words carry no extension, so appending your extension set is correct instead of producing waste like index.php.php, and directories are what recursion descends into. When the matching raft-*-files.txt list is present, Cataract also runs it as a filename pass without extensions, so real filenames are still covered.

After each tier Cataract prompts before continuing, so you spend big wordlists only where they earn their keep. You can also skip the cascade entirely and supply your own wordlists with -w (see below).

Options#

Every setting is a flag, and the important ones have sensible defaults, so interactive mode needs none of them:

FlagWhat it doesDefault
-o <dir>Output directory (required in non-interactive -a mode)—
-f <file>Read targets from a file, one per line—
-t <n>feroxbuster threads (how many requests run at once, not a time limit)50
-d <n>Recursion depth: how many directory levels deep to keep descending2
-x <exts>Comma-separated file extensions to append to each wordphp,html,txt,js,json,bak,zip
--no-extDon’t append any extensions on any passoff
-w <wordlist>Use a custom wordlist instead of the tier cascade; repeatable, and run in the order given—
--dry-runPrint the plan and per-tier request estimates, then exit without scanningoff
-k, --insecureSkip TLS certificate validation (for self-signed lab certs)auto-on for https://
-a, --autoNon-interactive: run every tier and auto-enumerate discovered portsoff
-H <header>Add an extra HTTP header; repeatable (e.g. a session cookie)—
--rate-limit <n>Cap feroxbuster at n requests per secondoff
--udpAlso sweep the top 100 UDP ports in the background (needs root)off
-h, --helpPrint usage and exit—

By default Cataract runs the port scan in two phases: a fast full-port sweep to find open ports quickly, then a deeper service- and script-detection scan on just those ports. The fast sweep uses nmap by default (the accuracy-first choice); set FAST_SCANNER=rustscan to use RustScan for much faster sweeps on low-latency or lab networks (it can miss ports on high-latency or rate-limited links), or FAST_SCANNER=auto to pick RustScan when it’s installed. Either way the scan reports progress at an interval, so a long sweep never looks hung. Run it (or at least the scan) as root for a SYN sweep, a “half-open” scan that never finishes the TCP handshake, so it is quicker and quieter; without root it falls back to a slower TCP connect scan and Cataract warns you at startup. Add --udp to also sweep the top UDP ports alongside the TCP scan.

Features#

  • Flexible target input: a bare IP, host:port, or a full URL (bare values default to http://)
  • Per-target service and port selection in interactive mode
  • Parallel full-port nmap scan in the background while feroxbuster works
  • Four-tier wordlist cascade with a continue-prompt after each tier
  • Auto-discovery of additional web ports nmap turns up, with the option to scan them too
  • Recursive directory discovery, with configurable depth
  • Automatic -k for HTTPS targets so self-signed certificates don’t break the run
  • Colorised output kept on screen while logging to a file and to JSON
  • A per-target summary.md plus a combined index.md report
  • Scriptable via CLI flags for unattended runs
  • tmux tabbed interface (one tab per target) that works over SSH and survives disconnects, with a sequential fallback when tmux isn’t available
  • Preflight checks for the required tools and wordlists, with install hints

Install#

git clone https://github.com/YusufAlMahmeed/cataract.git
cd cataract && chmod +x cataract.sh

Dependencies (Debian/Kali):

sudo apt update && sudo apt install -y nmap feroxbuster tmux jq dirb seclists bsdutils util-linux
  • Required: bash, nmap, feroxbuster, script (util-linux), dirb wordlists
  • Recommended: tmux, jq
  • Optional: SecLists (for the medium/large tiers)

Linux only (Kali/Debian/Ubuntu tested). Cataract uses util-linux script to keep feroxbuster colorized while logging, which isn’t available on macOS/BSD, so it exits early with a clear message on non-Linux hosts.

Usage#

Interactive mode walks you through targets and options:

./cataract.sh

You can also pass targets directly, as bare IPs, host:port, or full URLs:

./cataract.sh -o results/ 10.10.10.10 10.10.10.20:8080 https://app.local

What this does: -o results/ sets the output directory, and the remaining arguments are the targets (a bare IP defaults to http://). To read many targets from a file instead, use -f targets.txt.

For an unattended, authenticated, rate-limited run:

./cataract.sh -o results/ -a -t 30 -d 2 --rate-limit 40 \
              -H 'Cookie: session=abc123' https://app.local:8443

What this does: -a runs non-interactively through every tier (no continue-prompts), -t 30 sets feroxbuster to 30 concurrent threads (concurrency, not a 30-minute limit), -d 2 keeps recursion two directory levels deep, --rate-limit 40 caps feroxbuster at 40 requests per second (gentler on a fragile target), and -H 'Cookie: session=abc123' sends that session cookie on every request so the scan runs as a logged-in user.

To skip the tier cascade and run your own wordlists in order, and preview the plan before committing to it:

./cataract.sh -o results/ -w quick.txt -w big.txt --dry-run https://app.local

What this does: each -w adds a wordlist (they run in the order given), --dry-run prints the plan and per-tier request estimates and then exits without scanning, so you can see what a run will cost first.

See it run#

A quick run from start to finish: the interactive service/port prompts, the wordlist check, and the tiered feroxbuster scan with nmap working in the background.

Cataract running: interactive service and port prompts, the wordlist-tier check, and feroxbuster scanning while nmap runs in the background
A full run from start to finish: notice how Cataract takes the service and port for each target, checks which wordlist tiers are available, then runs feroxbuster while the nmap scan works in the background.

A note on scope#

Cataract is built for authorized testing only, engagements where you have explicit permission to enumerate the target. Point it at your own labs, or at systems you are contracted to assess. Large wordlists against a host you don’t own is noisy, and out of scope.

Stay in the loop#

This tool is actively maintained. Watch the GitHub repository for updates, and if you hit a bug or have a suggestion, please open an issue , feedback is what drives the next tier.

  • Shakabrah — an OffSec machine walkthrough where I use Cataract for the initial web enumeration.