Convert Figma logo to code with AI

projectdiscovery logodnsx

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.

2,139
238
2,139
9

Top Related Projects

Find domains and subdomains related to a given domain

11,936

In-depth attack surface mapping and asset discovery

3,103

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

The fastest and complete solution for domain recognition. Supports screenshoting, port scan, HTTP check, data import from other tools, subdomain monitoring, alerts via Discord, Slack and Telegram, multiple API Keys for sources and much more.

🔍 gowitness - a golang, web screenshot utility using Chrome Headless

Fast passive subdomain enumeration tool.

Quick Overview

dnsx is a fast and multi-purpose DNS toolkit designed for running DNS queries. It allows for multiple DNS record types, supports wildcard expansion, and can handle large-scale DNS enumeration tasks efficiently. The tool is particularly useful for security researchers and network administrators.

Pros

  • High-speed performance with concurrent DNS lookups
  • Supports multiple DNS record types (A, AAAA, CNAME, MX, NS, TXT, etc.)
  • Offers wildcard domain expansion capabilities
  • Provides flexible output formats (JSON, CSV, etc.)

Cons

  • Limited built-in DNS analysis features compared to more specialized tools
  • May require additional tools for comprehensive DNS security assessments
  • Documentation could be more extensive for advanced use cases
  • Might be overkill for simple DNS query needs

Getting Started

To install dnsx, you can use Go:

go install -v github.com/projectdiscovery/dnsx/cmd/dnsx@latest

Or download a pre-built binary from the releases page.

Basic usage:

dnsx -l domains.txt -A -AAAA -CNAME -MX -NS -TXT -resp

This command will perform DNS lookups for domains listed in domains.txt, querying for A, AAAA, CNAME, MX, NS, and TXT records, and display the responses.

For wildcard expansion:

dnsx -d example.com -w

This will expand and resolve wildcard subdomains for example.com.

To output results in JSON format:

dnsx -l domains.txt -json -o results.json

This will perform DNS lookups on the domains in domains.txt and save the results in JSON format to results.json.

Competitor Comparisons

Find domains and subdomains related to a given domain

Pros of assetfinder

  • Lightweight and fast execution
  • Simple to use with minimal configuration
  • Supports multiple sources for subdomain discovery

Cons of assetfinder

  • Limited to subdomain enumeration only
  • Less actively maintained compared to dnsx
  • Fewer advanced features and customization options

Code Comparison

assetfinder:

func main() {
    sources := []Source{
        &Crtsh{},
        &Hackertraget{},
        &Threatcrowd{},
        &Certspotter{},
        &Findsubdomains{},
    }
    // ... (code to process sources)
}

dnsx:

func main() {
    options := &runner.Options{}
    flagSet := goflags.NewFlagSet()
    flagSet.SetDescription(`dnsx is a fast and multi-purpose DNS toolkit allow to run multiple DNS queries`)
    // ... (code to set up options and run DNS queries)
}

The code snippets show that assetfinder focuses on combining multiple sources for subdomain discovery, while dnsx is designed as a more comprehensive DNS toolkit with various query options.

assetfinder is simpler and more focused on subdomain enumeration, making it easier to use for specific tasks. dnsx, on the other hand, offers a wider range of DNS-related functionalities, including reverse DNS, DNS resolution, and wildcard detection, making it more versatile for various DNS operations.

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
  • Visualization capabilities for discovered assets

Cons of Amass

  • Steeper learning curve due to more complex functionality
  • Slower execution compared to dnsx for simple DNS lookups
  • Higher resource consumption for extensive scans

Code Comparison

Amass (basic enumeration):

amass enum -d example.com

dnsx (basic DNS lookup):

echo "example.com" | dnsx -a -aaaa -cname -mx -ns -txt

Amass offers more advanced options for in-depth enumeration, while dnsx provides a simpler interface for quick DNS lookups. Amass is better suited for comprehensive asset discovery, whereas dnsx excels in rapid DNS resolution and information gathering.

Amass is designed for thorough subdomain enumeration and asset mapping, making it ideal for larger-scale reconnaissance. dnsx, on the other hand, focuses on fast and efficient DNS queries, making it more suitable for quick checks and integration into automated workflows.

Choose Amass for extensive reconnaissance and asset discovery projects, and opt for dnsx when you need quick, targeted DNS lookups or want to integrate DNS functionality into your existing tools and scripts.

3,103

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

Pros of massdns

  • Higher performance and faster DNS resolution capabilities
  • More flexible configuration options for advanced users
  • Better suited for large-scale DNS enumeration tasks

