Unwaf is a Go tool designed to help identify WAF bypasses using passive techniques. It automates the process of discovering the real origin IP behind a WAF/CDN by combining multiple discovery methods and verifying candidates through HTML similarity comparison, SSL certificate fingerprinting, and HTTP header analysis.
Unwaf is automating the steps I explained on this LinkedIn Post: Passive WAF bypassing
Current version: 3.0.0 — See CHANGELOG.md for version history.
- How It Works
- Discovery Methods
- Verification Methods
- Installation
- Usage
- Options
- Examples
- Configuration
- Author
- License
- Dynamic WAF CIDRs — Fetches live Cloudflare IP ranges and combines with hardcoded WAF/CDN ranges (including IPv6).
- WAF Confirmation — Resolves the domain's current A records, checks if they fall in known WAF/CDN ranges, and fingerprints via HTTP headers.
- Favicon Hashing — Fetches favicon.ico and generates MD5, SHA256, and MMH3 (Shodan) hashes.
- IP Discovery — Runs all enabled methods (up to 15 sources) to collect candidate origin IPs.
- Filtering — Discards IPs belonging to known WAF/CDN ranges and IPs that match the domain's current DNS resolution.
- Port Scanning — Checks candidates on 8 common web ports concurrently with progress bar.
- Origin Verification — For each web server:
- Fetches HTML (direct IP + Host-header injection) and compares with reference
- Compares SSL certificate fingerprints on TLS ports
- Compares HTTP response headers
- Calculates overall score (60% HTML + 25% cert + 15% headers ± status)
- Neighbor Scanning (optional) — Expands confirmed bypass IPs to /24 subnets and scans neighbors.
- ASN Lookup — Identifies ASN and organization for confirmed bypass IPs.
- Results — Reports matches above the threshold with scores, ASN info, and
curlverification commands.
| Method | Type | Description |
|---|---|---|
| SPF records | Free | Extracts IPs from ip4:/ip6: SPF mechanisms |
| MX records | Free | Resolves mail server hostnames (skips Google/Microsoft/etc.) |
| Subdomain probing | Free | Resolves 30+ common subdomains (mail, dev, staging, cpanel, origin, etc.) |
| Certificate Transparency | Free | Queries crt.sh for all subdomains, resolves to non-WAF IPs |
| AlienVault OTX | Free | Passive DNS records (optional API key raises rate limits) |
| RapidDNS | Free | Subdomain enumeration via HTML scraping |
| HackerTarget | Free | Host search API (50 req/day) |
| Wayback Machine | Free | Extracts hostnames from archived URLs via CDX API |
| WAF detection | Free | Fingerprints the WAF vendor via HTTP headers |
| Favicon hashing | Free | Generates MD5, SHA256, and MMH3 hashes for Shodan/Censys search |
| Shodan host search | API (free tier) | Searches by SSL cert CN, hostname, and favicon hash (search requires membership) |
| SecurityTrails history | API (free tier) | Historical DNS A records (50 req/month free) |
| ViewDNS history | API (free tier) | Historical DNS A records (250 free requests) |
| Censys SSL search | API (paid) | Finds hosts presenting SSL certs matching the domain |
| DNSDB/Farsight | API (free tier) | Historical DNS records via NDJSON API (Community Edition: 500 queries/month) |
| Method | Weight | Description |
|---|---|---|
| HTML similarity | 60% | Diff-based text comparison with reference page |
| SSL certificate | 25% | Serial number (50%), CN match (25%), SAN overlap (25%) |
| HTTP headers | 15% | Server, X-Powered-By, and Set-Cookie name comparison |
| Status code | ±5-20% | Bonus for match, penalty for success/error mismatch |
go install github.com/mmarting/unwaf@latestunwaf -h| Flag | Long Flag | Description | Default |
|---|---|---|---|
-d |
--domain |
The domain to check | (required unless -l) |
-s |
--source |
Source HTML file to compare | — |
-c |
--config |
Config file path | $HOME/.unwaf.conf |
-t |
--threshold |
Similarity threshold percentage | 60 |
-w |
--workers |
Number of concurrent workers | 50 |
-v |
--verbose |
Enable verbose output | false |
-q |
--quiet |
Silent mode: only output bypass IPs | false |
--timeout |
HTTP timeout in seconds | 10 |
|
--rate-limit |
Max HTTP requests per second, 0=unlimited | 0 |
|
--proxy |
Proxy URL (http:// or socks5://) |
— | |
--scan-neighbors |
Scan /24 neighbors of confirmed bypass IPs | false |
|
--json |
Output results as JSON | false |
|
-l |
--list |
File containing domains to check, one per line | — |
-o |
--output |
Write results to file | — |
--version |
Print version and exit | — | |
-h |
--help |
Display help information | — |
Check a domain (free methods only, no API keys needed):
unwaf -d example.comBoth bare domains and full URLs work:
unwaf -d https://example.com/pathCheck with a manually saved HTML file (useful when WAF blocks the tool):
unwaf -d example.com -s original.htmlLower the similarity threshold to catch partial matches:
unwaf -d example.com -t 40Increase concurrency for faster scanning:
unwaf -d example.com -w 100Verbose mode to see every resolved subdomain/IP:
unwaf -d example.com -vSilent mode for automation — outputs only IPs, one per line:
unwaf -q -d example.comJSON output for automation:
unwaf -d example.com --jsonBatch mode with domain list:
unwaf -l domains.txt --json -o results.jsonUse a proxy (Tor, Burp, etc.):
unwaf -d example.com --proxy socks5://127.0.0.1:9050Scan /24 neighbors of bypass IPs:
unwaf -d example.com --scan-neighborsRate-limit requests to 2/sec with a 5s timeout:
unwaf -d example.com --rate-limit 2 --timeout 5# Feed into nuclei
unwaf -q -d target.com | nuclei -l - -t waf-bypass.yaml
# Feed into httpx
unwaf -q -d target.com | httpx -silent
# Batch recon
cat domains.txt | while read d; do unwaf -q -d "$d" | sed "s/^/$d,/"; done > results.csv
# JSON + jq
unwaf -d target.com --json | jq '.bypasses[].ip'On first run, Unwaf creates $HOME/.unwaf.conf with this template:
# Unwaf config file — API keys for optional discovery methods
# Free methods (SPF, MX, crt.sh, subdomains, OTX, RapidDNS, HackerTarget, Wayback) work without any keys.
# ViewDNS.info — DNS history (250 free requests, no credit card required)
viewdns=""
# SecurityTrails — DNS history (https://securitytrails.com/corp/api)
securitytrails=""
# Censys — SSL certificate search (requires a PAID license)
censys_token=""
censys_org_id=""
# AlienVault OTX — passive DNS (optional, raises rate limits)
otx_api_key=""
# Shodan — host search by SSL cert, hostname, favicon hash
shodan_api_key=""
# DNSDB/Farsight — historical DNS records (Community Edition: 500 queries/month free)
dnsdb_api_key=""Martín Martín
Distributed under the GPL v3 License.