Katana: Complete Guide to Web Crawling and Attack Surface Discovery Using Kali Linux

Katana: Complete Guide to Web Crawling and Attack Surface Discovery Using Kali Linux

katana is a next-generation crawling and spidering framework developed by ProjectDiscovery, written in Go, designed to handle both traditional server-rendered HTML sites and modern JavaScript-heavy Single Page Applications (SPAs). Unlike simpler crawlers, katana supports a headless browsing mode (via chromedp) that fully renders JavaScript before extracting links, form actions, and API calls — making it far more effective against React/Angular/Vue applications. It also supports scope control, output filtering, passive-source integration, and direct piping into other ProjectDiscovery tools like httpx and Nuclei.

How to Install

# Kali Linux
sudo apt update
sudo apt install katana -y
katana -version

# Or via Go
go install github.com/projectdiscovery/katana/cmd/katana@latest

Headless mode requires Chromium:

sudo apt install chromium -y

Syntax

katana -u <target> [options]
katana -list <targets_file> [options]

All Command-Line Options (Key Flags)

OptionDescription
-u, -list <url/file>Target URL or file with list of URLs
-d, -depth <n>Maximum crawl depth (default 3)
-jc, -js-crawlEnable crawling/parsing of JavaScript files
-hl, -headlessEnable headless browser-based crawling
-sc, -system-chromeUse local installed Chrome instead of downloading one
-xhr, -xhr-extractionExtract XHR/API requests during headless crawl
-jsluiceUse jsluice for deeper JS endpoint extraction
-c, -concurrency <n>Concurrent workers (default 10)
-p, -parallelism <n>Concurrent parallel crawls
-rd, -rate-limit-domain <n>Rate limit per domain
-rl, -rate-limit <n>Global rate limit (requests/sec)
-kf, -known-files <type>Fetch known files (robotstxt, sitemapxml, all)
-fs, -field-scope <scope>Scope: rdn (root domain), fqdn, dn
-cs, -crawl-scope <regex>Regex-based crawl scope
-cos, -crawl-out-scope <regex>Exclude regex from crawl scope
-mdc, -match-condition <cond>Match based on custom DSL condition
-f, -field <field>Extract specific field: url, qurl, path, fqdn, rdn, rurl
-em, -extension-match <ext>Match specific extensions
-ef, -extension-filter <ext>Filter out specific extensions
-o, -output <file>Write output to file
-j, -jsonlOutput as JSON Lines
-silentSuppress banner, show only results
-nc, -no-colorDisable colored output
-timeout <secs>Request timeout
-retry <n>Retry count on failure
-proxy <url>Route requests through proxy
-H, -headers <header>Custom HTTP headers
-form-extractionExtract HTML form details
-tls-impersonateTLS fingerprint randomization/impersonation
-aff, -automatic-form-fillAutomatically fill and submit discovered forms

Basic Usage (Expected Output in Bash)

$ katana -u https://testphp.vulnweb.com

Output:

   __        __                 
  / /_____ _/ /____ ____  ___ _
 /  '_/ _  / __/ _  / _ \/ _  /
/_/\_\\_,_/\__/\_,_/_//_/\_,_/  v1.1.2

		projectdiscovery.io

[INF] Current katana version: v1.1.2
https://testphp.vulnweb.com/
https://testphp.vulnweb.com/login.php
https://testphp.vulnweb.com/search.php?test=query
https://testphp.vulnweb.com/categories.php

Practical Examples with Output

Example 1 — Headless crawl of a JavaScript SPA

$ katana -u https://example-spa.com -headless -jc

Output:

[INF] Starting headless crawl...
https://example-spa.com/
https://example-spa.com/api/v1/products
https://example-spa.com/api/v1/user/profile
https://example-spa.com/static/app.bundle.js

Example 2 — Extract XHR/API requests specifically

$ katana -u https://example-spa.com -headless -xhr -jsonl | jq '.request.endpoint'