Cons of massdns

  • Steeper learning curve and more complex setup
  • Less user-friendly for beginners or quick tasks
  • Requires more manual configuration for optimal performance

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_queue_push(line);
    }
}

dnsx:

func (r *Runner) Process() error {
    r.gologger.Info().Msgf("Starting DNS enumeration for %d domains", r.options.InputCount)
    defer close(r.output)

    for domain := range r.input {
        if r.options.Retries > 0 {
            domain = strings.TrimSpace(domain)
            if domain == "" {
                continue
            }
            r.processWithRetry(domain)
        } else {
            r.processHost(domain)
        }
    }
    return nil
}

Both projects focus on DNS resolution, but massdns is written in C for performance, while dnsx is written in Go for ease of use and cross-platform compatibility.

The fastest and complete solution for domain recognition. Supports screenshoting, port scan, HTTP check, data import from other tools, subdomain monitoring, alerts via Discord, Slack and Telegram, multiple API Keys for sources and much more.

Pros of Findomain

  • Supports multiple data sources for subdomain enumeration
  • Offers a user-friendly CLI interface with various output options
  • Includes built-in DNS resolution and port scanning capabilities

Cons of Findomain

  • Written in Rust, which may have a steeper learning curve for contributors
  • Requires API keys for some data sources, potentially limiting free usage
  • May be slower for large-scale scans compared to dnsx

Code Comparison

Findomain (Rust):

let subdomains = find_subdomains(&args.target, &args.wordlist);
for subdomain in subdomains {
    println!("Found: {}", subdomain);
}

dnsx (Go):

options := dnsx.DefaultOptions
dnsx.NewRunner(&options)
for result := range runner.Run() {
    fmt.Printf("A: %s\n", result.A)
}

Key Differences

  • Findomain focuses on comprehensive subdomain enumeration from various sources
  • dnsx specializes in fast DNS lookups and resolution
  • Findomain offers more features out-of-the-box, while dnsx is more lightweight and focused
  • dnsx is part of the larger projectdiscovery ecosystem, potentially offering better integration with other tools

Both tools serve different purposes within the domain enumeration and DNS resolution space, with Findomain being more feature-rich for subdomain discovery and dnsx excelling in fast DNS lookups and integration with other projectdiscovery tools.

🔍 gowitness - a golang, web screenshot utility using Chrome Headless

Pros of gowitness

  • Captures screenshots of web pages, providing visual evidence
  • Supports multiple output formats (HTML, JSON, SQLite)
  • Includes a web server for easy viewing of captured screenshots

Cons of gowitness

  • Limited to web-based reconnaissance
  • Requires more system resources due to browser rendering
  • May be slower for large-scale scanning compared to DNS-focused tools

Code comparison

gowitness:

cmd := &cobra.Command{
    Use:   "gowitness",
    Short: "A golang, web screenshot utility using Chrome Headless",
    Long:  `A golang, web screenshot utility using Chrome Headless`,
}

dnsx:

var options = &runner.Options{}

flagSet := goflags.NewFlagSet()
flagSet.SetDescription(`Fast and multi-purpose DNS toolkit`)

Key differences

  • Purpose: gowitness focuses on web page screenshots, while dnsx is a DNS toolkit
  • Functionality: gowitness provides visual reconnaissance, dnsx offers DNS enumeration and analysis
  • Performance: dnsx is likely faster for large-scale DNS operations
  • Use cases: gowitness is ideal for web application testing, dnsx for network and infrastructure analysis

Both tools serve different purposes in the cybersecurity toolkit, with gowitness excelling in visual web reconnaissance and dnsx in DNS-related tasks.

Fast passive subdomain enumeration tool.

Pros of subfinder

  • Broader subdomain discovery capabilities, utilizing multiple sources
  • Supports active and passive enumeration techniques
  • More extensive configuration options for customized searches

Cons of subfinder

  • Potentially slower due to querying multiple sources
  • May require API keys for some sources, limiting free usage

Code comparison

subfinder:

func (a *Agent) EnumerateSubdomains(domain string, config *Config) ([]string, error) {
    var subdomains []string
    for _, source := range config.Sources {
        results, err := source.Run(domain, config)
        if err != nil {
            return nil, err
        }
        subdomains = append(subdomains, results...)
    }
    return subdomains, nil
}

dnsx:

func (r *Runner) DNSLookup(domain string) ([]string, error) {
    var results []string
    ips, err := net.LookupIP(domain)
    if err != nil {
        return nil, err
    }
    for _, ip := range ips {
        results = append(results, ip.String())
    }
    return results, nil
}

Summary

