Patator DNS_forward and DNS_reverse Modules for Subdomain Enumeration

The dns_forward and dns_reverse modules in Patator enable high-speed subdomain enumeration and reverse DNS sweeping by leveraging the Controller_DNS class to resolve domain names to IPs and PTR records to hostnames, storing results in structured records and hostmap dictionaries for comprehensive DNS reconnaissance.

Patator provides specialized DNS reconnaissance capabilities through its dns_forward and dns_reverse modules, designed for security professionals performing subdomain enumeration and network mapping. These modules, built on top of the dnspython library and unified under the Controller_DNS infrastructure in src/patator/patator.py, allow for efficient brute-forcing of subdomains and reverse DNS lookups across IP ranges while maintaining detailed records of all DNS responses.

DNS Module Architecture and Core Implementation

Both DNS modules share the same controller infrastructure, Controller_DNS, which manages the state of DNS queries and aggregates results during enumeration tasks.

Controller_DNS State Management

The controller maintains two critical data structures while scanning:

  • records – A defaultdict(list) storing the full list of raw DNS records per name (line 38)
  • hostmap – A defaultdict(HostInfo) providing a simplified view linking hostnames to IPs and CNAME aliases (line 39)

When a module returns a response, the push_final method (starting at line 64) processes each answer record (rr) and updates these structures:

def push_final(self, resp):
    if hasattr(resp, 'rrs'):
        for rr in resp.rrs:
            name, qclass, qtype, data = rr
            info = (qclass, qtype, data)
            if info not in self.records[name]:
                self.records[name].append(info)

            if qclass == 'IN':
                if qtype == 'PTR':
                    data = data[:-1]
                    self.hostmap[data].ip.add(name)
                else:
                    if qtype in ('A', 'AAAA'):
                        name = name[:-1]
                        self.hostmap[name].ip.add(data)
                    elif qtype == 'CNAME':
                        name, data = name[:-1], data[:-1]
                        self.hostmap[data].alias.add(name)

This implementation allows Patator to distinguish between forward lookups (A/AAAA records) and reverse lookups (PTR records) while building a comprehensive map of the target infrastructure.

DNS_forward Module Implementation Details

The dns_forward module, defined at line 4018 in src/patator/patator.py, performs forward DNS resolution for subdomain enumeration.

Configuration Options

The module accepts the following parameters (lines 27-33):

  • name – The domain name to resolve (supports placeholders like FILE0, MOD0)
  • server – Target DNS server IP address
  • timeout – Query timeout in seconds
  • protocol – Transport protocol (UDP or TCP)
  • qtype – Query type (A, AAAA, CNAME, SRV, etc.)
  • qclass – Query class (typically IN for Internet)

Dynamic Key Generators

Patator injects two special generators via available_keys (lines 37-40) to facilitate comprehensive enumeration:

  • TLD – Full list of top-level domains for TLD enumeration
  • SRV – Common service records for service discovery

Execution Flow

The module builds a DNS query using the dns_query function and parses all answer sections (answer, additional, and authority). Raw answer rows are stored in resp.rrs (lines 53-58), enabling detailed post-processing of DNS responses.

DNS_reverse Module Implementation Details

The dns_reverse module, defined at line 3982, performs PTR lookups for reverse DNS enumeration.

Configuration Options

This module uses a streamlined parameter set (lines 90-94):

  • host – IP address or range to resolve (supports NET0 for CIDR notation)
  • server – Target DNS server
  • timeout – Query timeout
  • protocol – Transport protocol

PTR Resolution Process

The module uses dns.reversename.from_address(host) to convert each IP address to its corresponding PTR name format, then executes dns_query with qtype='PTR'. Returned PTR records are stored as [host, class, type, data] tuples (lines 9-12), allowing the controller to map IP addresses back to their canonical hostnames.

Practical Use Cases for Subdomain Enumeration

Subdomain Brute-forcing with dns_forward

Feed a wordlist of potential subdomains to identify valid hosts:

patator dns_forward \
    name=FILE0.example.com \
    0=subdomains.txt \
    server=8.8.8.8 \
    -x ignore:code=3

The FILE0 placeholder expands each line of subdomains.txt into the query, while -x ignore:code=3 filters out NXDOMAIN responses (RCODE 3).

Top-Level Domain Enumeration

Enumerate all TLD variants of a domain name:

patator dns_forward \
    name=google.MOD0 \
    0=TLD \
    server=1.1.1.1 \
    -x ignore:code=3

The MOD0 placeholder iterates through the dynamically generated list of all known TLDs.

Service Record Discovery

Locate specific services across domains using SRV records:

patator dns_forward \
    name=_ldap._tcp.MOD0 \
    0=SRV \
    server=8.8.4.4 \
    qtype=SRV \
    -x ignore:code=3

Network Reconnaissance with dns_reverse

Map IP ranges back to hostnames for internal network validation:

patator dns_reverse \
    host=NET0 \
    0=192.168.1.0/24 \
    server=10.10.0.53 \
    -x ignore:code=3

The NET0 placeholder expands the CIDR range, issuing PTR queries for every address in the subnet.

Summary

  • Controller_DNS provides unified state management through records and hostmap dictionaries that aggregate raw DNS responses and simplified host-to-IP mappings
  • dns_forward (line 4018) enables forward resolution with support for dynamic TLD and SRV generation, making it ideal for subdomain brute-forcing and service discovery
  • dns_reverse (line 3982) performs PTR lookups using dns.reversename.from_address(), essential for mapping IP ranges back to hostnames
  • Both modules support standard Patator placeholders (FILE0, NET0, MOD0) and filter options (-x ignore:code=3) to eliminate NXDOMAIN noise
  • The implementation in src/patator/patator.py uses dnspython for transport-agnostic DNS queries (UDP/TCP) with configurable timeouts

Frequently Asked Questions

How does Patator handle NXDOMAIN responses during subdomain enumeration?

Patator uses the -x ignore:code=3 command-line option to filter out DNS responses with RCODE 3 (NXDOMAIN), which indicates that a queried domain does not exist. This prevents noise from invalid subdomains while allowing valid responses (RCODE 0) to populate the records and hostmap structures.

What is the difference between the records and hostmap dictionaries in Controller_DNS?

The records dictionary stores the complete raw DNS answer data as tuples of (qclass, qtype, data) for each queried name, preserving all response details. The hostmap dictionary provides a processed view using HostInfo objects that consolidate IP addresses and CNAME aliases for each hostname, making it easier to analyze relationships between hosts and their resolved addresses.

Can Patator perform both forward and reverse DNS lookups simultaneously?

While dns_forward and dns_reverse are separate modules that require individual command invocations, you can pipeline their operations by first running a forward enumeration to discover IPs, then feeding those IPs into a reverse lookup. The hostmap structure from forward lookups can help identify which IP ranges warrant reverse enumeration.

What DNS query types are supported by the dns_forward module?

The dns_forward module supports any DNS query type specified via the qtype parameter, including standard records like A, AAAA, CNAME, MX, and NS, as well as service-specific records like SRV. The module passes the qtype directly to the underlying dns_query function, making it compatible with any record type supported by the target DNS server.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →