In a recent PCI DSS Compliance Report, I had an HTTP Header Internal IP Disclosure Vulnerability; which, I have dealt with before on a vanilla 2016 Exchange server but have really struggled to find any up to date information on this Vulnerability and the best way to fix it…
I use the term vulnerability very loosely in this tutorial as its what is stated in the PCI Compliance Report. Having only the internal IP address of a server is not going to get you very far; however, as part of your enumeration or as a wider attack, the internal IP address might be very useful.
I have added links to there Nessus pages showing the two vulnerabilities below:
Microsoft Exchange Client Access Server Information Disclosure: https://www.tenable.com/plugins/nessus/77026
Web Server HTTP Header Internal IP Disclosure: https://www.tenable.com/plugins/nessus/10759
These two Vulnerabilities exist because you can send the IIS webserver a specially crafted HTTP 1.0 GET request, without any host header set. This causes the server to divulge its own internal IP address.
The reason this happens is that the HTTP 1.0 protocol does not require the host header to be set by the client as part of the request. However, HTTP 1.1 requires the client to specify a host so is not affected.
In my test lab, I decided to recreate the Issue with a vanilla install of Windows Server 2016 and 2016 Exchange.
The tool ill be using to test these vulnerabilities is OpenSSL but there are other tools you can use like ncat or Nmap, you can even use burp and get the same results.
Microsoft Exchange Client Access Server Information Disclosure
Connect to the open HTTPS port of your exchange server using OpenSSL and the command below.
openssl s_client -host hostname.domain.com -port 443
Once the connection is made, you will be prompted to input a command.
Make a GET request to autodiscover.xml using the command below.
GET /autodiscover/autodiscover.xml HTTP/1.0
You need to hit Enter twice after you typed the GET request; before the server will respond.
This spits out its local IP address under the header WWW-Authenticate: Basic realm=.
Web Server HTTP Header Internal IP Disclosure
To test this vulnerability, it is basically the same procedure as the previous one; But, this time we are sending our GET request to the root of the webserver instead of autodiscover.xml.
Connect to your exchange server using OpenSSL as below.
openssl s_client -host host.domain.com -port 443
Then send this GET request to the root page of the webserver.
GET / HTTP/1.0
Notice the response kindly lets you know the Internal IP in the Location: header.
Originally when I started this tutorial my fix was to manually re-write the headers, so the headers displayed the external domain name instead of the internal IP address. This has got me through many a PCI DSS Compliance scan but there is a better way.
In researching this tutorial, I stumbled across this blog post from Cyberis.co.uk and their solution to this issue is to configure the IIS server to deny requests made without the Host header set. They achieve this by using the URL rewrite module for IIS.
I have tested this in my lab and it works a treat and would say is my prefered method to fix the two vulnerabilities.
Download the URL Rewrite module onto your exchange server and install it.
If installed correctly you should see a URL Rewrite shortcut in IIS, after clicking on the default website.
Click URL Rewrite to open it. Then click the Add Rule(s) button under actions.
Choose Request blocking rule and click OK.
Set Block access based on Host Header, Block requests that do not match the pattern, using regular expression and set the pattern to .+ (i.e match one or more of any characters).
Click OK and this rule should now display in URL Rewrite as below.
Connections now made via HTTP 1.0 without any Host header will be rejected by the server.
The Orignal Autodiscover.xml fix
This is my original fix for both the vulnerabilities, which I have left here just in case the URL Rewrite method does not work for you.
Let’s start with the exchange autodiscover local IP disclosure first, Open up IIS Manager, navigate to Autodiscover and then authentication.
Then right-click Basic Authentication and select edit.
Enter your external domain name into the Realm: and hit OK
Now resend the HTTP 1.0 Get request to autodiscover.xml and you should get back the external domain name instead of the local IP address.
HTTP Header Internal IP Disclosure
This is how to fix for the HTTP Header Internal IP Disclosure, took me ages to work this out.
The problem is that, even though there are no URL Redirections set In IIS by default with Exchange; the root of the website always redirects to Outlook web access(OWA).
The web.config file is located in the inetpub folder which in my test lab is C:\inetpub\wwwroot\web.config
!!! Make sure you have a backup copy of the web.config before making any changes to it !!!
This fixes the issue as the server now does not do any 302 redirections and if you try the GET request again, the server now responds with the HTML for the default IIS landing page.
If you open up a web browser and navigate to the root of web server, you should see a page like this.
Re-Setting up the Redirection
You can Easily re-setup the 302 Redirection to OWA with the HTTP Redirect module in IIS.
Click on Default Web Site in IIS Manager and Select HTTP Redirect.
Make sure, “Redirect requests to this destination” is ticked; Then type in https://external.domain.name/owa
Also, tick the box that says “only redirect requests to content in this directory (not subdirectories)”.
Re-run the GET request without any host header, and it should now give the external domain name instead of the internal IP address.
Please let me know in the comments, if this tutorial has helped you out or if you have had any difficulties sorting these vulnerabilities. I read and respond to them all.