June 24, 2026
I Ran One Command and Found 847 Subdomains in 3 Minutes. Here is How Subfinder Actually Works.
The Story That Changed How I Do Recon

By Yamini Yadav_369
12 min read
I was on my third hour of manual subdomain enumeration. I had Google dorked the target, checked certificate transparency logs manually on crt.sh, and built a wordlist for brute forcing. I had maybe 60 subdomains written down in a text file. My hands were tired, and I knew I was still missing things.
A colleague sat down next to me, opened a terminal, typed one command, and walked away to get coffee.
When he came back three minutes later, his screen had 847 subdomains listed. Clean, formatted, ready to pipe into the next tool.
He was using Subfinder.
That day, I stopped treating recon as a manual task and started treating it as an automated intelligence gathering phase. This blog is everything I learned about Subfinder since that day. We will cover what it is, how it actually works under the hood, every important command with a real explanation, and how to use it the way professionals do in bug bounty and pentesting.
What is Subfinder and Why Should You Care
Subfinder is a passive subdomain discovery tool built by ProjectDiscovery, the same team behind Nuclei, httpx, and many other tools in the modern security stack. It is written in Go, which makes it extremely fast and easy to install across platforms.
The word passive here is important. Subfinder does not send any requests directly to the target's servers. It does not brute force, it does not make noise on the target network, and it does not trigger any WAF or IDS. Instead, it queries external data sources that have already collected subdomain information over time.
These data sources include certificate transparency logs, DNS datasets, search engines, threat intelligence platforms, and passive DNS databases. Subfinder reaches out to all of these simultaneously and pulls back any subdomain they have on record for your target domain.
This is why it is so fast and so silent. The target never knows you looked.
How Subfinder Works Internally
Understanding the internal mechanism helps you use it better and debug it when the results look thin.
When you run Subfinder against a domain, here is what happens step by step.
First, Subfinder reads the domain name you provided and breaks out the root domain from any subdomain prefix you might have included.
Second, it loads the list of sources you want to query. By default it uses free sources that require no API key. If you have configured API keys, it also queries premium sources.
Third, it fires concurrent queries to all these sources at the same time. It does not wait for one source to finish before querying the next. All queries go out in parallel.
Fourth, each source returns a list of subdomains it has seen for your domain. These are raw results and they often include duplicates because multiple sources will return the same popular subdomains.
Fifth, Subfinder deduplicates the results, filters out anything that does not match the root domain you queried, and returns a clean unique list.
The whole process from start to finish can take anywhere from 15 seconds to a few minutes depending on how many sources are queried and how fast they respond.
The Sources Subfinder Queries
This is the part most tutorials skip, and it is honestly the most important thing to understand.
Subfinder gets its data from sources like these:
Certificate Transparency Logs watch every SSL certificate ever issued for a domain. When a company creates a new subdomain and puts an SSL certificate on it, that certificate appears in public CT logs. Tools like crt.sh and certspotter index these. Subfinder queries them.
Passive DNS Databases collect DNS resolution data from millions of sensors worldwide. When any machine on the internet resolves app.target.com, that query can be logged. Companies like SecurityTrails, Shodan, and VirusTotal maintain these databases. Subfinder queries them.
Search Engine Data includes Google, Bing, and others, which index pages that contain subdomain references. Subfinder can extract subdomain mentions from search results.
Threat Intelligence Platforms like ThreatCrowd and AlienVault OTX collect subdomain data as part of their threat research. Their data is often older but can surface subdomains that disappeared from other sources.
Public DNS Datasets, such as FDNS from Rapid7 store historical internet-wide DNS scans. These are massive datasets that sometimes contain subdomains long forgotten by the target.
The quality of your results depends directly on which of these sources are active and whether you have API keys configured. This is something we will come back to when we discuss advanced usage.
Installing Subfinder on Kali Linux
Install via Go
This is the recommended method and always gives you the latest version.
go install -v github.com/projectdiscovery/subfinder/v2/cmd/subfinder@latestgo install -v github.com/projectdiscovery/subfinder/v2/cmd/subfinder@latestAfter this runs, add the Go binary path to your shell environment if you have not done it already:
export PATH=$PATH:$(go env GOPATH)/binexport PATH=$PATH:$(go env GOPATH)/binMake it permanent by adding it to your shell config:
echo 'export PATH=$PATH:$(go env GOPATH)/bin' >> ~/.zshrc
source ~/.zshrcecho 'export PATH=$PATH:$(go env GOPATH)/bin' >> ~/.zshrc
source ~/.zshrcInstall via APT
sudo apt update && sudo apt install subfinder -ysudo apt update && sudo apt install subfinder -yThis works but may not give you the latest version.
Download Binary Directly
wget https://github.com/projectdiscovery/subfinder/releases/latest/download/subfinder_linux_amd64.zip
unzip subfinder_linux_amd64.zip
sudo mv subfinder /usr/local/bin/wget https://github.com/projectdiscovery/subfinder/releases/latest/download/subfinder_linux_amd64.zip
unzip subfinder_linux_amd64.zip
sudo mv subfinder /usr/local/bin/Verify the Installation
subfinder -versionsubfinder -versionYou should see the version number printed out.
Section 4: Basic Commands Every Security Tester Should Know
The Most Basic Scan
subfinder -d example.comsubfinder -d example.comWhat this does: Queries all default free sources for subdomains of example.com and prints them to the terminal. This is your starting point. Run this first on any new target and see how many subdomains it returns before you do anything else.
Save Results to a File
subfinder -d example.com -o subdomains.txtsubfinder -d example.com -o subdomains.txtWhat this does: Same as above but instead of printing to the screen, it writes all discovered subdomains to subdomains.txt. Always save your results. You will be using this file as input for other tools like httpx and nuclei.
Scan Multiple Domains from a File
subfinder -dL domains.txtsubfinder -dL domains.txtWhat this does: Reads a list of domains from a file and runs subfinder against all of them in sequence. This is useful when a bug bounty program has multiple in-scope domains, like target.com, targetapp.io, and targetpay.com all in scope at once.
The domains.txt file should have one domain per line:
target.com
targetapp.io
targetpay.comtarget.com
targetapp.io
targetpay.comSilent Mode for Clean Output
subfinder -d example.com -silentsubfinder -d example.com -silentWhat this does: Suppresses all the banner text and progress information that Subfinder normally prints. Only the actual subdomains are printed to stdout. This is essential when you are piping Subfinder output directly into another tool because extra text in the output will break the pipe.
Show All Sources Being Queried
subfinder -d example.com -vsubfinder -d example.com -vWhat this does: Enables verbose mode. You will see each source being queried in real time and which ones are returning results. This is useful for troubleshooting when you feel like you are getting fewer results than expected.
List All Available Sources
subfinder -lssubfinder -lsWhat this does: Prints a complete list of every source Subfinder can query. Sources marked with an asterisk or annotation require API keys to work. This command helps you understand exactly what you are and are not getting from a default scan.
Section 5: Intermediate Commands for Deeper Discovery
Use All Sources, Including Premium Ones
subfinder -d example.com -allsubfinder -d example.com -allWhat this does: Enables every source available including ones that are normally not included in a default scan. Some sources are rate limited or slow, which is why they are excluded by default. Using this flag gives you the most comprehensive results at the cost of speed.
Select Specific Sources to Query
subfinder -d example.com -sources shodan,censys,virustotalsubfinder -d example.com -sources shodan,censys,virustotalWhat this does: Tells Subfinder to only query the sources you specify. This is useful when you know which sources have the best coverage for a particular target or when you want to speed up a scan by skipping slow sources.
Exclude Specific Sources
subfinder -d example.com -exclude-sources github,gitlabsubfinder -d example.com -exclude-sources github,gitlabWhat this does: Runs all default sources but skips the ones you list. Useful when a particular source is returning errors or irrelevant results that are cluttering your output.
Set the Number of Concurrent Goroutines
subfinder -d example.com -t 20subfinder -d example.com -t 20What this does: Sets the number of concurrent threads Subfinder uses when querying sources. Default is 10. Increasing this can speed up scans but might also cause rate limiting from some sources. For large scope targets, experimenting with this value can save meaningful time.
Output as JSON
subfinder -d example.com -oJ -o results.jsonsubfinder -d example.com -oJ -o results.jsonWhat this does: Outputs each result as a JSON object instead of plain text. JSON output includes additional fields like the source that found each subdomain. This is useful when you are feeding results into a dashboard, SIEM, or custom processing script.
Output as CSV
subfinder -d example.com -oC -o results.csvsubfinder -d example.com -oC -o results.csvWhat this does: Writes results in CSV format, which makes them easy to open in a spreadsheet for review, sorting, or sharing with non-technical stakeholders.
Show IP Addresses Alongside Subdomains
subfinder -d example.com -oIsubfinder -d example.com -oIWhat this does: Resolves each discovered subdomain and includes its IP address in the output. This immediately shows you which subdomains are pointing to cloud providers, CDNs, or internal IP ranges. An IP pointing to a third-party service that the company no longer owns is a subdomain takeover candidate.
Recursive Subdomain Discovery
subfinder -d example.com -recursivesubfinder -d example.com -recursiveWhat this does: After finding subdomains of example.com, Subfinder takes each discovered subdomain and runs discovery on it too. So if it finds dev.example.com, it will then query for subdomains of dev.example.com, potentially surfacing things like api.dev.example.com or staging.dev.example.com. This significantly increases coverage on large targets.
Section 6: Configuring API Keys for Maximum Results
This is the step most beginners skip and it is exactly why their results are thin compared to experienced hunters.
Without API keys, Subfinder can only query free, unauthenticated sources. With API keys from the right platforms, you can dramatically increase the number of subdomains returned.
Where the Config File Lives
Subfinder stores its configuration at:
~/.config/subfinder/provider-config.yaml~/.config/subfinder/provider-config.yamlIf the file does not exist yet, create it:
mkdir -p ~/.config/subfinder
nano ~/.config/subfinder/provider-config.yamlmkdir -p ~/.config/subfinder
nano ~/.config/subfinder/provider-config.yamlWhat the Config File Looks Like
virustotal:
- your_virustotal_api_key_here
shodan:
- your_shodan_api_key_here
securitytrails:
- your_securitytrails_api_key_here
censys:
- your_censys_api_id:your_censys_api_secret
github:
- your_github_token_here
hunter:
- your_hunter_api_key_here
binaryedge:
- your_binaryedge_api_key_herevirustotal:
- your_virustotal_api_key_here
shodan:
- your_shodan_api_key_here
securitytrails:
- your_securitytrails_api_key_here
censys:
- your_censys_api_id:your_censys_api_secret
github:
- your_github_token_here
hunter:
- your_hunter_api_key_here
binaryedge:
- your_binaryedge_api_key_hereEach platform offers free tiers that are enough for regular security research. Sign up for accounts and generate API keys from each platform's developer settings, then paste them here.
Which Sources Matter Most
SecurityTrails and Shodan are the two that make the biggest difference. SecurityTrails has one of the largest passive DNS databases and regularly surfaces subdomains that nothing else finds. Shodan's historical data and certificate scanning often reveals internal services accidentally exposed to the internet.
VirusTotal is easy to get a free API key for and adds meaningful coverage. GitHub is worth adding because code repositories often contain subdomain references in configuration files and deployment scripts.
Use the Config File in a Scan
Once the config file is set up, Subfinder automatically reads it. You do not need to pass any additional flags. Just run the normal command and all configured sources will be queried.
subfinder -d example.com -o subdomains.txtsubfinder -d example.com -o subdomains.txtSection 7: Advanced Usage and Real Pentest Workflows
Chain Subfinder with httpx to Find Live Hosts
Discovering subdomains is step one. Step two is finding which ones are actually alive and serving HTTP responses.
subfinder -d example.com -silent | httpx -silent -o live-hosts.txtsubfinder -d example.com -silent | httpx -silent -o live-hosts.txtWhat this does: Subfinder outputs raw subdomains via silent mode. That output is piped directly into httpx, which probes each subdomain for a live HTTP or HTTPS response. Only subdomains that respond are saved to live-hosts.txt. Dead subdomains, parked domains, and NXDOMAIN responses are dropped automatically.
This single pipeline replaces hours of manual work.
Chain with Nuclei for Automated Vulnerability Scanning
subfinder -d example.com -silent | httpx -silent | nuclei -t exposures/ -o findings.txtsubfinder -d example.com -silent | httpx -silent | nuclei -t exposures/ -o findings.txtWhat this does: This is a three-tool pipeline. Subfinder finds subdomains. httpx filters to live ones. Nuclei runs exposure templates against every live subdomain and saves any findings to findings.txt. This entire command runs end to end without any human interaction needed in the middle.
Chain with Naabu for Port Scanning
subfinder -d example.com -silent | naabu -silent -o open-ports.txtsubfinder -d example.com -silent | naabu -silent -o open-ports.txtWhat this does: Subfinder discovers subdomains, naabu runs a port scan against each one, and open ports are saved. This surfaces services running on non-standard ports that web scanners would otherwise miss.
Filter for Interesting Subdomains
subfinder -d example.com -silent | grep -iE "admin|dev|staging|test|api|internal|beta|vpn|mail"subfinder -d example.com -silent | grep -iE "admin|dev|staging|test|api|internal|beta|vpn|mail"What this does: The grep filter extracts only subdomains containing keywords that often indicate interesting or sensitive functionality. Subdomains with words like staging, dev, or internal frequently have weaker security controls than production environments.
Use Subfinder in a Bash Loop for Large Programs
cat domains.txt | while read domain; do
subfinder -d $domain -silent >> all-subdomains.txt
done
sort -u all-subdomains.txt > unique-subdomains.txtcat domains.txt | while read domain; do
subfinder -d $domain -silent >> all-subdomains.txt
done
sort -u all-subdomains.txt > unique-subdomains.txtWhat this does: Iterates through every domain in your list, runs Subfinder against each one, appends all results to a single file, and then deduplicates the final file. The sort -u ensures you get a clean unique list even if multiple domains share wildcard subdomains.
Combine with Amass for Maximum Coverage
Subfinder and Amass cover different source sets. Running both and combining the output gives you the most complete picture.
subfinder -d example.com -silent -o sub-subfinder.txt
amass enum -passive -d example.com -o sub-amass.txt
cat sub-subfinder.txt sub-amass.txt | sort -u > combined-subdomains.txtsubfinder -d example.com -silent -o sub-subfinder.txt
amass enum -passive -d example.com -o sub-amass.txt
cat sub-subfinder.txt sub-amass.txt | sort -u > combined-subdomains.txtWhat this does: Both tools run independently, their results are merged into one file, and duplicates are removed. Professionals do this on high-value targets because a subdomain missed by one tool is often caught by the other.
Rate Limit Subfinder for Careful Scanning
subfinder -d example.com -rl 10subfinder -d example.com -rl 10What this does: Sets the requests per second limit when Subfinder queries sources. Lowering this helps avoid triggering rate limits on the data sources themselves, which can cause them to stop returning results mid-scan.
Timeout Setting
subfinder -d example.com -timeout 30subfinder -d example.com -timeout 30What this does: Sets the maximum time in seconds to wait for a response from each source. The default is quite generous but on slow or unreliable network connections you might want to increase this.
Section 8: How to Interpret Your Results
Getting a long list of subdomains is not the end goal. Knowing what to do with them is.
Subdomains that point to third-party services the company no longer actively uses are candidates for subdomain takeover. When you run the output through httpx and see a response like "There is no site configured at this address" from GitHub Pages, Heroku, or similar platforms, that is a signal to investigate.
Subdomains with words like staging, dev, test, uat, or sandbox often run older code and have weaker security. These should be your first manual testing targets.
Subdomains you cannot resolve sometimes indicate internal infrastructure that was briefly exposed or is accessible through specific network conditions. Make note of these even if you cannot reach them right now.
IP addresses that fall in unexpected ranges when you use the -oI flag might indicate cloud services, CDN providers, or third-party hosting that reveals information about the target's architecture.
Subdomains you have never seen mentioned in scope documentation should be checked against the bug bounty program rules. Wildcard scope like *.example.com covers everything, but some programs exclude certain subdomains explicitly.
Section 9: Common Mistakes and How to Avoid Them
Not using API keys is the most common reason people get disappointing results. If you are getting 20 subdomains on a major target, the issue is almost always missing API keys. Set them up once and your results will improve immediately.
Forgetting to use silent mode in pipes is a mistake that causes confusing behavior. When you pipe subfinder output to another tool without the -silent flag, the banner and progress text get included in the stream and corrupts the input for the next tool.
Not recursing on interesting subdomains means you miss entire sections of the attack surface. If you find dev.example.com, always check what lives under it.
Treating passive results as final is a trap. Subfinder gives you what data sources know. It does not know about brand new subdomains created last week that have not been indexed yet. Always complement passive tools with active brute force tools like PureDNS or dnsx for complete coverage.
Running without rate limiting on long lists can get your IP blocked by source APIs. If you are scanning hundreds of domains, add the rate limit flag.
Section 11: Subfinder in a Full Bug Bounty Recon Workflow
Here is the complete workflow I use personally when I start a new bug bounty target.
Step 1 Run subfinder to collect passive subdomains:
subfinder -d target.com -all -o passive-subs.txtsubfinder -d target.com -all -o passive-subs.txtStep 2 Run amass alongside it for additional coverage:
amass enum -passive -d target.com -o amass-subs.txtamass enum -passive -d target.com -o amass-subs.txtStep 3 Merge and deduplicate:
cat passive-subs.txt amass-subs.txt | sort -u > all-subs.txtcat passive-subs.txt amass-subs.txt | sort -u > all-subs.txtStep 4 Filter for live hosts using httpx:
cat all-subs.txt | httpx -silent -o live-hosts.txtcat all-subs.txt | httpx -silent -o live-hosts.txtStep 5 Quick Nuclei scan for common exposures:
nuclei -l live-hosts.txt -t exposures/ -t misconfiguration/ -severity medium,high,critical -o quick-findings.txtnuclei -l live-hosts.txt -t exposures/ -t misconfiguration/ -severity medium,high,critical -o quick-findings.txtStep 6 Manual review of interesting subdomains filtered by keyword:
cat live-hosts.txt | grep -iE "admin|dev|staging|api|internal" > interesting.txtcat live-hosts.txt | grep -iE "admin|dev|staging|api|internal" > interesting.txtFrom this point, the interesting.txt file becomes your manual testing list and quick-findings.txt becomes your initial report draft.
This workflow, from zero to a prioritized list of targets with automatic findings, takes under 30 minutes on most programs.
Subfinder is a recon tool, and its findings are the foundation of everything else. A missed subdomain means a missed vulnerability. Bugs reported from proper recon have included:
Exposed Jenkins dashboards on dev subdomains with no authentication. These often lead to remote code execution through the Groovy script console.
Staging environments with real user data because developers copied production databases for testing without sanitizing them.
Forgotten admin panels on old subdomains still running outdated software with known critical CVEs.
Internal APIs exposed at api-internal.target.com that were never meant to be publicly accessible and had no authentication.
Subdomain takeovers on unused cloud service subdomains where the CNAME record still pointed to a deprovisioned service.
None of these would have been found without comprehensive subdomain discovery first.
Mitigation: If You Are a Defender
If your organization wants to prevent attackers from mapping your subdomain footprint, the first step is understanding that passive data collection cannot be prevented. Once a certificate is issued for a subdomain, it lives in CT logs permanently.
What you can control is your attack surface itself. Audit your DNS records regularly and remove CNAME entries pointing to services you no longer use. Decommission subdomains properly by deleting both the DNS record and the cloud resource it points to, not just one of them.
Keep an inventory of all your subdomains and run tools like Subfinder against your own domains on a schedule. If you find subdomains you did not know existed, investigate them immediately.
Subfinder is one of those tools that looks simple on the surface but rewards you more the deeper you go. A basic scan gives you a list. But understanding the sources, configuring API keys, chaining with other tools, and knowing how to read the output turns that list into actual findings.
It is the first tool I open on any new target. It takes three minutes to run and the output shapes the rest of my testing strategy.
If you have not set up your provider config with API keys yet, do that today. It is a one-time setup that permanently improves every scan you run from that point forward.
Tags
subfinder subdomain-enumeration bug-bounty kali-linux penetration-testing recon web-security projectdiscovery ethical-hacking osint