Yet another passive subdomain enumeration tool written in Python from scratch.
- Subdomains from multiple sources
- JSON and regular output
- Multithreading
- Cross platform
- Rate-limiting evasion functionality
- Docker image
- subdomains.whoisxmlapi.com
- crt.sh
- urlscan.io
- otx.alienvault.com
- jonlu.ca (Anubis-DB)
- hackertarget.com
- dnsrepo.noc.org
Clone the project
git clone https://github.com/tuchaVshortah/puff.git
Go to the project directory
cd puff
Install dependencies
pip install -r requirements.txt
Start puff
python puff.py -d <domain> --boost
docker pull tuchavshortah/puff:latest
ℹ️ The same arguments can be used in the Docker installation.
Replace "python puff.py" with "docker run --rm tuchavshortah/puff" to run the Docker container.
❗The -n flag limits the maximum amount of subdomains to probe. You may get less results than the specified number due to the fact that subdomains may be dead
Parse remotes in multithreading mode and perform active scanning on 3 subdomains of the specified domain:
(.venv) PS C:\Users\nuken\Projects\puff> python puff.py -d google.com -b -a -n 3
Parsing sites... ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00
Completing concurrent.futures... ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00
Preparing alive subdomains... ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00
Alive subdomains
┏━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━┓
┃ Number ┃ Subdomain ┃ Status code ┃ Title ┃ Backend ┃
┡━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━┩
│ 1 │ pub-1556105567536871.afd.ghs.google.com │ 404 │ Error 404 (Not Found)!!1 │ ghs │
│ 2 │ 36-98.docs.google.com │ 200 │ Sign in - Google Accounts │ ESF │
└────────┴─────────────────────────────────────────┴─────────────┴───────────────────────────┴─────────┘
Parse in multithreading mode and save 3 subdomains in the subdomains.<domain>.<format> files:
(.venv) PS C:\Users\nuken\Projects\puff> python puff.py -d google.com -b -n 3 -a -df
Parsing sites... ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00
Completing concurrent.futures... ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00
Preparing alive subdomains... ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00
Alive subdomains
┏━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━┓
┃ Number ┃ Subdomain ┃ Status code ┃ Title ┃ Backend ┃
┡━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━┩
│ 1 │ o-o.preferreaccounts-ph.sn-35153iuxa-unxe.v9.lscache2.c.anaccounts-phroiaccounts-ph.clients.google.com │ 404 │ Error 404 (Not │ N/A │
│ │ │ │ Found)!!1 │ │
└────────┴────────────────────────────────────────────────────────────────────────────────────────────────────────┴─────────────┴────────────────┴─────────┘
❗Functionality provided by the -n flag allows you to have a cleaner terminal while saving the full output to the specified file
In the example below only 5 subdomains are outputted to the CLI, but all of the found subdomains were saved into the specified file.
Parse, list and save all subdomains of the specified domain to the given file but limit the CLI output with 5 subdomains only:
(.venv) PS C:\Users\nuken\Projects\puff> python puff.py -d google.com -f subdomains.google.txt -n 5
Parsing sites... ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00
Preparing subdomains... ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00
Subdomains
┏━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Number ┃ Subdomain ┃
┡━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ 1 │ testing6.r4.sn-npoeenle.c.docs.google.com │
│ 2 │ 13q8faa.feedproxy.ghs.google.com │
│ 3 │ alt24468.xmpp.l.google.com │
│ 4 │ alt-0243.upload.google.com │
│ 5 │ payh2gjxuyyt2o3gsax5gcxri6d4nr7ts7xhepbxuxv3bxweuosa.mx-verification.google.com │
└────────┴─────────────────────────────────────────────────────────────────────────────────┘
Parse and output 5 subdomains of the specified domain in JSON:
(.venv) PS C:\Users\nuken\Projects\puff> python puff.py -d google.com -j -n 5
Parsing sites... ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00
[
"jmcnamara.r1.sn-npoeenl7.c.docs.google.com",
"pub-5461530528097278.afd.ghs.google.com",
"e3bxooh7aamclbxgyf2c5vcxe64xt5dajflll5bp4denufti5rna.mx-verification.google.com",
"google-proxy-74-125-211-40.google.com",
"google-proxy-66-249-93-40.google.com"
]
Number of found subdomains for google.com:
(.venv) PS C:\Users\nuken\Projects\puff> python puff.py -d google.com -b -v -n 0
Parsing sites... ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00
10000 subdomains from whoisxmlapi.com
0 subdomains from crt.sh
5 subdomains from] urlscan.io
199 subdomains from otx.alienvault.com
5197 subdomains from jonlu.ca
136 subdomains from dnsrepo.noc.org
Total unique subdomains: 15422
Preparing subdomains... ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00
Multithreaded execution time:
(.venv) PS C:\Users\nuken\Projects\puff> Measure-Command { python puff.py -d google.com -b } | Select-Object TotalSeconds
TotalSeconds
------------
9.4502747
Number of found subdomains for yahoo.com:
(.venv) PS C:\Users\nuken\Projects\puff> python puff.py -d yahoo.com -b -v -n 0
Parsing sites... ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00
10000 subdomains from whoisxmlapi.com
0 subdomains from crt.sh
0 subdomains from] urlscan.io
254 subdomains from otx.alienvault.com
8232 subdomains from jonlu.ca
145 subdomains from dnsrepo.noc.org
Total unique subdomains: 18320
Preparing subdomains... ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00
Multithreaded execution time:
(.venv) PS C:\Users\nuken\Projects\puff> Measure-Command { python puff.py -d yahoo.com -b } | Select-Object TotalSeconds
TotalSeconds
------------
9.8459897
puff parses subdomains.whoisxmlapi.com, crt.sh, urlscan.io, otx.alienvault.com, jonlu.ca (Anubis-DB), hackertarget.com and dnsrepo.noc.org to get information about subdomains of the target domain.
Currently, two output formats are supported: JSON and TXT.
Very fast IMHO. However, your connection speed might be its bottleneck.
-
✅ Add an option to check for alive domains
-
Add a class named ConfigWrapper to make management of arguments easier and add support for config files
-
Add a universal ConsoleWrapper class which will manage output styles and options (such as --quiet)
-
✅ Multithreading
-
✅ Good README
-
Clean code
-
✅ Modular codebase
-
✅ Comprehensive --help page
-
Comprehensive documentation
-
✅ Parse data
-
✅ requirements.txt
-
Configurability
-
Logging
-
✅ Check alive subdomains
-
✅ Rate limiting evasion
-
Caching
-
Vulnerability searching 🧐
-
Threat detection 🧐
-
GUI 🧐
-
Full information about the target
-
Integrate paid APIs
-
CI/CD 🧐?
-
✅ Github releases
-
Sponsoring 🧐?