Convert Figma logo to code with AI

blechschmidt logomassdns

A high-performance DNS stub resolver for bulk lookups and reconnaissance (subdomain enumeration)

3,103
459
3,103
14

Top Related Projects

23,262

TCP port scanner, spews SYN packets asynchronously, scanning entire Internet in under 5 minutes.

2,139

dnsx is a fast and multi-purpose DNS toolkit allow to run multiple DNS queries of your choice with a list of user-supplied resolvers.

10,098

Fast passive subdomain enumeration tool.

11,936

In-depth attack surface mapping and asset discovery

Find domains and subdomains related to a given domain

Quick Overview

massdns is a high-performance DNS resolver library and tool designed for mass DNS lookups. It is written in C and aims to provide fast and efficient DNS resolution capabilities for various use cases, such as security research, domain monitoring, and large-scale network analysis.

Pros

  • High Performance: massdns is capable of performing DNS lookups at a very high rate, making it suitable for large-scale projects that require fast and efficient DNS resolution.
  • Flexibility: The tool supports a wide range of DNS record types and can be customized to suit different use cases.
  • Actively Maintained: The project is actively maintained, with regular updates and bug fixes.
  • Open-Source: massdns is an open-source project, allowing users to contribute, modify, and extend the tool as needed.

Cons

  • Command-Line Interface: The primary interface for massdns is a command-line tool, which may not be as user-friendly as a graphical user interface (GUI) for some users.
  • Limited Documentation: While the project has some documentation, it may not be as comprehensive as some users would prefer, especially for more advanced use cases.
  • Dependency on External Libraries: massdns relies on external libraries, such as libevent, which may introduce additional complexity for some users.
  • Potential Performance Issues: In some cases, the high performance of massdns may come at the cost of increased resource usage, which could be a concern for users with limited system resources.

Code Examples

N/A (massdns is not a code library)

Getting Started

To get started with massdns, follow these steps:

  1. Clone the repository:
git clone https://github.com/blechschmidt/massdns.git
  1. Change to the project directory:
cd massdns
  1. Compile the project:
make
  1. Run massdns with a list of domains:
./bin/massdns -r resolvers.txt -t A -o S -w output.txt domains.txt

This command will perform DNS lookups for the domains listed in the domains.txt file, using the resolvers specified in the resolvers.txt file. The results will be saved to the output.txt file.

For more advanced usage and configuration options, please refer to the project's documentation.

Competitor Comparisons

23,262

TCP port scanner, spews SYN packets asynchronously, scanning entire Internet in under 5 minutes.

Pros of masscan

  • Extremely fast port scanning, capable of scanning the entire Internet in under 6 minutes
  • Supports both TCP and UDP scanning
  • Highly customizable with various output formats and scanning options

Cons of masscan

  • Focused primarily on port scanning, not DNS resolution
  • May generate more network traffic and be more intrusive than massdns
  • Less suitable for targeted DNS-based reconnaissance

Code comparison

massdns:

for (;;) {
    if (ctx->finished) {
        break;
    }
    ssize_t numread = read(ctx->sockfd, ctx->recvbuf, DNS_EDNS0_MAXLEN);
    if (numread <= 0) {
        break;
    }
}

masscan:

for (i=0; i<range->count; i++) {
    struct MassIP ip;
    ip = range->list[i];
    if (ip.begin <= ip.end) {
        while (ip.begin <= ip.end)
            scan_address(ip.begin++);
    }
}

Summary

massdns is specialized for DNS resolution and enumeration, while masscan is a high-speed port scanner. massdns is more focused and less intrusive, making it better suited for DNS-based reconnaissance. masscan offers broader scanning capabilities but may be more noticeable on networks. The choice between them depends on the specific requirements of the task at hand, whether it's DNS enumeration or comprehensive port scanning.

2,139

dnsx is a fast and multi-purpose DNS toolkit allow to run multiple DNS queries of your choice with a list of user-supplied resolvers.

Pros of dnsx

  • Written in Go, offering better cross-platform compatibility
  • Supports multiple output formats (JSON, CSV, etc.)
  • Includes additional features like wildcard detection and DNS record filtering

Cons of dnsx

  • Generally slower performance compared to massdns
  • Less optimized for handling extremely large datasets
  • May consume more system resources due to Go runtime

Code Comparison

massdns:

while ((nread = read(STDIN_FILENO, buffer, sizeof(buffer))) > 0) {
    for (char* line = buffer; line < buffer + nread; line = next) {
        next = memchr(line, '\n', buffer + nread - line);
        if (next == NULL) {
            next = buffer + nread;
        }
        *next++ = '\0';
        resolver_submit(line);
    }
}