subfinder is a more comprehensive tool for subdomain enumeration, offering a wider range of sources and techniques. It's ideal for thorough reconnaissance but may be slower and require API keys. dnsx, on the other hand, focuses on fast DNS lookups and resolution, making it more suitable for quick DNS-related tasks and integration into other workflows.

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

dnsx

A fast and multi-purpose DNS toolkit designed for running DNS queries

Features • Installation • Usage • Running `dnsx` • Wildcard • Notes • Join Discord


dnsx is a fast and multi-purpose DNS toolkit designed for running various probes through the retryabledns library. It supports multiple DNS queries, user supplied resolvers, DNS wildcard filtering like shuffledns etc.

Features

dnsx

  • Simple and Handy utility to query DNS records.
  • A, AAAA, CNAME, PTR, NS, MX, TXT, SRV, SOA query support
  • DNS Resolution / Brute-force support
  • Custom resolver input support
  • Multiple resolver format (TCP/UDP/DOH/DOT) support
  • stdin and stdout support
  • Automatic wildcard handling support

Installation Instructions

dnsx requires go1.21 to install successfully. Run the following command to install the latest version:

go install -v github.com/projectdiscovery/dnsx/cmd/dnsx@latest

Usage

dnsx -h

This will display help for the tool. Here are all the switches it supports.

INPUT:
   -l, -list string      list of sub(domains)/hosts to resolve (file or stdin)
   -d, -domain string    list of domain to bruteforce (file or comma separated or stdin)
   -w, -wordlist string  list of words to bruteforce (file or comma separated or stdin)

QUERY:
   -a                       query A record (default)
   -aaaa                    query AAAA record
   -cname                   query CNAME record
   -ns                      query NS record
   -txt                     query TXT record
   -srv                     query SRV record
   -ptr                     query PTR record
   -mx                      query MX record
   -soa                     query SOA record
   -any                     query ANY record
   -axfr                    query AXFR
   -caa                     query CAA record
   -recon                   query all the dns records (a,aaaa,cname,ns,txt,srv,ptr,mx,soa,axfr,caa)
   -e, -exclude-type value  dns query type to exclude (a,aaaa,cname,ns,txt,srv,ptr,mx,soa,axfr,caa) (default none)

FILTER:
   -re, -resp          display dns response
   -ro, -resp-only     display dns response only
   -rc, -rcode string  filter result by dns status code (eg. -rcode noerror,servfail,refused)

PROBE:
   -cdn  display cdn name
   -asn  display host asn information

RATE-LIMIT:
   -t, -threads int      number of concurrent threads to use (default 100)
   -rl, -rate-limit int  number of dns request/second to make (disabled as default) (default -1)

UPDATE:
   -up, -update                 update dnsx to latest version
   -duc, -disable-update-check  disable automatic dnsx update check

OUTPUT:
   -o, -output string  file to write output
   -j, -json           write output in JSONL(ines) format
   -omit-raw, -or      omit raw dns response from jsonl output

DEBUG:
   -hc, -health-check  run diagnostic check up
   -silent             display only results in the output
   -v, -verbose        display verbose output
   -raw, -debug        display raw dns response
   -stats              display stats of the running scan
   -version            display version of dnsx
   -nc, -no-color      disable color in output

OPTIMIZATION:
   -retry int                number of dns attempts to make (must be at least 1) (default 2)
   -hf, -hostsfile           use system host file
   -trace                    perform dns tracing
   -trace-max-recursion int  Max recursion for dns trace (default 32767)
   -resume                   resume existing scan
   -stream                   stream mode (wordlist, wildcard, stats and stop/resume will be disabled)

CONFIGURATIONS:
   -auth                         configure projectdiscovery cloud (pdcp) api key (default true)
   -r, -resolver string          list of resolvers to use (file or comma separated)
   -wt, -wildcard-threshold int  wildcard filter threshold (default 5)
   -wd, -wildcard-domain string  domain name for wildcard filtering (other flags will be ignored - only json output is supported)

Running dnsx

DNS Resolving

Filter active hostnames from the list of passive subdomains, obtained from various sources:

subfinder -silent -d hackerone.com | dnsx -silent

a.ns.hackerone.com
www.hackerone.com
api.hackerone.com
docs.hackerone.com
mta-sts.managed.hackerone.com
mta-sts.hackerone.com
resources.hackerone.com
b.ns.hackerone.com
mta-sts.forwarding.hackerone.com
events.hackerone.com
support.hackerone.com

Print A records for the given list of subdomains:

subfinder -silent -d hackerone.com | dnsx -silent -a -resp

