Keeping that in mind, we recently ran our flagship product through a security audit. It was such a helpful exercise in tying-off any remaining lose ends in our application in terms of application security.
Based on the security audit report, there was a relatively minor issue that appeared when accessing the /images directory of our application. Turns out that the Location response header of the 301 request returns an Internal IP address. The issue is detailed below.
Issue reported
Internet Information Services (IIS) may reveal its real or internal IP address in the Location header via a request to the /images directory. The value returned whilst pen testing is https://10.0.0.10/images.
The risk
Information regarding internal IP address ranges is usually hidden from internet facing systems and can provide an attacker with useful information about internal network structure which can be later used in a targeted attack.
The recommendation
As a matter of best practice, internal information should be removed or masked.
Understanding the Issue
When the /images directory is requested, IIS ensures that /images directory has “Directory Browsing” enabled. If it is not enabled and the directory does not have a Default.html/htm page within the directory, a “Forbidden” page needs to be shown.
When the request method used is HTTP/1.0, the Location response header of the 301 request returns an Internal IP address. This needs to be mitigated!
In terms of HTTP Headers, the following 2 request, responses are made:
- Response Code 301 /images => /images/
- Response Code 403 Forbidden
The actual interactions between the browser and server are listed below.
* Response Code 301 /images => /images/
The request
Remote
Address
|
10.0.0.10: 443
|
Request URL
|
https://dev-2008-iis01.pv.local/images
|
Request
Method
|
GET
|
Status Code
|
301 Moved Permanently
|
Request headers
Accept
|
text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
|
Accept-Encoding
|
gzip,deflate,sdch
|
Accept-Language
|
en-US,en;q=0.8
|
Connection
|
keep-alive
|
Cookie
|
ASP.NET_SessionId=e5hlhemgbpcu0a3k0dphke5y; __RequestVerificationToken=ufS2rtMQMEHuRRQdV8umKRyJF4LMN4Pt9tNbF2QEDxQhvLWlZiycwD_vYNVlUwi6858t5-m8oLvW1CppLT1VuXVPeLE1
|
Host
|
development-server-iis.local
|
User-Agent
|
Mozilla/5.0 (Windows NT 6.1; WOW64)
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36
|
Response headers
Content-Length
|
162
|
Content-Type
|
text/html; charset=UTF-8
|
Date
|
Tue, 22 Jul 2014 03:27:31 GMT
|
Location
|
https://development-server-iis.local/images
|
Server
|
Microsoft-IIS/7.5
|
X-Powered-By
|
ASP.NET
|
* Response Code 403 Forbidden
The request
Remote
Address
|
10.0.0.10:443
|
Request URL
|
https://development-server-iis.local/images/
|
Request
Method
|
GET
|
Status Code
|
403 Forbidden
|
Request headers
Accept
|
text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
|
Accept-Encoding
|
gzip,deflate,sdch
|
Accept-Language
|
en-US,en;q=0.8
|
Connection
|
keep-alive
|
Cookie
|
ASP.NET_SessionId=e5hlhemgbpcu0a3k0dphke5y; __RequestVerificationToken=ufS2rtMQMEHuRRQdV8umKRyJF4LMN4Pt9tNbF2QEDxQhvLWlZiycwD_vYNVlUwi6858t5-m8oLvW1CppLT1VuXVPeLE1
|
Host
|
development-server-iis.local
|
User-Agent
|
Mozilla/5.0 (Windows NT 6.1; WOW64)
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36
|
Response headers
Content-Length
|
1233
|
Content-Type
|
text/html
|
Date
|
Tue, 22 Jul 2014 04:0:16 GMT
|
Server
|
Microsoft-IIS/7.5
|
X-Powered-By
|
ASP.NET
|
Verification of the exploit
As you saw in the initial response header from the server, the Location header (highlighted in red) does not actually reveal an IP address (which is what we want).
This is deceiving as it turns out, IIS may reveal the internal IP Address if the request method is HTTP/1.0 instead of HTTP/1.1
To verify this issue, I used https://development-server-iis.local/images/. As this issue is reproducible in HTTP/1.0, we can verify it via TELNET.Using TELNET, make the request as follows:
telnet /images HTTP/1.0
The following Response is received:
The resolution
As IIS server sometimes leaks its internal IP address in a header field, to combat it we can specify the host name to use for redirection. To do so, we will use “ServerRuntime”.
The <serverRuntime> element configures the following settings that are related to the Internet Information Services (IIS) 7 server runtime:
- Setting the enabled attribute to true will configure IIS 7 to serve content on the URL where the <serverRuntime> element is configured; setting the enabled attribute to false will configure IIS 7 to not serve content for that URL.
- The alternateHostName attribute specifies a host name that is different from the computer name in the HTTP Content-location head
Note: This is compatible in the following versions:
Version | Notes |
---|---|
IIS 8.5 | The <serverRuntime> element was not modified in IIS 8.5. |
IIS 8.0 | The <serverRuntime> element was not modified in IIS 8.0. |
IIS 7.5 | The authenticatedUserOverride attribute was added in IIS 7.5. |
IIS 7.0 | The <serverRuntime> element was introduced in IIS 7.0. |
IIS 6.0 | The <serverRuntime> element replaces the following IIS 6.0 metabase properties:
|
Information you need
Before you commence, you will need to know the
Name of website
This is visible in “Internet Information Services Manager” (inetmgr)
As you can see, in our case, the name of the Website is “WebTier”
Host Name
In our case, the name of the host was “development-server-iis.local”
Steps to resolve
- Log into the server that hosts the Web Tier of Support Point application as an Administrator and open an administrator command prompt.
- Navigate to AppCmd.exe (is located in the %systemroot%\system32\inetsrv\)
- Using AppCmd enable server runtime for your Application using the following command
appcmd.exe set config "WebTier" -section:system.webServer/serverRuntime /enabled:"True" /commit:apphost (Note: Here you will need to replace WebTier with the name of your website.) - Using AppCmd enable server runtime for your Application using the following command
appcmd.exe set config "WebTier" -section:system.webServer/serverRuntime /alternateHostName:"development-server-iis.local" /commit:apphost (Note: Here you will need to replace WebTier with the name of your website. You will also need to replace development-server-iis.local with your host name.) - Restart the website via “Internet Information Services Manager” (inetmgr)
Verification of Resolution
To verify if this has resolved the issue, we can use telnet in a similar way to when we verified the existence of the exploit. The response received shows that the issue has been resolved.
Using TELNET, make the request as follows:
telnet /images HTTP/1.0
The following Response is received:
References: http://www.iis.net/configreference/system.webserver/serverruntime
The command "telnet /images HTTP/1.0" doesn't return what you have documented here.
ReplyDeleteI'm working on a Server 2012 R2 server running Exchange 2016.
When I run "telnet /images HTTP/1.0" I get
C:\Windows\System32\inetsrv>telnet /images HTTP/1.0
telnet [-a][-e escape char][-f log file][-l user][-t term][host [port]]
-a Attempt automatic logon. Same as -l option except uses
the currently logged on user's name.
-e Escape character to enter telnet client prompt.
-f File name for client side logging
-l Specifies the user name to log in with on the remote system.
Requires that the remote system support the TELNET ENVIRON option.
-t Specifies terminal type.
Supported term types are vt100, vt52, ansi and vtnt only.
host Specifies the hostname or IP address of the remote computer
to connect to.
port Specifies a port number or service name.
Please help.
Here is how-to:
Deletetelnet [Your IIS IP address] 80
and then type the below when you get a new prompt:
GET /images HTTP/1.0
Sample below:
> telnet 192.168.85.22 80
Connecting to 192.168.85.22:80...
Connection established.
To escape to local shell, press 'Ctrl+Alt+]'.
GET /images HTTP/1.0
HTTP/1.1 404 Not Found
Content-Type: text/html
Server: Microsoft-IIS/7.5
X-Powered-By: ASP.NET
Date: Wed, 04 May 2016 06:16:31 GMT
Connection: close
Content-Length: 1238