You are on a Red Team internal engagement and find an IP with a webserver running. However, you’re unsure of the Fully Qualified Domain Name(FQDN) it’s hosting. Without knowing the FQDN we cannot access any sites hosted on the webserver, besides the default site. Now you are stuck staring at the default IIS or Apache landing page. How can we access the websites when we don’t have the FQDNs?
Whenever you make a web request, part of the web request contains the “HOST:” option in the HTTP Header. The “HOST:” option is the FQDN; for example, “HOST: yahoo.com.” The Header option tells the web service to use the “VHost” settings matching the FQDN. The default page is displayed if you do not provide an FQDN(using just the IP), or a non-existent FQDN.
Let’s look at the response difference we get when using the FQDN vs the IP when making a request to Yahoo’s webserver.
You can see in the above images that the responses are different based on the host options used. So we need to know the FQDN of a website hosted on a webserver before we can access that site.
To find the FQDNs we will brute-force the “HOST:” header options to find the VHosts configured on a webserver.
Why not just brute-force the DNS?
You may be thinking, “Why not just brute-force the DNS records instead?” Glad you asked! The short answer is you may miss websites hosted on the webserver. Here are some reasons why sites will be missed.
- No access to the targets network DNS server.
- Split-brain DNS, and you are on a external network. A target may have a website hosted on a server that is Internet-facing, but DNS records are on the internal DNS server only. So only internal company employees can resolve the FQDN to the website.
- Find old and Dev websites. It is not uncommon to find temporary websites that a Dev Team or System Admin put up to test and then forgot about. They likely only configured their local systems “hosts” file for their test, so no DNS records.
GoBuster does not cover this,
VHost Brute-Force Tactic
To brute-force a webservers VHosts, we can use the curl command. The curl command allows us to dictate a host option and the IP address to resolve the FQDN. Here is an example below.
# curl http://fqdn --resolve "fqdn:port:IP" -H "HOST: fqdn"
curl "http://test.example.com" --resolve "test.example.com:80:10.1.1.30" -H "HOST: test.example.com"
Now that we have the tactic of enumerating the webserver’s VHosts, we can script the testing procedure.
The brute-force procedure goes like this.
- Curl the IP without an FQDN, take note of the Content-Length in the returned message response.
- Curl the IP with the FQDN, and compare the returned Content-Length to the first request.
- If the returned Content-Lengths do not match, then you discovered a website.
I have written up a quick script to weaponize this procedure. The script is available on my GitHub.