www.hackerone.com [104.16.100.52]
www.hackerone.com [104.16.99.52]
hackerone.com [104.16.99.52]
hackerone.com [104.16.100.52]
api.hackerone.com [104.16.99.52]
api.hackerone.com [104.16.100.52]
mta-sts.forwarding.hackerone.com [185.199.108.153]
mta-sts.forwarding.hackerone.com [185.199.109.153]
mta-sts.forwarding.hackerone.com [185.199.110.153]
mta-sts.forwarding.hackerone.com [185.199.111.153]
a.ns.hackerone.com [162.159.0.31]
resources.hackerone.com [52.60.160.16]
resources.hackerone.com [3.98.63.202]
resources.hackerone.com [52.60.165.183]
resources.hackerone.com [read.uberflip.com]
mta-sts.hackerone.com [185.199.110.153]
mta-sts.hackerone.com [185.199.111.153]
mta-sts.hackerone.com [185.199.109.153]
mta-sts.hackerone.com [185.199.108.153]
gslink.hackerone.com [13.35.210.17]
gslink.hackerone.com [13.35.210.38]
gslink.hackerone.com [13.35.210.83]
gslink.hackerone.com [13.35.210.19]
b.ns.hackerone.com [162.159.1.31]
docs.hackerone.com [185.199.109.153]
docs.hackerone.com [185.199.110.153]
docs.hackerone.com [185.199.111.153]
docs.hackerone.com [185.199.108.153]
support.hackerone.com [104.16.51.111]
support.hackerone.com [104.16.53.111]
mta-sts.managed.hackerone.com [185.199.108.153]
mta-sts.managed.hackerone.com [185.199.109.153]
mta-sts.managed.hackerone.com [185.199.110.153]
mta-sts.managed.hackerone.com [185.199.111.153]

Extract A records for the given list of subdomains:

subfinder -silent -d hackerone.com | dnsx -silent -a -resp-only

104.16.99.52
104.16.100.52
162.159.1.31
104.16.99.52
104.16.100.52
185.199.110.153
185.199.111.153
185.199.108.153
185.199.109.153
104.16.99.52
104.16.100.52
104.16.51.111
104.16.53.111
185.199.108.153
185.199.111.153
185.199.110.153
185.199.111.153

Extract CNAME records for the given list of subdomains:

subfinder -silent -d hackerone.com | dnsx -silent -cname -resp

support.hackerone.com [hackerone.zendesk.com]
resources.hackerone.com [read.uberflip.com]
mta-sts.hackerone.com [hacker0x01.github.io]
mta-sts.forwarding.hackerone.com [hacker0x01.github.io]
events.hackerone.com [whitelabel.bigmarker.com]

Extract ASN records for the given list of subdomains:

subfinder -silent -d hackerone.com | dnsx -silent  -asn

b.ns.hackerone.com [AS13335, CLOUDFLARENET, US]
a.ns.hackerone.com [AS13335, CLOUDFLARENET, US]
hackerone.com [AS13335, CLOUDFLARENET, US]
www.hackerone.com [AS13335, CLOUDFLARENET, US]
api.hackerone.com [AS13335, CLOUDFLARENET, US]
support.hackerone.com [AS13335, CLOUDFLARENET, US]

Probe using dns status code on given list of (sub)domains:

subfinder -silent -d hackerone.com | dnsx -silent -rcode noerror,servfail,refused

ns.hackerone.com [NOERROR]
a.ns.hackerone.com [NOERROR]
b.ns.hackerone.com [NOERROR]
support.hackerone.com [NOERROR]
resources.hackerone.com [NOERROR]
mta-sts.hackerone.com [NOERROR]
www.hackerone.com [NOERROR]
mta-sts.forwarding.hackerone.com [NOERROR]
docs.hackerone.com [NOERROR]

Extract subdomains from given network range using PTR query:

echo 173.0.84.0/24 | dnsx -silent -resp-only -ptr

cors.api.paypal.com
trinityadminauth.paypal.com
cld-edge-origin-api.paypal.com
appmanagement.paypal.com
svcs.paypal.com
trinitypie-serv.paypal.com
ppn.paypal.com
pointofsale-new.paypal.com
pointofsale.paypal.com
slc-a-origin-pointofsale.paypal.com
fpdbs.paypal.com

Extract subdomains from given ASN using PTR query:

echo AS17012 | dnsx -silent -resp-only -ptr 

apiagw-a.paypal.com
notify.paypal.com
adnormserv-slc-a.paypal.com
a.sandbox.paypal.com
apps2.paypal-labs.com
pilot-payflowpro.paypal.com
www.paypallabs.com
paypal-portal.com
micropayments.paypal-labs.com
minicart.paypal-labs.com

DNS Bruteforce

Bruteforce subdomains for given domain or list of domains using d and w flag:

