Skip to content

Latest commit

 

History

History
165 lines (122 loc) · 6.37 KB

File metadata and controls

165 lines (122 loc) · 6.37 KB

dnspython

A comprehensive DNS toolkit (dns module) for performing lookups, zone transfers, and record manipulation from Python — the go-to library for DNS reconnaissance.

Overview

dnspython provides both high-level resolver helpers and low-level message construction for every common record type (A, AAAA, MX, NS, TXT, CNAME, SOA, PTR). In offensive work it powers subdomain brute-forcers, mail-security checks (SPF/DMARC), reverse-DNS mapping, and zone-transfer tests. It talks directly to resolvers or authoritative servers, giving precise control over queries during authorized footprinting.

Installation

pip install dnspython

Basic Usage

import dns.resolver

answers = dns.resolver.resolve("example.com", "A")
for record in answers:
    print(record.to_text())

print(answers.rrset.ttl)

resolve() raises rather than returning empty: NXDOMAIN when the name does not exist, NoAnswer when it exists but has no record of that type.

Important APIs

API Purpose
dns.resolver.resolve(name, rdtype) Query a record type
dns.resolver.Resolver() Custom resolver — set .nameservers, .timeout, .lifetime
answers.rrset.ttl TTL of the answer set
record.to_text() Record value as a string
dns.resolver.NXDOMAIN Name does not exist
dns.resolver.NoAnswer Name exists, no record of that type
dns.resolver.Timeout Resolver did not respond
dns.resolver.NoNameservers SERVFAIL from every nameserver
dns.zone.from_xfr(dns.query.xfr(ns, domain)) Attempt an AXFR zone transfer
dns.reversename.from_address(ip) Build a PTR lookup name

Note

The pip package is dnspython; the import name is dns. This mismatch is a frequent source of confusion.

Example

Resolve common record types for a domain:

import dns.resolver

domain = "example.com"
for rtype in ("A", "MX", "NS", "TXT"):
    try:
        answers = dns.resolver.resolve(domain, rtype)
        for r in answers:
            print(f"{rtype:4} {r.to_text()}")
    except dns.resolver.NoAnswer:
        print(f"{rtype:4} (no record)")

Output

A    93.184.216.34
NS   a.iana-servers.net.
NS   b.iana-servers.net.

Subdomain discovery with a wordlist (authorized target):

import dns.resolver

domain = "example.com"
wordlist = ["www", "mail", "dev", "vpn", "admin"]

for sub in wordlist:
    fqdn = f"{sub}.{domain}"
    try:
        answers = dns.resolver.resolve(fqdn, "A")
        print(f"[+] {fqdn} -> {answers[0].to_text()}")
    except (dns.resolver.NXDOMAIN, dns.resolver.NoAnswer):
        pass

Output

[+] www.example.com -> 93.184.216.34

Attempt an AXFR zone transfer against a name server (misconfiguration check):

import dns.query
import dns.zone

ns = "ns1.zonetransfer.me"      # known public test target
domain = "zonetransfer.me"
try:
    zone = dns.zone.from_xfr(dns.query.xfr(ns, domain, timeout=5))
    for name, node in list(zone.nodes.items())[:3]:
        print(name.to_text(), "->", node.to_text(name))
except Exception as exc:
    print("AXFR refused:", exc)

Output

@ -> @ 7200 IN SOA nsztm1.digi.ninja. robin.digi.ninja. ...
info -> info 7200 IN TXT "ZoneTransfer.me service..."

Security Use Cases

  • DNS enumeration — map A/AAAA/MX/NS/TXT records to understand an organization's infrastructure and mail setup.
  • Subdomain brute-forcing — resolve wordlists against a domain to discover hidden hosts and expand attack surface.
  • Zone-transfer testing — check whether name servers wrongly allow AXFR, leaking the entire zone.
  • Mail-security review — parse TXT records for SPF, DKIM, and DMARC policies during a posture assessment.
  • Reverse DNS mapping — resolve PTR records across an in-scope IP range to name hosts.

Common Mistakes

  • Installing the wrong namepip install dnspython, then import dns.
  • Treating NXDOMAIN and NoAnswer as the same — they are different findings: the name does not exist versus the name exists without that record type.
  • Not catching Timeout — a slow or unreachable resolver raises rather than returning nothing.
  • Assuming the system resolver — set Resolver().nameservers explicitly when results must be reproducible.
  • Expecting AXFR to succeed — refusal is correct behaviour; success is a misconfiguration finding.
  • Ignoring TTLs when caching results, producing stale data.
  • Not stripping the trailing dot from to_text() output when comparing names.

Security Considerations

[!warning] Authorized use only Enumerate only domains you own or that are explicitly in scope for a signed engagement.

  • A successful zone transfer is a real finding. AXFR to an arbitrary client exposes the entire internal naming of an organisation. Report it with clear remediation: restrict AXFR to authorised secondaries.
  • Attempting AXFR is more intrusive than a normal query and is logged by the nameserver. Only do it within an authorized engagement.
  • Bulk querying is noisy and rate-limited. Public resolvers throttle or block aggressive clients, which affects everyone sharing your address.
  • DNS answers are untrusted input. A hostile or poisoned resolver can return arbitrary data; validate before using a result in a filesystem path, a shell command, or a connection target.
  • Discovered names are sensitive — an internal hostname inventory is a target list.
  • Prefer DNSSEC-validating resolvers where integrity matters, and note that plain DNS is unauthenticated and observable in transit.

Best Practices

  • Set dns.resolver.Resolver().timeout / lifetime so lookups fail fast in bulk scans.
  • Handle NXDOMAIN, NoAnswer, and Timeout explicitly; they are normal in enumeration loops.
  • Point at a specific resolver (resolver.nameservers = ["1.1.1.1"]) for consistent results.
  • Rate-limit brute-force queries to avoid tripping resolver protections.
  • Only test zone transfers against name servers you are authorized to assess.

References

Related Topics

  • [[Scapy]] — for hand-crafted DNS packets and lower-level control
  • [[requests]] — combine DNS recon with HTTP probing of discovered hosts
  • [[Readme|Python for Security Professionals]] — course home