Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 64 additions & 0 deletions tools/zeithawk/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,18 @@ review/testing work against systems they're authorized to test.
- **Comparer** — line-level diff between two blocks of text.
- **History** — every request sent from Repeater or Intruder, stored in
`localStorage`, click a row to reload it into Repeater.
- **Recon** — DNS records (A/AAAA/MX/TXT/NS/CNAME/SOA) via DNS-over-HTTPS,
WHOIS/RDAP, and an HTTP-reachability check on common web ports for a
domain or IP — plus ready-to-copy `ping`/`traceroute`/`whois`/`nmap`
commands for the things a browser can't do (see below).
- **Vuln Scan** — a lightweight header/config checker in the spirit of
securityheaders.com or Mozilla Observatory: checks for common security
headers (HSTS, CSP, X-Frame-Options, X-Content-Type-Options,
Referrer-Policy, Permissions-Policy), flags a permissive-plus-credentialed
CORS policy, and probes a fixed list of commonly-exposed sensitive paths
(`.env`, `.git/HEAD`, `wp-config.php.bak`, `id_rsa`, etc). Not a
signature-based scanner like Nessus/OpenVAS/Nikto — see below for what it
can and can't actually prove.

## Constraints (by design — it runs entirely client-side)

Expand All @@ -42,3 +54,55 @@ mitmproxy).

**Authorized testing only.** Only point this at systems you own or have
explicit permission to test.

## Recon's limits (also by design)

A browser has no API for raw sockets, so three of the things "recon a
target" usually means are flatly impossible from client-side JS, not just
inconvenient:

- **ICMP ping** — needs a raw socket; there's no ping API in a browser.
- **Traceroute** — needs to send packets with increasing TTL and read back
ICMP responses; same problem, no workaround.
- **A real port scan** — needs raw TCP SYN/connect control across arbitrary
ports; a browser's `fetch()` can only ever make an HTTP request, and only
on ports the browser itself doesn't block outright.

Recon's "HTTP reachability" table is a limited, honest substitute: it tries
a plain HTTPS/HTTP request on a handful of common web ports and reports
reachable/timeout/closed — useful signal, not a substitute for `nmap`.
For the real thing, Recon prints ready-to-copy `ping`, `traceroute`,
`whois`, and `nmap` commands to run in your own terminal, against targets
you're authorized to test.

DNS-over-HTTPS (`dns.google`) and RDAP (`rdap.org`, which bootstraps to the
authoritative registry) are both public APIs with no key required. RDAP
lookups can still fail if the target registry's own RDAP server doesn't
send CORS headers for browser access — when that happens, Recon says so
and points at the `whois` command instead.

## Vuln Scan's limits (also by design)

The security-header checks can only ever prove a header is **present** —
they can never prove one is **missing**. Browsers only expose a small
CORS-safelisted set of response headers to cross-origin JavaScript
(`Cache-Control`, `Content-Language`, `Content-Length`, `Content-Type`,
`Expires`, `Last-Modified`, `Pragma`); none of the security headers this
tool checks are in that list. A server can only make a header readable by
naming it in its own `Access-Control-Expose-Headers` response header. So
when a check reports "Not readable cross-origin", that means exactly what
it says — unproven either way — not "confirmed missing." This applies to
`Access-Control-Allow-Origin` itself too: if it isn't exposed via
`Access-Control-Expose-Headers`, Vuln Scan can't even read whether CORS is
open, and says so rather than guessing. Every row that reports a real
finding (a header actually read, a CORS policy actually inspected, a path
that actually returned a status code) is something ZeitHawk directly
observed — never inferred from silence. For ground truth on anything
marked "Not readable cross-origin," the read-out includes a ready-to-copy
`curl -sD - -o /dev/null <url>` command, which sees every header a server
sends, no CORS restriction involved.

The exposed-path checks need the target to allow cross-origin reads at
all (same CORS requirement as Repeater) to see status codes back; a
target with a locked-down CORS policy will show every path check as
blocked, which is not the same as those paths not existing.
Loading
Loading