dnsx:

func (r *Runner) Process() error {
    r.gologger.Info().Msgf("Starting DNS enumeration for %d domains", len(r.options.Domain))
    for _, domain := range r.options.Domain {
        if err := r.EnumerateSingleDomain(domain); err != nil {
            return err
        }
    }
    return nil
}

Both projects aim to perform DNS enumeration, but their implementations differ significantly. massdns focuses on high-performance C code for processing large datasets, while dnsx offers a more feature-rich Go implementation with better usability and output options.

10,098

Fast passive subdomain enumeration tool.

Pros of subfinder

  • More comprehensive subdomain enumeration using multiple sources and techniques
  • Actively maintained with regular updates and new features
  • Built-in filtering and output options for easier integration into workflows

Cons of subfinder

  • Slower performance compared to massdns for large-scale DNS resolution
  • Higher resource consumption due to its comprehensive approach
  • May require API keys for some sources, potentially limiting free usage

Code comparison

subfinder:

subdomains, err := subfinder.New(config)
results, err := subdomains.Run(context.Background(), "example.com")
for result := range results {
    fmt.Println(result)
}

massdns:

dns_resolver_t *resolver = dns_resolver_new(NULL);
dns_pkt_t *pkt = dns_pkt_new();
dns_question_t *q = dns_question_new_domain(domain, DNS_RR_A, DNS_CLASS_IN);
dns_pkt_set_question(pkt, q);

Summary

subfinder offers a more feature-rich and user-friendly approach to subdomain enumeration, with active development and comprehensive techniques. However, massdns excels in raw DNS resolution performance and efficiency, making it better suited for large-scale operations. The choice between the two depends on specific use cases and requirements, with subfinder being more versatile for general subdomain discovery and massdns being optimal for high-speed DNS resolution tasks.

11,936

In-depth attack surface mapping and asset discovery

Pros of Amass

  • More comprehensive subdomain enumeration with multiple data sources
  • Advanced features like DNS zone transfers and certificate transparency logs
  • Built-in visualization and reporting capabilities

Cons of Amass

  • Slower performance due to its extensive feature set
  • Higher resource consumption, especially for large-scale scans
  • Steeper learning curve with more complex configuration options

Code Comparison

MassDNS (simple DNS resolution):

static int
handle_response(struct context *ctx, ldns_pkt *packet, struct sockaddr_storage *addr)
{
    if (packet == NULL) return 0;
    ldns_rr_list *rrs = ldns_pkt_answer(packet);
    for (int i = 0; i < ldns_rr_list_rr_count(rrs); i++) {
        ldns_rr *rr = ldns_rr_list_rr(rrs, i);
        // Process DNS record
    }
}

Amass (more complex subdomain enumeration):

func (e *Enumeration) submitKnownNames() {
    for _, src := range e.Sys.DataSources() {
        if names, err := src.Domains(); err == nil {
            e.submitNames(names)
        }
    }
    for _, g := range e.Sys.GraphDatabases() {
        if names, err := g.FindNames(); err == nil {
            e.submitNames(names)
        }
    }
}

Find domains and subdomains related to a given domain

Pros of assetfinder

  • Lightweight and easy to use
  • Supports multiple data sources for subdomain discovery
  • Written in Go, making it cross-platform compatible

Cons of assetfinder

  • Limited to subdomain enumeration
  • May not be as fast as massdns for large-scale DNS resolution
  • Less customizable compared to massdns

Code Comparison

assetfinder:

func main() {
    domain := flag.String("d", "", "The domain to find assets for")
    flag.Parse()
    for result := range assetfinder.Run(*domain) {
        fmt.Println(result)
    }
}

massdns:

int main(int argc, char* argv[]) {
    struct config cfg;
    memset(&cfg, 0, sizeof(struct config));
    if (argc < 2) {
        usage();
    }
    // ... (configuration and setup code)
}

Summary

assetfinder is a user-friendly tool focused on subdomain discovery, while massdns is a more powerful and flexible DNS resolution tool. assetfinder is easier to use and supports multiple data sources, but massdns offers better performance for large-scale DNS operations and more customization options. The choice between the two depends on the specific requirements of the task at hand.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

MassDNS

A high-performance DNS stub resolver

MassDNS is a simple high-performance DNS stub resolver targeting those who seek to resolve a massive amount of domain names in the order of millions or even billions. Without special configuration, MassDNS is capable of resolving over 350,000 names per second using publicly available resolvers.

Contributors

Compilation

Clone the git repository and cd into the project root folder. Then run make to build from source. If you are not on Linux, run make nolinux. On Windows, the Cygwin packages gcc-core, git and make are required.

