Serving The WebEssential Security Administration For IIS 6.0
IIS 5.0 administrators are familiar with the important security-related tasks required to harden and maintain a secure Web services environment. The many new features and capabilities of IIS 6.0, available with every version of Windows Server™ 2003, renders the previous version obsolete. If you're like me, when I first opened the IIS 6.0 user interface, I was surprised at how familiar it seemed. If you can configure security for an IIS 5.0 server, you're well on your way to managing an IIS 6.0 server. Nevertheless, experienced IIS administrators are sometimes caught by surprise trying to get their IIS 5.0 applications to work on IIS 6.0, prevented from doing so in certain scenarios because of the new security defaults and design.
With just a little research, you can avoid the bumps in the road that you would otherwise most certainly encounter. In this article, I'll review a few of the most important new items to add to your "must do" list, and I'll highlight how you can improve security in ways not possible before.
Identify Entries for Web Service Extensions
The troubleshooting question IIS administrators ask most frequently when they first deploy IIS 6.0 involves a new feature that is a bit surprising when first encountered. In the IIS Manager console, a new node has been added called Web Service Extensions (WSE), shown in Figure 1.
Figure 1** IIS Manager **
Don't let the innocent sound of WSE lead you to believe that you can deal with this after you get your application up and running. WSE has nothing to do with XML Web Services or FrontPage® Server Extensions. Rather, these settings control which executables and libraries are allowed to run on the Web server, and by default, nothing is allowed to run. (No, I'm not kidding.) Even if you set NTFS permissions to give everyone full control, unless you specifically allow an extension in Web Service Extensions, IIS will not run it. This is a perfect example of what Microsoft means by "secure by default."
Sub-Status Error Codes
The following list details the sub-status codes that were added for troubleshooting specific situations:
|401.7||URLAuthZ denied due to policy|
|403.20||Passport login failure|
|404.1||Denied due to MIME policy|
|404.2||Denied due to lockdown policy|
|500.16||UNC Username/Password incorrect|
|500.17||URLAuthZ store not found|
|500.18||URLAuthZ store cannot be opened|
|500.19||Bad file metadata|
|500.20||URLAuthZ scope not found|
This does not mean you will need to identify all scripts by full path and file name, but it does mean identifying all script engines. For example, in order to host ASP.NET applications, you must specifically allow ASP.NET as provided by aspnet_isapi.dll (which can be enabled during installation or with the Manage Your Server Wizard). You also need to create an "allow" rule for all DLL and executable files you invoke from a URL or redirect.
If you absolutely, positively have to get running today, you can set Web Service Extensions to not enforce any restrictions by enabling Allow All Unknown ISAPI or Allow All Unknown CGI, but in doing so you give up a great defensive security feature that can help protect you against current and future exploits. The following is a tip on how to quickly identify all the required entries you will need.
As part of the IIS 6.0 Resource Kit you'll find a very cool utility called Log Parser 2.1. This tool allows you to query many log files, text files, and other items too numerous to mention using a SQL query (Microsoft® SQL Server™ is not required). Copy Logparser.exe and the script Extensions.sql into the folder that contains the log files you want to analyze, and then run the following query from a command line in the log folder:
Log parser file: extensions.qry
This will create a unique list of all the file extensions that are involved in your real-world IIS server. On my machine, this results in the output shown in Figure 2.
Figure 2 Unique Extensions
Extension Query ------------ --------- .jpg 1306544 .gif 790245 .htm 407679 .asp 222184 .png 176696 .GIF 32983 .ico 23439 .txt 19564 .dll 4502 .exe 2379 .php 2233 .html 2065
With this info in hand, you can run another query on each executable file extension to identify URL paths to all your executables. To do this using Log Parser 2.1 type the following query (or modify extensions.qry) into Notepad and save it as extensions-uri.qry. This query looks more involved than it is, and with Log Parser 2.2 (due for release Fall 2004), it can be greatly simplified. In the meantime, the following query should work:
SELECT Distinct cs-uri-stem, SUBSTR(cs-uri-stem, LAST_INDEX_OF(cs-uri-stem,'.'), STRLEN(cs-uri-stem) ) AS Extension FROM ex*.log WHERE Extension = '.dll' and cs-method='GET' and sc-status=200 ORDER BY cs-uri-stem
With this query in hand, you can run it with the following command:
After the query has finished executing, you'll see output that looks something like Figure 3.
Figure 3 Executable Paths
cs-uri-stem Extension ------------------------------- --------- /_vti_bin/SHTML.dll .dll /_vti_bin/_vti_adm/admin.dll .dll /_vti_bin/_vti_adm/fpadmdll.dll .dll /_vti_bin/_vti_aut/author.dll .dll /_vti_bin/shtml.dll .dll
With just a few tweaks, you could use these same queries to scan your entire Web server farm. If you're a TechNet subscriber and you'd like to learn more about the Log Parser tool, you'll find a white paper introducing the tool in the April 2004 edition of the TechNet subscription available on CD, along with a beta version of Log Parser 2.2 on the Downloads CD.
Now you know how to utilize WSE to get your IIS 6.0 applications online and more secure. Adding entries to the list and allowing new applications to run is a simple process using the IIS Manager or using the iisext.vbs script.
Identify Required Entries for MIMEMaps
IIS 6.0 will not deliver content for which there is no MIMEMap entry. This is a new security feature that prevents IIS 6.0 from delivering content for any file type on the server, regardless of whether it is a known or unknown file type. For example, if you place new scripts on the server for a file type that is undefined, IIS 5.0 would deliver the content as text until the application mapping has been installed. This can also occur if a script engine is uninstalled while at the same time leaving the related scripts on the server.
You can view the list of defined MIME types by opening the IIS Manager, right-clicking on the computer icon, selecting Properties, and clicking the MIME Types Button (see Figure 4).
Figure 4** MIME Types **
Reviewing the list of file extensions you generated with the Log Parser tool from your existing IIS log files, if you find any MIME types that are legitimately required, you will need to add them to the MIME types list in IIS 6.0. While you are there, because you also know from the Log Parser list what isn't in use, you can safely remove any of those MIME types that are defined, but that aren't being used (and most likely there will be many). Of course, it's always a good idea to make a complete backup first in the unlikely event that you delete something you need.
Undefined MIME Types/Web Service Extensions
Let's say that one day after installing your IIS 6.0 servers, a user contacts you and says they are getting a 404—File Not Found message. You verify that the file is on the IIS server and that the user has rights to access the file. You try to request the file, and you get the same result—file not found. You restart the server to clear any problems, but it has no effect.
This exact scenario occurs when you try to access a file that is an undefined MIME type or an extension that is requested but not defined in the WSE. In both cases, the requested file can exist on the server with proper permissions, but IIS will return to the user a simple and intentionally misleading 404—File Not Found message.
Wouldn't it be nice if you had quick way to determine if a 404—File Not Found message is returned because the file is actually missing, or is one of these two special cases?
Figure 5** Logging Properties **
Your wish is granted! The IIS W3SVC log file on IIS 6.0 has a new field called the sub-status code that can specifically identify when a 404 error occurs because of a MIME type or WSE. To use the field, simply enable it in the log file Advanced properties page (see Figure 5). Right-click on a Web site in the IIS Manager, select Properties, click on the Properties Button on the Web Site tab, then click on the Advanced tab. Note that this field is only available when your log files are set to W3C Extended Log File Format. The sidebar entitled "Sub-Status Error Codes" lists the error codes that may get logged. Inspecting the contents of the sc-status field for 404 error and the sc-sub-status fields for Error 404.1 and 404.2 would quickly identify the problem in our example.
An Entirely New Log File
Since we're talking about log files, for security and troubleshooting purposes you should know about an entirely new log file available from IIS 6.0. A brief explanation helps to explain why this log is necessary.
IIS 6.0 contains a kernel-mode HTTP parsing engine and cache called http.sys. When the http.sys listener encounters an error, it requires a place to record it, and so its developers invented the httperr(x).log files which you can find in \system32\logfiles\httperr. Httperr logs have an entry when requests are rejected by the http.sys. Http.sys, which hands off requests to IIS 6.0 applications, won't take requests that do not meet specific criteria. Client requests for content must be well-formed HTTP 1.1, meet size constraints, not have any high-order bit characters, and not violate other well-defined rules (see INF: Http.sys Registry Settings for IIS for information on configurable parameters). An attacker will almost certainly leave tracks in this log, so be sure to include a review of the httperr logs located at \system32\logfiles\httperr in your regular monitoring tasks.
IIS 6.0 and NTFS Permissions
Many IIS servers store content in and under the \inetpub\wwwroot folder. With IIS 6.0, the wwwroot folder has tighter permissions than with previous versions of IIS, and you may need to make some modifications in order to once again get your applications working effectively.
For example, the IIS anonymous user account is given the Deny Write permission. You might need to modify this permission for certain scripts to work that need write permission for Web Forms or for other applications that write to the files in the context of the anonymous user.
Another more common problem arises when you don't use the \inetpub\wwwroot folder for content. There is a new group in IIS 6.0 called the IIS_WPG that will require at least read access to your entire site's content when you run ASP.NET applications. Failure to do so will result in the return of an ASP.NET error message similar to the following:
Exception Details: System.UnauthorizedAccessException: Access to the path "D:\data\txtinv.txt" is denied. ASP.NET is not authorized to access the requested resource...
Allowing the IIS_WPG access to the all your Web content will avoid this and other related problems.
Of course, this isn't a complete review, but these issues are at the top of the list of new security-related tasks for administering IIS 6.0. I would be remiss without mentioning that you should always keep your server(s) fully patched (make sure you visit Windows® Update frequently) and that you should continue to monitor for unusual activity. Don't forget to check out the aforementioned Log Parser tool, as it will make your IIS-related tasks easier. Also, keep an eye out for other new and exciting tools to assist with keeping your IIS servers running smoothly and securely.
Brett Hill is an IIS MVP and runs IISTraining.com, IISFAQ.com, and IISAnswers.com. He is a regular speaker at TechEd and Windows Connections conferences, and is considered one of the nation's leading authorities on IIS. You can reach Brett at IISTraining.com.
© 2008 Microsoft Corporation and CMP Media, LLC. All rights reserved; reproduction in part or in whole without permission is prohibited.