Skip to main content

VirtualHost Enumeration

VirtualHosts Examples

In the diagram above, this is the valid way to use virtual hosts. You create the virtual host configuration on the web server and then create the DNS record for the virtual host and point it at the web server IP address.

However, the point of virtual host enumeration is to discover virtual host configurations on the web server where a DNS record has not been created. For this, you'd use your local /etc/hosts once you find the virtual host using the methodology below.

NGINX

/etc/nginx/sites-available/example.com.conf

server {
       listen 80;
       server_name www.example.com;
       root /var/www/example.com;
       index index.html;

       location / {
               try_files $uri $uri/ =404;
       }
}

server {
       listen 80;
       server_name dev.example.com;
       root /var/www/my-test-server;
       index index.html;

       location / {
               try_files $uri $uri/ =404;
       }
}

Server Block 1

    • Listens on TCP/80
    • Answer any HTTP request with HOST: www.example.com
    • Serve the contents out of /var/www/example.com
    • Home page (index) is /var/www/example.com/index.html
    • When hitting the server name, try files in:
      • /var/www/example.com/ + user/requested/resource


Server Block 2

    • Listens on TCP/80
    • Answer any HTTP request with HOST: dev.example.com
    • Serve the contents out of /var/www/my-test-server
    • Home page (index) is /var/www/my-test-server/index.html
    • When hitting the server name, try files in:
      • /var/www/my-test-server/ + user/requested/resource

Apache

/etc/apache2/sites-available/example.com.conf

<VirtualHost *:80>
        ServerName www.example.com
        ServerAdmin webmaster@localhost
        DocumentRoot /var/www/html
        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

<VirtualHost *:80>
        ServerName dev.example.com
        ServerAdmin webmaster@localhost
        DocumentRoot /var/www/my-test-server
        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

Server Block 1

    • Listens on TCP/80
    • Answer any HTTP request with HOST: www.example.com
    • Serve the contents out of /var/www/example.com
    • Home page (index) is /var/www/example.com/index.html
    • When hitting the server name, try files in:
      • /var/www/example.com/ + user/requested/resource


Server Block 2

    • Listens on TCP/80
    • Answer any HTTP request with HOST: dev.example.com
    • Serve the contents out of /var/www/my-test-server
    • Home page (index) is /var/www/my-test-server/index.html
    • When hitting the server name, try files in:
      • /var/www/my-test-server/ + user/requested/resource



Enumeration

Given the domain: example.com, we know www.example.com exists, and probably is the production web server for the domain example.com

We don't know that dev.example.com exists. How would we discover this?

GoBuster

gobuster (and other tools like wfuzz) have a Virtual Host enumeration mode.

# Set some variables
target='https://10.6.6.100'
base_domain="example.com"
wordlist="/usr/share/seclists/Discovery/DNS/subdomains-top1million-110000.txt"

# Run gobuster in VirtualHost enumeration mode
gobuster vhost -k --domain $base_domain --append-domain -u $target -w $wordlist

In vhost mode, gobuster is going to do the following:

GET / HTTP/1.1
Host: [wordlist-item].example.com
User-Agent: gobuster/x.x
Content-Length: xx
Accept: */*
X-Custom-Header-Example: blah

The server is going to look at the value of the Host: header and determine if it has a virtual host configuration for that hostname. And if it does, respond accordingly.

  • [wordlist-item1].example.com ...... if server responds HTTP 200, VirtualHost exists
  • [wordlist-item2].example.com ...... if server responds HTTP 200, VirtualHost exists
  • [wordlist-item3].example.com ...... if server responds HTTP 200, VirtualHost exists
  • [wordlist-item4].example.com ...... if server responds HTTP 200, VirtualHost exists
  • [wordlist-item5].example.com ...... if server responds HTTP 200, VirtualHost exists
  • etc, etc.

You may also need to filter based on --exclude-length as server responses such as HTTP 200 may not be a good indicator and may lead to false positives.