Usage

Usage: ./bin/massdns [options] [domainlist]
  -b  --bindto           Bind to IP address and port. (Default: 0.0.0.0:0)
      --busy-poll        Use busy-wait polling instead of epoll.
  -c  --resolve-count    Number of resolves for a name before giving up. (Default: 50)
      --drop-group       Group to drop privileges to when running as root. (Default: nogroup)
      --drop-user        User to drop privileges to when running as root. (Default: nobody)
      --extended-input   Input names are followed by a space-separated list of resolvers.
                         These are used before falling back to the resolvers file.
      --filter           Only output packets with the specified response code.
      --flush            Flush the output file whenever a response was received.
  -h  --help             Show this help.
      --ignore           Do not output packets with the specified response code.
  -i  --interval         Interval in milliseconds to wait between multiple resolves of the same
                         domain. (Default: 500)
  -l  --error-log        Error log file path. (Default: /dev/stderr)
      --norecurse        Use non-recursive queries. Useful for DNS cache snooping.
  -o  --output           Flags for output formatting.
      --predictable      Use resolvers incrementally. Useful for resolver tests.
      --processes        Number of processes to be used for resolving. (Default: 1)
  -q  --quiet            Quiet mode.
      --rand-src-ipv6    Use a random IPv6 address from the specified subnet for each query.
      --rcvbuf           Size of the receive buffer in bytes.
      --retry            Unacceptable DNS response codes.
                         (Default: All codes but NOERROR or NXDOMAIN)
  -r  --resolvers        Text file containing DNS resolvers.
      --root             Do not drop privileges when running as root. Not recommended.
  -s  --hashmap-size     Number of concurrent lookups. (Default: 10000)
      --sndbuf           Size of the send buffer in bytes.
      --status-format    Format for real-time status updates, json or ansi (Default: ansi)
      --sticky           Do not switch the resolver when retrying.
      --socket-count     Socket count per process. (Default: 1)
  -t  --type             Record type to be resolved. (Default: A)
      --verify-ip        Verify IP addresses of incoming replies.
  -w  --outfile          Write to the specified output file instead of standard output.

Output flags:
  L - domain list output
  S - simple text output
  F - full text output
  B - binary output
  J - ndjson output

Advanced flags for the domain list output mode:
  0 - Include NOERROR replies without answers.

Advanced flags for the simple output mode:
  d - Include records from the additional section.
  i - Indent any reply record.
  l - Separate replies using a line feed.
  m - Only output reply records that match the question name.
  n - Include records from the answer section.
  q - Print the question.
  r - Print the question with resolver IP address, Unix timestamp and return code prepended.
  s - Separate packet sections using a line feed.
  t - Include TTL and record class within the output.
  u - Include records from the authority section.

Advanced flags for the ndjson output mode:
  e - Write a record for each terminal query failure.

For a detailed description of the command line interface, please consult the man page using man ./doc/massdns.1.

Example

Resolve all AAAA records from domains within domains.txt using the resolvers within resolvers.txt in lists and store the results within results.txt:

$ ./bin/massdns -r lists/resolvers.txt -t AAAA domains.txt > results.txt

This is equivalent to:

$ ./bin/massdns -r lists/resolvers.txt -t AAAA -w results.txt domains.txt

Example output

By default, MassDNS will output response packets in text format which looks similar to the following:

;; Server: 77.41.229.2:53
;; Size: 93
;; Unix time: 1513458347
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 51298
;; flags: qr rd ra ; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 0

;; QUESTION SECTION:
example.com. IN A

;; ANSWER SECTION:
example.com. 45929 IN A 93.184.216.34

;; AUTHORITY SECTION:
example.com. 24852 IN NS b.iana-servers.net.
example.com. 24852 IN NS a.iana-servers.net.

The resolver IP address is included in order to make it easier for you to filter the output in case you detect that some resolvers produce bad results.

Resolving

The repository includes the file resolvers.txt consisting of a filtered subset of the resolvers provided by the subbrute project. Please note that the usage of MassDNS may cause a significant load on the used resolvers and result in abuse complaints being sent to your ISP. Also note that the provided resolvers are not guaranteed to be trustworthy. The resolver list is currently outdated with a large share of resolvers being dysfunctional.

MassDNS's custom, malloc-free DNS implementation currently only supports the most common records. You are welcome to help changing this by collaborating.

PTR records

MassDNS includes a Python script allowing you to resolve all IPv4 PTR records by printing their respective queries to the standard output.

$ ./scripts/ptr.py | ./bin/massdns -r lists/resolvers.txt -t PTR -w ptr.txt

