Our security administrator sent over a few security ‘vulnerabilities’ that had been flagged during a recent audit. One of them was a finding that one of our websites was leaking an internal IP. All I was given to track this down was the output from the auditor’s Nessus scan:
Nessus was able to verify the issue with the following request :
GET autodiscover/autodiscover.xml HTTP/1.0
Accept-Charset: iso-8859-1,utf-8;q=0.9,*;q=0.1
Accept-Language: en
Connection: Close
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)
Pragma: no-cache
AcceptL image/gif, image/x-xbitmap, image/jpeg, impage/pjpeg, image/png, */*
Which returned the following IP address :
10.10.0.31
After some quick research, I learned that this is actually Microsoft Exchange Client Access Server Information Disclosure. That it was being termed a vulnerability was pretty generous use of the term by our auditors in the PCI Compliance Report. Knowing an internal IP isn’t actually going to open the door for an attacker, but it could be useful as part of the enumeration or in a wider attack, the internal IP address might be very useful.
This vulnerability is usually found in conjunction with Web Server HTTP Header Internal IP Disclosure, which returns the internal IP in the location field. However, a previous audit had found that and I’d remediated it. I wonder how come this first audit didn’t find the Microsoft Exchange Client Access Server Information Disclosure vulnerability? Hmm.
In both of these ‘vulnerabilities’, an attacker can send an IIS webserver a specially-crafted HTTP 1.0 GET request, without any host header set. This causes the server to return its internal IP address in the reply. The reason for this is that the HTTP 1.0 protocol does not require the host header to be set by the client in the request. The HTTP 1.1 protocol requires the client to specify a host in the header, so is not affected.
Once I sorted out what I was looking for, it was time to replicate the findings, so that I can self-test that the ‘vulnerability’ has been remediated.
I love the chocolatey package manager for Powershell, especially since Windows doesn’t ship with anything useful. (WinGet seems to be what Microsoft is positioning as their Package Manager, but it’s far behind chocolatey at this point). In any case, since I have chocolatey already installed, let’s use it to download and install the openssl package:
choco install openssl
Wow, that was pretty easy, right? Let’s get started by opening a connection to the Exchange server using SSL/TLS:
C:\Program Files\OpenSSL-Win64\bin>openssl s_client -host 206.98.14.28 -port 443
CONNECTED(00000130)
Can't use SSL_get_servername
depth=1 C = GB, ST = Greater Manchester, L = Salford, O = Sectigo Limited, CN = Sectigo RSA Domain Validation Secure Server CA
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 OU = Domain Control Validated, OU = PositiveSSL Multi-Domain, CN = webmail.company.com
verify return:1
---
Certificate chain
0 s:OU = Domain Control Validated, OU = PositiveSSL Multi-Domain, CN = webmail.company.com
i:C = GB, ST = Greater Manchester, L = Salford, O = Sectigo Limited, CN = Sectigo RSA Domain Validation Secure Server CA
1 s:C = GB, ST = Greater Manchester, L = Salford, O = Sectigo Limited, CN = Sectigo RSA Domain Validation Secure Server CA
i:C = US, ST = New Jersey, L = Jersey City, O = The USERTRUST Network, CN = USERTrust RSA Certification Authority
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIGkzCCBXugAwIBAgIQeMhcbdyCJZhuKNK1eI9BnDANBgkqhkiG9w0BAQsFADCB
jzELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G
A1UEBxMHU2FsZm9yZDEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTcwNQYDVQQD
Ey5TZWN0aWdvIFJTQSBEb21haW4gVmFsaWRhdGlvbiBTZWN1cmUgU2VydmVyIENB
MB4XDTE5MTEwNTAwMDAwMFoXDTIxMTEwNDIzNTk1OVowZTEhMB8GA1UECxMYRG9t
YWluIENvbnRyb2wgVmFsaWRhdGVkMSEwHwYDVQQLExhQb3NpdGl2ZVNTTCBNdWx0
aS1Eb21haW4xHTAbBgNVBAMTFHdlYm1haWwuYWdyaWNvcnAuY29tMIIBIjANBgkq
hkiG9w0BAQEFAAOCAQ8AM11BCgKCAQEAzkoRlNCs5fI4iiNvh2YcaV3y3KynScoj
F7sk8frQY1iYBrQ4oLfDI2h+Np7a21kvdMyYufLzWeAz1n0EDu29/kkp8QBIVaDU
CgCNdsocnvwC41E7Qyc9wumBRNWbz0c4B7tyDvhImgBfl6IIXUe+cy/KsrqWb3Tq
mJKJ7acSBNzRcPgK8qUbUCdtNixhBRruWKjnQ7qwmzLwsRozFZGExUCms5/MX4Od
uZ5UHWGYZed+w30vu86Hy1/jf0VWeDGSAsiPUySLq55fvwClyRftN1aS9bwROrvE
sTJ1rAkR26wUFNyQi9ijkOEPCh2TqyclQNvRnokSI346ZMKKkaPpFwIDAQABo4ID
EjCCAw4wHwYDVR0jBBgwFoAUjYxexFStiuF36Zv5mwXhuAGNYeEwHQYDVR0OBBYE
FKb+bHu4DBzyNq5bUYs8Ppfr2EXFMA4GA1UdDwEB/wQEAwIFoDAMBgNVHRMBAf8E
AjAAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjBJBgNVHSAEQjBAMDQG
CysGAQQBsjEBAgIHMCUwIwYIKwYBBQUHAgEWF2h0dHBzOi8vc2VjdGlnby5jb20v
Q1BTMAgGBmeBDAECATCBhAYIKwYBBQUHAQEEeDB2ME8GCCsGAQUFBzAChkNodHRw
Oi8vY3J0LnNlY3RpZ28uY29tL1NlY3RpZ29SU0FEb21haW5WYWxpZGF0aW9uU2Vj
dXJlU2VydmVyQ0EuY3J0MCMGCCsGAQUFBzABhhdodHRwOi8vb2NzcC5zZWN0aWdv
LmNvbTA6BgNVHREEMzAxghR3ZWJtYWlsLmFncmljb3JwLmNvbYIZYXV0b2Rpc2Nv
dmVyLmFncmljb3JwLmNvbTCCAX8GCisGAQQB1nkCBAIEggFvBIIBawFpAHYAfT7y
+I//iFVoJMLAyp5SiXkrxQ54CX8uapdomX4i8NcAAAFuPDgr2gAABAMARzBFAiAi
1bJ3H3IUyTUswT99xLn8P2xHsFjAm4FjcuqpbSdgxAIhAPZOftlPa1H1jQPQ1ESb
IMox3lbDRSrPOOESq+oGMCPZAHcARJRlLrDuzq/EQAfYqP4owNrmgr7YyzG1P9Mz
lrW2gagAAAFuPDgrzgAABAMASDBGAiEAgNOhZoOzgj8DwuR516eWmpms/RmaQ61x
5z8CAnfYOL0CIQD5ODhJYisT5s7oRmqXgEzCg84dWeysi5/DjYzWvlqzFQB2AFWB
1MIWkDYBSuoLm1c8U/DA5Dh4cCUIFy+jqh0HE9MMAAABbjw4K5wAAAQDAEcwRQIg
adxDdH5iWyGh6tReXl/1t0zLEBcPwXe24St5WYnSwlcCIQC5RKhMAD63eyKpojIo
6fJocT/P6SBsfAykYhwThDFIPDANBgkqhkiG9w0BAQsFAAOCAQEAnUwWuOimEN5k
zzXFVVDFdwRYmTdnW7fzOgXnQKVmtkqAXiL0Qp05OnUq7qPJuTaOR+KaGPS0nnLN
b3/U3SimzH+tukkDZWcVch7tFzrEzpmWzighsQrzdCO0fv7SL3un7aKxQzf/u+se
iCZ5F8W40+YmZq8mW7LUdYINbtR/vGgays/7xzjWioWVjbgNsWiFdpmZ/Fch1H9q
m7UoFGNcTPDQrsg5rI2fKU/JBxWWqaUlWQ6DClhzwBp55DY3MGCoPesiiIU0HN/7
GyqwDIklkHOX6pRRmlXb5ZEK31Bo4qvwv/yolil83NL1q/Lk3C64jLmPEtH5rJy1
JaY6tu+MsA==
-----END CERTIFICATE-----
subject=OU = Domain Control Validated, OU = PositiveSSL Multi-Domain, CN = webmail.company.com
issuer=C = GB, ST = Greater Manchester, L = Salford, O = Sectigo Limited, CN = Sectigo RSA Domain Validation Secure Server CA
---
No client certificate CA names sent
Peer signing digest: SHA256
Peer signature type: RSA-PSS
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 3885 bytes and written 683 bytes
Verification error: unable to get local issuer certificate
---
New, TLSv1.3, Cipher is TLS_AES_128_GCM_SHA256
Server public key is 2048 bit
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 20 (unable to get local issuer certificate)
---
At this point, openssl has successfully established the connection and is awaiting a case-sensitive command. Let’s send the HTTP 1.0 packet to the autodiscover URL. You may need to press ENTER a couple of times:
GET /autodiscover/autodiscover.xml HTTP/1.0
HTTP/1.1 401 Unauthorized
Server: Microsoft-IIS/10.0
request-id: e1722265-bc09-4d32-a25e-02bf98f7d8f9
X-SOAP-Enabled: True
X-WSSecurity-Enabled: True
X-WSSecurity-For: None
X-OAuth-Enabled: True
X-OWA-Version: 15.1.2308.14
WWW-Authenticate: Negotiate
WWW-Authenticate: NTLM
X-Powered-By: ASP.NET
X-FEServer: EXCHANGE02
WWW-Authenticate: Basic realm="10.1.0.31"
Date: Fri, 17 Sep 2021 19:04:53 GMT
Connection: keep-alive
Content-Length: 0
Strict-Transport-Security: max-age=15552000
closed
And there it is! The internal server name and IP, in black and white. Thanks for nothing, IIS.
Alright, let’s go about fixing this. Instead of fixing this in IIS with the URL-Rewrite module, I decided to use Netscaler.
- The same change is made on just 2 Netscaler devices, vs. 5 Exchange servers
- The changes are not dependant on IIS, which may possibly be reset by patches or other installed software
- Netscaler is where I generally do this sort of thing (consistency leads to ease of administration)
In any case, this is what Netscaler will do:
- Any replies from the Webmail object are inspected for the WWW-Authenticate header.
- If it’s found, the WWW-Authenticate header is deleted as well as any X-FEServer header.
I accomplished this with a couple of Responder Policies in Netscaler:
add rewrite action RW_ACTION_OWA_FEServer delete_http_header X-FEServer
add rewrite action RW_ACTION_OWA_WWWAuthenticate delete_http_header WWW-Authenticate
add rewrite policy RW_POLICY_OWA_FEServer "HTTP.RES.HEADER(\"X-FEServer\").EXISTS" RW_ACTION_OWA_FEServer NOREWRITE
add rewrite policy RW_POLICY_OWA_WWWAuthenticate "HTTP.RES.HEADER(\"WWW-Authenticate\").EXISTS" RW_ACTION_OWA_WWWAuthenticate NOREWRITE
bind lb vserver VSRV-Exchange-OWA-External -policyName RW_POLICY_OWA_WWWAuthenticate -priority 100 -gotoPriorityExpression NEXT -type RESPONSE
bind lb vserver VSRV-Exchange-OWA-External -policyName RW_POLICY_OWA_FEServer -priority 110 -gotoPriorityExpression END -type RESPONSE
Let’s repeat the test and make sure that the internal information is no longer returned:
get /autodiscover/autodiscover.xml HTTP/1.0
HTTP/1.1 401 Unauthorized
Server: Microsoft-IIS/10.0
request-id: 068763fb-67ff-4f09-8ca9-02139957f4c2
X-SOAP-Enabled: True
X-WSSecurity-Enabled: True
X-WSSecurity-For: None
X-OAuth-Enabled: True
X-OWA-Version: 15.1.2308.14
X-Powered-By: ASP.NET
Date: Fri, 17 Sep 2021 19:16:43 GMT
Connection: keep-alive
Content-Length: 0
Strict-Transport-Security: max-age=15552000
closed