Output:

"https://example-spa.com/api/v1/login"
"https://example-spa.com/api/v1/cart"

Example 3 — Crawl with scope restricted to root domain

$ katana -u https://example.com -fs rdn -d 4

Output:

https://example.com/
https://example.com/blog/post-1
https://sub.example.com/dashboard

Example 4 — Extract only unique query-string URLs

$ katana -u https://testphp.vulnweb.com -f qurl

Output:

https://testphp.vulnweb.com/search.php?test=query
https://testphp.vulnweb.com/artists.php?artist=1
https://testphp.vulnweb.com/listproducts.php?cat=1

Example 5 — Filter by file extension (only JS files)

$ katana -u https://example.com -em js

Output:

https://example.com/static/main.js
https://example.com/static/vendor.js

Example 6 — Crawl a list of targets and save JSONL

$ katana -list targets.txt -jsonl -o katana-results.jsonl
$ jq -r '.request.endpoint' katana-results.jsonl | head -3

Output:

https://target1.com/
https://target1.com/about
https://target2.com/login

Example 7 — Known-files discovery (robots.txt, sitemap.xml)

$ katana -u https://example.com -kf all

Output:

[INF] Found robots.txt with 12 disallowed paths
[INF] Found sitemap.xml with 84 URLs
https://example.com/admin (from robots.txt)
https://example.com/archive/2024 (from sitemap.xml)

Example 8 — Route through Burp for combined manual/automated recon

$ katana -u https://testphp.vulnweb.com -proxy http://127.0.0.1:8080

Output:

[INF] Proxy configured: http://127.0.0.1:8080
https://testphp.vulnweb.com/login.php

Example 9 — Chain with httpx and Nuclei

$ katana -u https://testphp.vulnweb.com -silent | httpx -silent | nuclei -silent -tags xss,sqli

Output:

[sqli-error-based] [http] [high] https://testphp.vulnweb.com/artists.php?artist=1

Example 10 — Automatic form filling and submission

$ katana -u https://testphp.vulnweb.com -aff -form-extraction

Output:

[INF] Discovered form: /search.php (method=GET, field=searchFor)
[INF] Auto-filled and submitted form
https://testphp.vulnweb.com/search.php?searchFor=test&goButton=go

Common Use Cases

Automation with Bash

#!/bin/bash
# katana-full-crawl.sh — headless crawl + API extraction + Nuclei scan pipeline

TARGET="$1"
OUTDIR="katana-scan-$(date +%Y%m%d)"
mkdir -p "$OUTDIR"

echo "[*] Running headless crawl with XHR extraction..."
katana -u "$TARGET" -headless -jc -xhr -jsonl -o "$OUTDIR/crawl.jsonl" -silent

echo "[*] Extracting unique endpoints..."
jq -r '.request.endpoint' "$OUTDIR/crawl.jsonl" | sort -u > "$OUTDIR/endpoints.txt"

echo "[*] Probing endpoints with httpx..."
cat "$OUTDIR/endpoints.txt" | httpx -silent -o "$OUTDIR/live-endpoints.txt"

echo "[*] Running Nuclei against live endpoints..."
nuclei -l "$OUTDIR/live-endpoints.txt" -silent -o "$OUTDIR/nuclei-findings.txt"

echo "[+] Pipeline complete. Findings: $OUTDIR/nuclei-findings.txt"

Tips and Best Practices

Troubleshooting

IssueCauseFix
Headless mode fails to launchMissing Chromiumsudo apt install chromium and retry, or use -sc for system Chrome
Crawl misses SPA routesJS not executedEnsure -headless -jc are both enabled
Too many out-of-scope resultsNo scope restriction setUse -fs rdn or -cs with a regex
Extremely slow crawlHigh depth + headless overheadReduce -d depth or increase -c concurrency carefully
Rate-limited/blocked by targetNo rate limiting configuredSet -rl and -rd to reasonable values

References

Exit mobile version