Certificate Parsing with `domain-recon`

Ervin SzilágyiErvin Szilágyi
5 min read

What is Certificate Parsing?

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.

What is domain-recon?

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.

Example of Usage

The source code for domain-recon tool can be found on GitHub. Executables are built and released for all Linux, Mac, and Windows operating systems and can be downloaded from the releases.

List all the domains and subdomains for dev.to:

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 104.22.63.243, 172.67.27.61, 104.22.62.243
dev.to A 151.101.194.217, 151.101.2.217, 151.101.66.217, 151.101.130.217
sni174710.cloudflaressl.com A 172.67.27.61, 104.22.63.243, 104.22.62.243
www.jobs.dev.to A 188.114.97.13, 188.114.96.13
jobs.dev.to A 188.114.97.13, 188.114.96.13
t2.shared.global.fastly.net A 151.101.2.217, 151.101.66.217, 151.101.130.217, 151.101.194.217
2020.dev.to A 3.67.255.218, 34.141.28.239
storybook.dev.to A 3.67.234.155, 3.67.153.12
shop.dev.to A 23.227.38.74
status.dev.to A 52.215.192.133
docs.dev.to A 34.141.11.154, 34.159.58.69
customer-service.status-ovhcloud.com A 52.215.192.131
status-beta.sailpoint.com A 52.215.192.132
itstatus.stmonicatrust.co.uk A 52.215.192.131

Expanding wildcards...
admin.forem.com A 35.198.80.163, 34.141.28.239
docs.forem.com A 34.141.28.239, 34.141.48.9
demo.forem.com A 3.19.109.223, 3.135.110.253, 3.13.138.118
www.forem.com A 34.251.201.224, 54.194.170.100, 34.253.101.190
www.dev.to A 188.114.97.13, 188.114.96.13

We can omit to expand wildcards by not specifying a wordlist:

domain-recon -d dev.to

Output:

Fetching certificates...
Extracting domains....
jobs.dev.to A 188.114.97.13, 188.114.96.13
sni174710.cloudflaressl.com A 104.22.62.243, 172.67.27.61, 104.22.63.243
dev.to A 151.101.194.217, 151.101.2.217, 151.101.66.217, 151.101.130.217
www.jobs.dev.to A 188.114.97.13, 188.114.96.13
shop.dev.to A 23.227.38.74
sni.cloudflaressl.com A 104.22.63.243, 172.67.27.61, 104.22.62.243
storybook.dev.to A 3.67.255.218, 3.67.153.12
docs.dev.to A 34.141.11.154, 34.159.132.250
customer-service.status-ovhcloud.com A 52.215.192.133
status-beta.sailpoint.com A 52.215.192.133
t2.shared.global.fastly.net A 151.101.2.217, 151.101.66.217, 151.101.130.217, 151.101.194.217
2020.dev.to A 3.67.255.218, 34.141.11.154
status.dev.to A 52.215.192.131
itstatus.stmonicatrust.co.uk A 52.215.192.133

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 httpx.

Example:

$ 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] [301] [] [104.22.62.243]
https://www.dev.to [SUCCESS] [301] [] [188.114.97.8]
https://jobs.dev.to [SUCCESS] [301] [] [188.114.97.13]
https://t2.shared.global.fastly.net [SUCCESS] [] [Fastly error: unknown domain t2.shared.global.fastly.net] [151.101.114.217]
https://shop.dev.to [SUCCESS] [301] [] [23.227.38.74]
https://dev.to [SUCCESS] [200] [DEV Community 👩‍💻👨‍💻] [151.101.130.217]
http://www.jobs.dev.to [SUCCESS] [308] [] [188.114.97.8]
https://admin.forem.com [SUCCESS] [200] [Hello from Forem Admin Docs | Forem Admin Docs] [34.141.28.239]
https://docs.dev.to [SUCCESS] [301] [] [3.64.200.242]
https://2020.dev.to [SUCCESS] [200] [thank you] [3.125.16.34]
https://storybook.dev.to [SUCCESS] [200] [Webpack App] [18.159.128.50]
https://shop.forem.com [SUCCESS] [200] [Forem Shop] [23.227.38.74]
http://sni.cloudflaressl.com [SUCCESS] [301] [] [172.67.27.61]
https://www.forem.com [SUCCESS] [200] [[Forem] Community for Everyone] [34.253.101.190]
https://status.dev.to [SUCCESS] [200] [DEV Status] [52.215.192.131]
https://customer-service.status-ovhcloud.com [SUCCESS] [200] [Customer Service Status] [52.215.192.132]
https://docs.forem.com [SUCCESS] [301] [] [34.159.168.235]
https://itstatus.stmonicatrust.co.uk [SUCCESS] [200] [St Monica Trust IT Status] [52.215.192.133]
https://status-beta.sailpoint.com [SUCCESS] [302] [] [52.215.192.131]
https://demo.forem.com [SUCCESS] [200] [Dunder Mifflin Community 📄] [3.19.109.223]

Limitations

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.

Further Reading

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.

Source Code and Contributing

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. ;)

2
Subscribe to my newsletter

Read articles from Ervin Szilágyi directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Ervin Szilágyi
Ervin Szilágyi

Solutions Architect, AWS Community Builder, passionate about cloud and technology. Currently learning Rust for fun and street credz.