One of my pet peeves is users running "Security Scanners" against their servers and treating the resulting report as Gospel...
Oh my gosh, I have to fix all of these vulnerabilities in IIS6 that this report lists! Such an insecure piece of software, this IIS6 is!
... without understanding the basic premises of security for a server. I know, I know, most users do not "get" security because they treat it as a destination which the "Security Scanner" allows them to reach. But, I take solace in that the destination is usually more secure than the point of origin, so I guess that is good. 😉 Like any social lemming, users get a warm-fuzzy feeling of accomplishment at checking off all the check boxes, and security firms capitalize on that. Now, the goal of getting all boxes checked has been accomplished... so is the server forever secure?
Here is an illustrative situation...
During a recent security scan of our IIS 6 box, it was shown that the IIS Version, 6 in this case, and the Internal IP address of the box were being shown externally.
Why would this be and how can I fix this.
The box is natted behind a firewall.
Actually, neither the revelation of the IIS version nor the Internal IP address are security issues. They are really instances of insecurities in the the HTTP protocol itself. What, you actually think that the HTTP protocol is secure? 😉
For example, we all know that Basic Authentication passes username:password around in clear text, so why does IIS allow Basic Authentication without SSL? Because that's what the specification allows - even though doing it is terribly insecure. We all should know that. Clearly, IIS's only responsibility is to give you a choice to securely configure your server otherwise (i.e. suggest and conduct Basic Authentication over SSL), but the ability to have such insecure configuration is not an issue to fix.
Internal IP Revelation
If you think about it, this is really a problem introduced by the NAT but not solvable by the NAT.
HTTP Specification allows the return of Content-Location: header (in absolute and relative forms) as well as Location: header (in absolute form) for the benefit of the client and caches, telling the client where the server thinks the resource comes from or where the client should redirect to.
Normally, this is ok because the server's Name/IP is also the public Name/IP. However, in the NAT scenario:
- The server only knows its Internal Name and Internal IP since it is on the Internal Private Network
- It is the NAT that translates access to External IP into access to Internal IP (and route the response back out)
So, what happens when the client makes a request that makes the server return Content-Location (via a static file) or Location: (via a 302 courtesy redirection)? Well, the Server only knows about its TCP bindings to the Internal Name/IP and does not know about the NAT, so it is only logical for it to return the Internal Name/IP on those response fields... which is an information disclosure when those responses are subsequently routed Externally by the NAT.
Another way to view the situation is to see that the problem is that the NAT only translates at the TCP/IP level from External to Internal and vice-versa. It fails to translate at the logical HTTP level (or any other higher level) from Internal to External when it NAT's the request. However, I do not totally blame the NAT because it is nearly impossible for it to provide logical Internal-to-External translation correctly.
Thus, this is really just an insecurity allowed by the HTTP specification. How can the server be secure when it has to tell such information to anonymous clients? The work-around on IIS6 is provided with KB 834141. Basically, IIS gives you a metabase property that allows you to control which string to use, instead of Internal Name/IP, for those revealing Content-Location: and Location: headers. It's a real hack around the HTTP specification and the NAT, but it is a practical solution.
Server Version Revelation
In the case of the Server: header, HTTP specification's culpability is even clearer. The specification itself calls out the possibility:
Note: Revealing the specific software version of the server might
allow the server machine to become more vulnerable to attacks
against software that is known to contain security holes. Server
implementors are encouraged to make this field a configurable
Great! The HTTP designers saw this possibility and tried to warn implementers, so the fact that IIS has no configuration to not send the Server: header is just proof that Microsoft still does not get security, right?
Well, if you think that hiding the server version actually *improves* security, then think again. Security through obscurity does not work. When doing security analysis, you always assume that the adversary has infinite time, resources, and resiliancy, so even if you hide it, they will find it.
In the case of Server Version, the attacker has other ways to determine it, such as:
- Making a series of innocuous-looking HTTP requests whose different responses "footprint" a server version
- Making a series of subtle TCP connections whose different behaviors "footprint" the OS and server version
Ok, playing devil's advocate... suppose you are able to hide the Server: header and eliminate all "footprints" from external detection so that you keep your server software version a complete secret. Does that make your server more secure against version-specific attacks?
Let's suppose that you are running a version of server software with a certain known vulnerability which is under active exploitation. Hiding your server version does little good because to obtain the maximum damage, a hacker or worm will simply try the exploit against any server REGARDLESS of version - it takes longer to determine the version than to just send the payload and see if it works.
So, even though you manage through great lengths to keep your server software version a complete secret, you still get automatically exploited if you run vulnerable software. The Security Analysis view of this issue says that you deal with this threat by never allowing the outside world to see your vulnerable software system. Either take it offline, or make sure you are always patched. Running unpatched and obscuring software version is simply a ticking timebomb.
In other words, removing the Server: header does not improve security.
But, it does seem to buy users a nice warm-fuzzy feeling of accomplishment at checking off that check box, so I guess that's a positive. 🙂 Anyways, the IIS team provides URLScan as an optional tool to do this task (and many other security-conscious tasks).
So, do you still think that:
- Public specifications like HTTP are secure? When it allows username:password over clear text, anonymous requests, etc...
- NAT and Firewall is somehow going to protect you when running Server Software? When NAT/Firewall just look at TCP/IP level traffic and offers no defense at the logical layers like HTTP???
- Hiding Server Software Version helps maintain security? When most exploits simply disregard server version.
Hopefully, this helps to put things into perspective... and how Security Scans may be useful but far from Gospel.