dnsx -silent -d facebook.com -w dns_worldlist.txt

blog.facebook.com
booking.facebook.com
api.facebook.com
analytics.facebook.com
beta.facebook.com
apollo.facebook.com
ads.facebook.com
box.facebook.com
alpha.facebook.com
apps.facebook.com
connect.facebook.com
c.facebook.com
careers.facebook.com
code.facebook.com

Bruteforce targeted subdomain using single or multiple keyword input, as d or w flag supports file or comma separated keyword inputs:

dnsx -silent -d domains.txt -w jira,grafana,jenkins

grafana.1688.com
grafana.8x8.vc
grafana.airmap.com
grafana.aerius.nl
jenkins.1688.com
jenkins.airbnb.app
jenkins.airmap.com
jenkins.ahn.nl
jenkins.achmea.nl
jira.amocrm.com
jira.amexgbt.com
jira.amitree.com
jira.arrival.com
jira.atlassian.net
jira.atlassian.com

Values are accepted from stdin for all the input types (-list, -domain, -wordlist). The -list flag defaults to stdin, but the same can be achieved for other input types by adding a - (dash) as parameter:

cat domains.txt | dnsx -silent -w jira,grafana,jenkins -d -

grafana.1688.com
grafana.8x8.vc
grafana.airmap.com
grafana.aerius.nl
jenkins.1688.com
jenkins.airbnb.app
jenkins.airmap.com
jenkins.ahn.nl
jenkins.achmea.nl
jira.amocrm.com
jira.amexgbt.com
jira.amitree.com
jira.arrival.com
jira.atlassian.net
jira.atlassian.com

DNS Bruteforce with Placeholder based wordlist

$ cat tld.txt

com
by
de
be
al
bi
cg
dj
bs
dnsx -d google.FUZZ -w tld.txt -resp

      _             __  __
   __| | _ __   ___ \ \/ /
  / _' || '_ \ / __| \  / 
 | (_| || | | |\__ \ /  \ 
  \__,_||_| |_||___//_/\_\ v1.1.2

      projectdiscovery.io

google.de [142.250.194.99] 
google.com [142.250.76.206] 
google.be [172.217.27.163] 
google.bs [142.251.42.35] 
google.bi [216.58.196.67] 
google.al [216.58.196.68] 
google.by [142.250.195.4] 
google.cg [142.250.183.131] 
google.dj [142.250.192.3] 

Wildcard filtering

A special feature of dnsx is its ability to handle multi-level DNS based wildcards, and do it so with a very reduced number of DNS requests. Sometimes all the subdomains will resolve, which leads to lots of garbage in the output. The way dnsx handles this is by keeping track of how many subdomains point to an IP and if the count of the subdomains increase beyond a certain threshold, it will check for wildcards on all the levels of the hosts for that IP iteratively.

dnsx -l subdomain_list.txt -wd airbnb.com -o output.txt

Dnsx as a library

It's possible to use the library directly in your golang programs. The following code snippets is an example of use in golang programs. Please refer to here for detailed package configuration and usage.

package main

import (
	"fmt"

	"github.com/projectdiscovery/dnsx/libs/dnsx"
)

func main() {
	// Create DNS Resolver with default options
	dnsClient, err := dnsx.New(dnsx.DefaultOptions)
	if err != nil {
		fmt.Printf("err: %v\n", err)
		return
	}

	// DNS A question and returns corresponding IPs
	result, err := dnsClient.Lookup("hackerone.com")
	if err != nil {
		fmt.Printf("err: %v\n", err)
		return
	}
	for idx, msg := range result {
		fmt.Printf("%d: %s\n", idx+1, msg)
	}

	// Query
	rawResp, err := dnsClient.QueryOne("hackerone.com")
	if err != nil {
		fmt.Printf("err: %v\n", err)
		return
	}
	fmt.Printf("rawResp: %v\n", rawResp)

	jsonStr, err := rawResp.JSON()
	if err != nil {
		fmt.Printf("err: %v\n", err)
		return
	}
	fmt.Println(jsonStr)

	return
}

📋 Notes

  • As default, dnsx checks for A record.
  • As default dnsx uses Google, Cloudflare, Quad9 resolver.
  • Custom resolver list can be loaded using the r flag.
  • Domain name (wd) input is mandatory for wildcard elimination.
  • DNS record flag can not be used when using wildcard filtering.
  • DNS resolution (l) and DNS brute-forcing (w) can't be used together.
  • VPN operators tend to filter high DNS/UDP traffic, therefore the tool might experience packets loss (eg. Mullvad VPN). Check this potential solution.

dnsx is made with 🖤 by the projectdiscovery team.