Please note that the labels within in-addr.arpa are reversed. In order to resolve the domain name of 1.2.3.4, MassDNS expects 4.3.2.1.in-addr.arpa as input query name. As a consequence, the Python script does not resolve the records in an ascending order which is an advantage because sudden heavy spikes at the name servers of IPv4 subnets are avoided.

Reconnaissance by brute-forcing subdomains

Perform reconnaissance scans responsibly and adjust the -s parameter to not overwhelm authoritative name servers.

Similar to subbrute, MassDNS allows you to brute force subdomains using the included subbrute.py script:

$ ./scripts/subbrute.py example.com lists/names.txt | ./bin/massdns -r lists/resolvers.txt -t A -o S -w results.txt

As an additional method of reconnaissance, the ct.py script extracts subdomains from certificate transparency logs by scraping the data from crt.sh:

$ ./scripts/ct.py example.com | ./bin/massdns -r lists/resolvers.txt -t A -o S -w results.txt

The files names.txt and names_small.txt, which have been copied from the subbrute project, contain names of commonly used subdomains. Also consider using Jason Haddix' subdomain compilation with over 1,000,000 names or the Assetnote wordlist with over 9,000,000 million names.

MassDNS also includes a recon.py wrapper script (beta status) in the scripts folder, which performs subdomain enumeration against authoritative name servers directly and thus does not require third-party resolvers. The concurrency is determined automatically by MassDNS and supports hundreds of thousands of queries per second, while delivering reliable results. On a cheap dedicated server, the Assetnode wordlist can be enumerated in less than a minute. A current limitation is that zone delegation is only handled up to the delegation point. For example, if example.org is enumerated and sub.example.org is delegated to another name server, abc.sub.example.org will not be found by this script if abc.sub is contained in the word list. However, the script will report this fact as ?.sub.example.org in this case.

$ ./scripts/recon.py -d google.com -l lists/best-dns-wordlist.txt > google.txt

Screenshots

Screenshot

Security

MassDNS does not require root privileges and will therefore drop privileges to the user called "nobody" by default when being run as root. If the user "nobody" does not exist, MassDNS will refuse execution. In this case, it is recommended to run MassDNS as another non-privileged user. The privilege drop can be circumvented using the --root argument which is not recommended. Also note that other branches than master should not be used in production at all.

Practical considerations

Performance tuning

MassDNS is a simple single-threaded application designed for scenarios in which the network is the bottleneck. It is designed to be run on servers with high upload and download bandwidths. Internally, MassDNS makes use of a hash map which controls the concurrency of lookups. Setting the size parameter -s hence allows you to control the lookup rate. If you are experiencing performance issues, try adjusting the -s parameter in order to obtain a better success rate.

Rate limiting evasion

In case rate limiting by IPv6 resolvers is a problem, you can make use of --rand-src-ipv6 <your_ipv6_prefix>. MassDNS will then use a raw socket for sending and receiving DNS packets and randomly pick a source IPv6 address from the specified prefix for each query. This requires that MassDNS is run with CAP_NET_RAW privileges. When making use of this method, you should have iptables or nftables drop the DNS traffic received by MassDNS such that no ICMP Port unreachable responses are generated by the operating system, e.g. using ip6tables -p udp --sport 53 -I INPUT -j DROP. Note that this rule is just examplary and would drop all DNS traffic, including traffic for other applications. You might want to adapt the rule to be more fine-grained to fit your use case.

Result authenticity

If the authenticity of results is highly essential, you should not rely on the included resolver list. Instead, set up a local unbound resolver and supply MassDNS with its IP address. In case you are using MassDNS as a reconnaissance tool, you may wish to run it with the default resolver list first and re-run it on the found names with a list of trusted resolvers in order to eliminate false positives.

In case you are enumerating subdomains for a single name, e.g. for example.com, you may want to simply leave out third-party resolvers. In this case, you can directly probe the authoritative nameservers like so:

$ ./bin/massdns -r <(./scripts/auth-addrs.sh example.com) --norecurse -o Je example-com-subdomains.txt > results.txt

Todo

  • Prevent flooding resolvers which are employing rate limits or refusing resolves after some time
  • Implement bandwidth limits
  • Employ cross-resolver checks to detect DNS poisoning and DNS spam (e.g. Level 3 DNS hijacking)
  • Add wildcard detection for reconnaissance
  • Improve reconnaissance reliability by adding a mode which re-resolves found domains through a list of trusted (local) resolvers in order to eliminate false positives
  • Detect optimal concurrency automatically
  • Parse the command line properly and allow the usage/combination of short options without spaces