Open-source project
haccer/subjack avatar
haccer/subjack

Subjack: nine-vector DNS takeover scanner for subdomain security testing

DNS Takeover tool written in Go

2,123 stars347 forksGoMIT

At a glance

What is it?
Subjack is a Go tool that checks subdomains for nine categories of DNS misconfiguration, from dangling CNAMEs to expired mail server domains, using concurrent scans against a wordlist or from stdin. CNAME chain and SRV record checks run on every scan without a flag; NS, stale A record, AXFR, and email checks each require an explicit flag to enable.
Who is it for?
Subjack covers nine DNS takeover vectors in a single tool, from basic dangling CNAMEs through SPF include chain expiration and zone-transfer NS bruteforcing that sets it apart from simpler CNAME-only scanners. Bug bounty researchers and infrastructure security teams scanning large subdomain wordlists are the intended audience, and the stdin integration makes it easy to chain with enumeration tools like subfinder.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 11 days ago.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Nine detection categories, four automatic and five behind explicit flags

Subjack checks for nine types of DNS-based exposure. Four categories run on every scan without any flag: CNAME takeovers, CNAME chain takeovers, SRV record takeovers, and NXDOMAIN registration. The remaining five require dedicated flags: NS delegation takeovers (-ns), stale A records (-ar), zone transfers (-axfr), and SPF plus MX email takeovers (-mail).

The automatic CNAME chain check follows multi-level chains up to 10 hops and tests each intermediate hop for claimability. Standard CNAME detection stops at the first hop, so a claimable target sitting at hop three would be missed by a simpler scanner. SRV records point to servers for SIP, XMPP, LDAP, Kerberos, IMAP, CalDAV, and other services; subjack checks a list of common SRV names against each domain for expired or unregistered targets without the user opting in.

Because the four automatic checks always run, any minimal scan also tests CNAME chains and SRV targets. Running the same wordlist again with additional flags produces separate output files covering NS, stale A, AXFR, or email vectors, and combining results from multiple runs requires manual review since there is no built-in deduplication across separate invocations.

Installing via go install requires Go 1.25.1, a version the README does not state

The README gives the install command as:

bash
go install github.com/haccer/subjack@latest

It links to the Go download page with the note "Requires Go" but does not list a minimum version. The go.mod file in the repository sets the minimum at go 1.25.1. A developer checking only the README and running an older Go toolchain will hit a build failure with no guidance from the documentation on which version to install.

Once installed, the basic scan command from the README is:

bash
subjack -w subdomains.txt -t 100 -timeout 30 -o results.txt -ssl

The flag table in the README documents a default thread count of 10 for -t, while the example passes 100. A user running the scan without -t gets one tenth of the concurrency in the example. The -timeout default is 10 seconds, and the -ssl flag forces HTTPS; the README notes this may increase accuracy. Using a .json extension in -o writes the output in JSON format rather than plain text.

Without -a, the scan skips domains that have no CNAME record

The -a flag broadens scan coverage from CNAME-bearing domains to all domains in the wordlist. In the README's flag table, -a is described with a parenthetical "(recommended)" inside the description field, making it the only flag in that table to carry FoxIO's own recommendation directly in the table cell.

With -a absent, a domain carrying a stale A record but no CNAME gets no outbound request. An expired MX target that lacks a CNAME receives no probe. The gap means that running the basic command without -a misses every takeover vector that exists on non-CNAME domains. Because the default is false, users copying the install command get narrower coverage than a full -a scan would produce.

Subjack also reads domains from stdin, making it compatible with subdomain enumeration pipelines:

bash
subfinder -d example.com | subjack -ssl -o results.json

The -r flag accepts a file of custom DNS resolvers, one IP per line; subjack falls back to 8.8.8.8 if a listed resolver fails. The -m flag marks dead CNAME records even when the target domain is not currently available for registration, catching cases where the domain is parked or in a redemption period rather than outright available.

NS takeover checks test expired domains and deleted zones across six cloud providers

With -ns, subjack runs two checks per domain. The first tests whether the domain's nameservers have expired and are available for re-registration. The second checks whether the hosted zone at the provider has been deleted: subjack queries each NS host directly for an SOA record, and if all nameservers return SERVFAIL or REFUSED, the zone is absent and the delegation may be claimable. Six cloud DNS providers are in scope: AWS Route 53, Google Cloud DNS, Azure DNS, DigitalOcean, Vultr, and Linode. Subjack matches each by the nameserver hostname patterns in that provider's standard delegations. A delegation pointing to a provider outside that list is not tested for zone presence.

bash
subjack -w subdomains.txt -ns -o results.json

An expired NS domain gives an attacker full DNS control over every record in the zone. The README names the consequences: adding any record type, intercepting email through MX modification, and issuing certificates for subdomains. These outcomes are listed directly in the NS takeover section of the documentation.

