Certificate parsing is a way of conducting web hacking reconnaissance when an attacker is targeting an organization. The goal is to gather information about the organization and widen the attack space by enumerating every possible domain and subdomain owned by an organization. One methodology of enumerating domains and subdomains is to take advantage of the SSL certificates used by the organization. There are several online databases like crt.sh and sslmate which can be used to enumerate certificates issued for domains owned by an organization. Moreover, if we take a look at the
Subject Alternative Name of a certificate, we might be able to enumerate other hostnames for which the certificate is applied.
domain-recon is an open-source command line tool written in Rust, which automates certificate parsing. It uses
[crt.sh](https://crt.sh/) database to fetch information about certificates issued for a domain and all of its subdomains. It extracts all the hostnames from the
Common Name and
Matching Identities fields, the result of which will be a list of domains requiring further filtering. We can distinguish the following type of domains in the list:
- registered domains that can be resolved as IPv4 or IPv6 IP addresses;
- unregistered domains;
- wildcard domains, domain names which contain a wildcard character (
*), for example:
*.example.com. Wildcards are used to secure multiple subdomain names (hosts) pertaining to the same base domain.
domain-recon filters out wildcard domains from the list and tries to do a domain resolution for each non-wildcard domain. It drops all the domain names which are not registered and it displays a list only with the "valid" domain names.
In the case of the wildcard domains, it will try to guess possible subdomains. This is accomplished by taking a wordlist as input and replacing the wildcards with entries from the list. To detect which domain names are registered, it tries to do a domain resolution for each new entry and displays a new list with the successful queries.
List all the domains and subdomains for
domain-recon -d dev.to -f words.txt
The output of which will be something like this:
Fetching certificates... Extracting domains.... sni.cloudflaressl.com A 220.127.116.11, 18.104.22.168, 22.214.171.124 dev.to A 126.96.36.199, 188.8.131.52, 184.108.40.206, 220.127.116.11 sni174710.cloudflaressl.com A 18.104.22.168, 22.214.171.124, 126.96.36.199 www.jobs.dev.to A 188.8.131.52, 184.108.40.206 jobs.dev.to A 220.127.116.11, 18.104.22.168 t2.shared.global.fastly.net A 22.214.171.124, 126.96.36.199, 188.8.131.52, 184.108.40.206 2020.dev.to A 220.127.116.11, 18.104.22.168 storybook.dev.to A 22.214.171.124, 126.96.36.199 shop.dev.to A 188.8.131.52 status.dev.to A 184.108.40.206 docs.dev.to A 220.127.116.11, 18.104.22.168 customer-service.status-ovhcloud.com A 22.214.171.124 status-beta.sailpoint.com A 126.96.36.199 itstatus.stmonicatrust.co.uk A 188.8.131.52 Expanding wildcards... admin.forem.com A 184.108.40.206, 220.127.116.11 docs.forem.com A 18.104.22.168, 22.214.171.124 demo.forem.com A 126.96.36.199, 188.8.131.52, 184.108.40.206 www.forem.com A 220.127.116.11, 18.104.22.168, 22.214.171.124 www.dev.to A 126.96.36.199, 188.8.131.52
We can omit to expand wildcards by not specifying a wordlist:
domain-recon -d dev.to
Fetching certificates... Extracting domains.... jobs.dev.to A 184.108.40.206, 220.127.116.11 sni174710.cloudflaressl.com A 18.104.22.168, 22.214.171.124, 126.96.36.199 dev.to A 188.8.131.52, 184.108.40.206, 220.127.116.11, 18.104.22.168 www.jobs.dev.to A 22.214.171.124, 126.96.36.199 shop.dev.to A 188.8.131.52 sni.cloudflaressl.com A 184.108.40.206, 220.127.116.11, 18.104.22.168 storybook.dev.to A 22.214.171.124, 126.96.36.199 docs.dev.to A 188.8.131.52, 184.108.40.206 customer-service.status-ovhcloud.com A 220.127.116.11 status-beta.sailpoint.com A 18.104.22.168 t2.shared.global.fastly.net A 22.214.171.124, 126.96.36.199, 188.8.131.52, 184.108.40.206 2020.dev.to A 220.127.116.11, 18.104.22.168 status.dev.to A 22.214.171.124 itstatus.stmonicatrust.co.uk A 126.96.36.199
We can use the
--plain flag to suppress displaying IP addresses. This can be useful if we want a list with domain names only, which can be provided as input for tools such as
$ domain-recon -d dev.to -f words.txt --plain | httpx -probe -sc -title -ip __ __ __ _ __ / /_ / /_/ /_____ | |/ / / __ \/ __/ __/ __ \| / / / / / /_/ /_/ /_/ / | /_/ /_/\__/\__/ .___/_/|_| /_/ v1.2.5 projectdiscovery.io Use with caution. You are responsible for your actions. Developers assume no liability and are not responsible for any misuse or damage. http://sni174710.cloudflaressl.com [SUCCESS]   [188.8.131.52] https://www.dev.to [SUCCESS]   [184.108.40.206] https://jobs.dev.to [SUCCESS]   [220.127.116.11] https://t2.shared.global.fastly.net [SUCCESS]  [Fastly error: unknown domain t2.shared.global.fastly.net] [18.104.22.168] https://shop.dev.to [SUCCESS]   [22.214.171.124] https://dev.to [SUCCESS]  [DEV Community 👩💻👨💻] [126.96.36.199] http://www.jobs.dev.to [SUCCESS]   [188.8.131.52] https://admin.forem.com [SUCCESS]  [Hello from Forem Admin Docs | Forem Admin Docs] [184.108.40.206] https://docs.dev.to [SUCCESS]   [220.127.116.11] https://2020.dev.to [SUCCESS]  [thank you] [18.104.22.168] https://storybook.dev.to [SUCCESS]  [Webpack App] [22.214.171.124] https://shop.forem.com [SUCCESS]  [Forem Shop] [126.96.36.199] http://sni.cloudflaressl.com [SUCCESS]   [188.8.131.52] https://www.forem.com [SUCCESS]  [[Forem] Community for Everyone] [184.108.40.206] https://status.dev.to [SUCCESS]  [DEV Status] [220.127.116.11] https://customer-service.status-ovhcloud.com [SUCCESS]  [Customer Service Status] [18.104.22.168] https://docs.forem.com [SUCCESS]   [22.214.171.124] https://itstatus.stmonicatrust.co.uk [SUCCESS]  [St Monica Trust IT Status] [126.96.36.199] https://status-beta.sailpoint.com [SUCCESS]   [188.8.131.52] https://demo.forem.com [SUCCESS]  [Dunder Mifflin Community 📄] [184.108.40.206]
domain-recon can discover domain names that have public SSL certificates. Currently, it scans only valid certificates, this can be easily changed to include invalid ones as well, but according to my experience, this is not as useful.
Nowadays, most websites have SSL certificates, including development and testing environments as well. It can be helpful for a pen-tester to scan for these environments. Obviously, it can not find environments without registered SSL certificates.
domain-recon currently uses Google, Cloudflare, and Quad9 domain resolvers. By default, it is set to use Google only, which we can override with
--dns_resolver argument. We can also set to use multiple resolvers at the same time (
--dns_resolver="google,cloudflare,quad9"). According to my experience, having only one resolver might invoke rate limiting if we are scanning a huge number of domains at the same time. Unfortunately, there are slowdowns with multiple resolvers as well. It relies on
async-std-resolver crate for DNS resolution. A future improvement would be to optimize the usage of
async-std-resolver to achieve better performance. Since it relies on async calls, we can run on errors related to having too many opened connections. This is somewhat mitigated by limiting the DNS calls to a lower number, but I'm sure there better ways to deal with it.
domain-recon tool was inspired by "Bug Bounty Bootcamp: The Guide to Finding and Reporting Web Vulnerabilities" book by Vickie Li. It is a great resource for anyone interested in web hacking and penetration testing.
As mentioned above, the source code for
domain-recon can be found on GitHub: https://github.com/domain-recon/domain-recon-rs. It is written entirely in Rust. Any contribution is welcomed. ;)