A fast, operator-friendly CLI for querying the ip.thc.org public intelligence API (dataset advertised as ~6.13 Billion indexed domains) to perform:
- Reverse DNS lookups (IP → domains)
- Subdomain enumeration (domain → subdomains)
- CNAME relationship discovery (target domain → domains pointing to it)
Disclaimer: This tool was developed independently. The author has no affiliation with The Hacker’s Choice (THC).
$ ip-thc subdomain example.com -s
example.com
www.example.com
1.example.com
mail.example.com
*.example.com$ ip-thc reverse-dns 1.1.1.1 -s
example.com$ ip-thc cname github.io -s
shuaxin.011330.xyz
266.icu
book.72moc.com
music.72moc.com
photos.72moc.comWhen you’re doing recon at scale (red team ops, pentests, bug bounty triage, or investigative work), you often need fast enrichment from a large dataset:
- Pivot from an IP to domains hosted behind it (Reverse DNS)
- Expand scope with subdomain coverage (Subdomain Lookup)
- Identify possible hosting / SaaS / takeover surfaces via CNAME pivots (CNAME Lookup)
ip-thc is built as a stable, defensive CLI:
- Clear target ingestion (flags, lists, explicit STDIN)
- Strong operational controls (threads, rate-limit, pagination)
- Proxy support (HTTP(S) + SOCKS5) for segmented environments
- Clean output modes (raw or file output with sort+dedupe)
The CLI is built around subcommands (one per query mode), each with its own
--help:
$ ./ip-thc --help
/$$ www.thc.org /$$ /$$
|__/ | $$ | $$
/$$ /$$$$$$ /$$$$$$ | $$$$$$$ /$$$$$$$
| $$ /$$__ $$ /$$$$$$|_ $$_/ | $$__ $$ /$$_____/
| $$| $$ \ $$|______/ | $$ | $$ \ $$| $$
| $$| $$ | $$ | $$ /$$| $$ | $$| $$
| $$| $$$$$$$/ | $$$$/| $$ | $$| $$$$$$$
|__/| $$____/ \___/ |__/ |__/ \_______/
| $$
| $$ github.com/haltman-io/ip-thc (Golang version)
|__/ [release: v1.1.0]
[!] This tool was developed independently. The author has no affiliation with The Hacker's Choice.
A fast, operator-friendly CLI for querying the ip.thc.org public intelligence
API (dataset advertised as ~6.13 Billion indexed domains).
Run one of the subcommands (reverse-dns, subdomain, cname) and pass targets
via -t, -L/--target-list, --stdin or positional arguments.
Usage:
ip-thc [flags]
ip-thc [command]
Available Commands:
cname CNAME lookup (target domain -> domains pointing to it)
help Help about any command
reverse-dns Reverse DNS lookup (IP -> domains)
subdomain Subdomain lookup (domain -> subdomains)
Flags:
-h, --help help for ip-thc
-V, --version Print version and exit
Use "ip-thc [command] --help" for more information about a command.$ ./ip-thc subdomain --help
Subdomain enumeration against the ip.thc.org dataset.
Targets are domains; they may come from -t, -L/--target-list, --stdin, or
positional arguments.
Usage:
ip-thc subdomain [targets...] [flags]
Aliases:
subdomain, sub
Flags:
--all Auto-pagination until next_page_state is empty
--debug Verbose debug logs to STDERR
-h, --help help for subdomain
-k, --insecure Disable TLS verification (curl-style)
--jsonl Print results as JSON lines (full metadata, not just domain)
--limit int Alias for --results (default 10)
--no-proxy Ignore proxy environment variables
-o, --output string Save sorted + deduped results to file
--proxy string Proxy URL: http://host:port, https://host:port, socks5://host:port
--proxy-auth string Proxy auth: HTTP Basic or SOCKS5 user/pass
--rate-limit float Max requests per second (default 5)
-r, --results int Max results per API request (default 10)
--retries int HTTP retries on transient errors/429/5xx (0 disables) (default 3)
-s, --silent Print results only (also suppress banner)
--stdin Read targets from STDIN (pipe) as additional targets
-t, --target stringArray Define a target (repeatable, comma-separated supported)
-L, --target-list stringArray File with targets (one per line; repeatable, comma-separated supported)
--threads int Concurrent targets (default 1)
--timeout duration HTTP timeout (default: 30s). Examples: 30s, 2m (default 30s)
--user-agent string Override User-Agent (default "ip-thc/v1.1.0")The reverse-dns and cname subcommands accept the same flags.
ip-thc reverse-dns(aliasrdns) →POST /api/v1/lookupip-thc subdomain(aliassub) →POST /api/v1/lookup/subdomainsip-thc cname(aliascn) →POST /api/v1/lookup/cnames
--target/-t(repeatable, supports comma-separated lists)--target-list/-L(repeatable, supports comma-separated file paths; one target per line)--stdin(explicitly enables reading piped targets from STDIN)- positional arguments:
ip-thc subdomain example.com
STDIN is ignored unless --stdin is explicitly provided.
Targets are normalized automatically: schemes (https://), trailing slashes
and trailing dots are stripped, casing is lowered, and duplicates are collapsed.
In reverse-dns mode the target must be a valid IP address (the CLI refuses
to start otherwise), so no API calls are wasted.
- API responses include
next_page_state - With
--all,ip-thccontinues requesting pages untilnext_page_state == ""
--threadscontrols concurrency across targets--rate-limitcontrols max requests per second (global token-bucket limiter shared by all workers, so the exact RPS holds at scale)--retries(default 3) retries transient failures with exponential backoff + jitter:- network errors, HTTP
408,429, and5xx - honors the server's
Retry-Afterheader - disabled with
--retries 0
- network errors, HTTP
- Server-side rate guidance (response headers):
X-Ratelimit-Remaining < 5→ silent 15s pauseX-Ratelimit-Remaining == 0→ silent 30s pause
- Default prints one result per line (streamed as pages arrive)
--jsonlprints full records as JSON lines (domain + apex/country/city/ASN/TLD/org/last-seen when the API provides them) — ideal for piping into downstream tooling--output/-osaves sorted + deduplicated results to a file (plain lines or JSONL with--jsonl)- A run summary (targets / ok / errors / results / elapsed) is printed to STDERR, so stdout stays clean for piping
-
--proxysupports:http://host:porthttps://host:portsocks5://host:port(andsocks5h://host:port)
-
--proxy-auth user:passfor HTTP Basic proxy auth or SOCKS5 auth -
--no-proxyignores environment proxy variables -
--insecure/-kdisables TLS verification (curl-style)
--silent/-ssuppresses the banner and prints only results (no decorations)
--version/-Vprints the version and exits (no banner, script-friendly)
Hidden easter egg
--thcprints a greets message and exits (not listed in help)
- Reverse DNS lookup:
https://ip.thc.org/docs/API/reverse-dns-lookup - Subdomain lookup:
https://ip.thc.org/docs/API/subdomain-lookup - CNAME lookup:
https://ip.thc.org/docs/API/cname-lookup
| Variable | Purpose |
|---|---|
IP_THC_BASE_URL |
Override the API base URL (default https://ip.thc.org/api/v1) — useful for mirrors/tests |
HTTP_PROXY / HTTPS_PROXY / ALL_PROXY |
Honored unless --no-proxy is set |
- Go 1.22+
- Network access to
ip.thc.org(unless you route through a proxy)
git clone https://github.com/haltman-io/ip-thc.git
cd ip-thc
make build # builds ./ip-thc (or: go build -o ./ip-thc ./cmd/ip-thc)
make test # runs the test suite (with -race)Run:
./ip-thc --helpGo installs binaries into:
$GOBINif set, otherwise$GOPATH/bin(commonly~/go/bin)
From the repository root:
go install ./cmd/ip-thcNow ip-thc should be available on your PATH if $GOBIN (or $GOPATH/bin) is in PATH.
Verify:
command -v ip-thc
ip-thc --helpgo build -o ip-thc ./cmd/ip-thc
mv ip-thc "${GOBIN:-$HOME/go/bin}/ip-thc"Ensure your PATH includes the bin directory:
export PATH="${GOBIN:-$HOME/go/bin}:$PATH"ip-thc --help # root help + subcommand list
ip-thc subdomain --help # per-subcommand help
ip-thc help cname # or: ip-thc cname -h--target-listshorthand is now-L(pflag supports single-char shorthands only;-tLno longer exists)--rate-limithas no shorthand (-rlremoved); use the long flag- Targets can also be passed as positional arguments:
ip-thc subdomain example.com - Subcommand aliases:
rdns,sub,cn
ip-thc reverse-dns -t 1.1.1.1All pages:
ip-thc reverse-dns -t 1.1.1.1 --allip-thc subdomain -t example.comMultiple targets (comma-separated):
ip-thc subdomain -t google.com,twitter.comMultiple targets (repeat flag):
ip-thc subdomain -t google.com -t twitter.comip-thc cname -t github.ioSingle list:
ip-thc subdomain -L targets.txtMultiple files:
ip-thc subdomain -L targets1.txt -L targets2.txtMultiple files (comma-separated):
ip-thc subdomain -L targets1.txt,targets2.txtSTDIN must be explicitly enabled:
cat targets.txt | ip-thc subdomain --stdinPipeline + extra targets combined:
cat targets.txt | ip-thc subdomain --stdin -t example.comip-thc subdomain -t example.com --all -o subdomains.txtThe file will contain unique entries, sorted lexicographically.
ip-thc reverse-dns -t 1.1.1.1 --all --jsonlEach line is a JSON object, e.g.:
{"domain":"one.example.com","apex_domain":"example.com","country":"US","city":"...","asn":"AS13335","tld":"com","organization":"...","last_seen_on":"2026-01-01"}Pipe straight into downstream tooling:
ip-thc reverse-dns -t 1.1.1.1 --jsonl | jq -r .domainDefault:
--rate-limit 5(requests per second)
Tune it:
ip-thc subdomain -t example.com --rate-limit 2Default: --retries 3 with exponential backoff + jitter (up to 30s per retry),
honoring the server's Retry-After header. Disable for strict one-shot behavior:
ip-thc subdomain -t example.com --retries 0If the server sends:
X-Ratelimit-Remaining < 5
ip-thc will pause silently for 15 seconds to reduce the chance of hitting hard limits (30 seconds when the quota is exhausted).
You should still use conservative settings when running at scale. Don’t abuse public services.
ip-thc subdomain -t example.com --proxy http://127.0.0.1:8080ip-thc subdomain -t example.com --proxy http://127.0.0.1:8080 --proxy-auth user:passip-thc subdomain -t example.com --proxy socks5://127.0.0.1:9050ip-thc subdomain -t example.com --proxy socks5://127.0.0.1:9050 --proxy-auth user:passip-thc subdomain -t example.com --proxy http://127.0.0.1:8080 --no-proxyDisable TLS verification (curl -k style):
ip-thc subdomain -t example.com -kUse only when you fully understand the risk (MITM visibility, etc.).
Enable debug logs to STDERR:
ip-thc subdomain -t example.com --debugDebug includes:
- Request path + request JSON
- HTTP status + truncated response payload
- Worker/target execution traces
0→ success (no fatal errors)1→ completed but at least one target failed2→ invalid arguments / configuration / initialization errors
This tool is intended for:
- authorized security assessments,
- lawful investigation,
- defensive research,
- and legitimate bug bounty activity.
You are responsible for complying with:
- applicable laws,
- scope boundaries,
- and the upstream service’s acceptable use policies.
This project is licensed under the Unlicense, see the LICENSE file for details.
- Public intelligence API: ip.thc.org
- Inspired by the operational needs of offensive and investigative practitioners