Stale A record detection uses ICMP ping and requires root; TCP probes port 80 and 443 as a fallback

With -ar, subjack resolves A records and tests whether each IP is reachable. When a cloud server is terminated but its A record is left in DNS, the IP returns to the provider pool and becomes claimable by a different account on the same provider.

Detection starts with ICMP ping. The README's flag table marks -ar with "(may require root for ICMP)", and without root the tool falls back to a TCP connection on port 80, then 443. A non-responding IP is flagged as STALE A RECORD. The README advises manual verification of all flagged results because a non-responding IP does not confirm the address is reclaimable.

Subjack identifies the cloud provider by IP range when possible and includes the name in the output. Seven providers are in scope: AWS, GCP, Azure, DigitalOcean, Linode, Vultr, and Oracle. The provider identification helps direct the next step toward the right platform for testing whether the address is registrable.

bash
sudo subjack -w subdomains.txt -ar -o results.json

Email-based checks cover SPF include chain expiration and expired MX record targets

The -mail flag activates two checks. For SPF, subjack fetches TXT records and parses any include: directives. Each included domain goes through a registration check; if the domain is expired and available, it is flagged. An attacker who registers an expired SPF include domain can send email that passes SPF and DMARC validation as the target organization.

For MX, subjack checks whether any mail server hostname in the MX records is expired and available. Control over an MX host allows interception of all inbound email, including password resets and two-factor authentication codes.

bash
subjack -w domains.txt -mail -o results.json

The email checks operate on DNS records and do not attempt to send or receive email. Whether a registrable domain translates to actual email interception depends on the registrar and the MX record TTL, neither of which subjack evaluates.

AXFR zone transfers include NS hostname bruteforcing to catch forgotten secondary nameservers

With -axfr, subjack attempts zone transfers against each domain's official nameservers and also sends AXFR queries to a list of bruteforced NS hostnames such as ns1, dns-0, and ns-backup. The README explains the rationale: secondary or forgotten nameservers often retain open transfer permissions even after the primary ones have been secured. By including bruteforced hostnames in the transfer attempt, subjack reaches those hosts without knowing them in advance.

Results are flagged as ZONE TRANSFER and include the vulnerable nameserver hostname and the count of records exposed. Both single-domain and wordlist modes work:

bash
subjack -d example.com -axfr -o results.json
subjack -w domains.txt -axfr -o results.json

The AXFR check generates DNS queries to IP addresses derived from bruteforced hostnames, which may not belong to the target organization. The README does not describe rate-limiting controls specific to the AXFR mode, and the bruteforced queries go to whichever server owns those hostnames, not only the target's registered NS records. The repository was last pushed on 2026-07-03 and carries an Apache-2.0 licence.

Editorial conclusion

Subjack covers nine DNS takeover vectors in a single tool, from basic dangling CNAMEs through SPF include chain expiration and zone-transfer NS bruteforcing that sets it apart from simpler CNAME-only scanners. Bug bounty researchers and infrastructure security teams scanning large subdomain wordlists are the intended audience, and the stdin integration makes it easy to chain with enumeration tools like subfinder. Two things to verify before relying on it: the go.mod specifies go 1.25.1 but the README does not mention a version requirement, so check the installed Go version first. Second, confirm whether the scan scope allows -ar (generates ICMP traffic, requires root) and -axfr (actively probes nameservers beyond the official ones), since both carry higher network noise than the default CNAME checks.

Frequently asked questions

What is subjack used for?

Subjack scans subdomains for DNS takeover vulnerabilities. It checks for dangling CNAMEs, expired NS domains, deleted cloud DNS zones, stale A records, abandoned SPF include and MX record targets, and zone transfer misconfigurations.

How do I install subjack?

The README gives the install command as go install github.com/haccer/subjack@latest. The go.mod file specifies go 1.25.1 as the minimum version, though the README does not mention a version requirement.

What is subdomain takeover and when does it happen?

Subdomain takeover occurs when a subdomain's DNS points to a third-party service or IP address that is no longer claimed, allowing an attacker to register that resource and serve content from the subdomain. Subjack identifies subdomains where this condition exists.

Does subjack need a subdomain list to run?

Yes. Subjack requires a wordlist supplied with -w, a single domain with -d, or domains piped via stdin. It does not enumerate subdomains on its own.

Which DNS takeover checks run automatically and which need a flag?

CNAME takeovers, CNAME chain takeovers up to 10 hops deep, SRV record takeovers, and NXDOMAIN registration checks run on every scan. NS delegation checks (-ns), stale A record detection (-ar), zone transfer attempts (-axfr), and SPF and MX email checks (-mail) all require explicit flags.

Official sources

  1. haccer/subjack on GitHub
  2. Issues
  3. License: Apache-2.0
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/haccer-subjack.svg)](https://hysenlabs.com/projects/haccer-subjack)

Was this useful?