07- IIS 7.5 on Windows 2008 R2 with ModSecurity 2.7.2


We will assume that we have an existing infrastructure in place, including Active Directory and DNS. In the example, the Active Directory domain will be named class.tu, with domain controller giskard.class.tu at

Configure the networking for the new server; in this example we set the IP address of the web server to

We also configure the name and domain of the server; in the example, the web server will be named kalgan.class.tu. We will join the web server to our domain.

All other settings are in their default state. In particular, we have not added any additional roles to our server.


Run the Add Roles Wizard (which can be found on Initial Configuration Tasks), select Web Server (IIS). In Windows 2008 (not R2) It will ask to also install some additional features (Windows Process Activation Service), we will do so. There are a number of potential roles this system can take on. All of the default features will be accepted (Static Content, Default Document, Directory Browsing, HTTP Errors, HTTP Logging, Request Monitoring, Request Filtering, Static Content Compression, IIS Management Console). We will add the following:

  • Logging Tools
  • Basic Authentication
  • Windows Authentication
  • URL Authorization
  • IP and Domain Restrictions
  • IIS Management Scripts and Tools

Note that we will not be discussing important topics like ASP, ASP.NET, CGI scripts, and ISAPI. Sorry.

If you want to install an FTP server on the machine, this is where you do that as well. We won’t.


The basics

The primary tool for managing your IIS web site is the IIS Manager. To find it, navigate Start → Administrative Tools → Internet Information Services (IIS) Manager. Expand the tree on the left.

IIS Manager

First view the node IIS (UNSEEN\administrator) [The text UNSEEN\administrator will be replaced by your particular domain & user combination.] This gives you the data for the IIS installation as a whole.

Expand the Sites node. Now you see a list of all of the sites running on that
server. A Default Web Site already exists.

Expand the Default Web Site node. Notice that many of the icons are the same as the icons for the IIS installation as a whole.

Let us add some content to the default web site. The default directory for the IIS web site is c:\inetpub\wwwroot. You can visit that site directly in file explorer; you can also open that folder directly from the action pane in IIS Manager. From the tree on the left, select IIS → Sites → Default Web Site. From the action pane on the right side, click the link “Explore”. The default install has two documents- an image (welcome.png) and a web page (iisstart.htm). View the contents of iisstart.htm, both in a browser and in a text editor. Does the image have any intreresting properties?

Create a web page, called index.html and place it in the c:\inetpub\wwwroot directory. Note that UAC may make this process more enjoyable than you would expect. I created my example file in the Documents library and copied it over to the proper directory; I am sure that there are other options.

Verify that your document is served.

Though there is a default web site already set up, let’s build a second. Go back to the IIS manager, then navigate Sites (rt click) → Add Web Site. Set the Site name: WebTest, and set the Physical path: C:\WebTest. You will need to create this folder- it does not yet exist. Set the Host name: webtest.class.tu, and start the web site immediately.


In c:\webtest, create the default file index.html. Now we need to set the permissions on our directory (and files) so that the IIS server can read the file to serve it. Ensure that the local group KALGAN\IIS_IUSRS has access to the directory (Read & execute; List folder contents; Read)(Replace KALGAN by the name of your host). To do this, select the folder (right click) → Security → Edit.

When IIS is installed, it creates the user IUSR_<computername> and the group IIS_IUSRS. Use of the IUSR account is deprecated and it is only kept for backward compatibility. Any user or account belonging to the group IIS_IUSRS can be used as the anonymous account for IIS to access file data. By default, the IIS_IUSRS group has no members.

Now we should verify that we have our permission set correctly. Navigate IIS Manager → KALGAN → Sites → WebTest. From the action pane on the right side, select Basic Settings; then select "Test Settings". You should receive no errors and only one warning. The warning will exist because, by default IIS will use pass-through authentication for the web site, meaning that the user that will be used to authenticate to the file system will be selected at run time. The validity of this user cannot be determined statically.

How do we account for the fact that our web server already has a web site? We will give our IIS machine a second IP address, with a second DNS entry. Go to network properties (e.g. Network & Sharing Center → View Status → Properties -→ Internet Protocol Version 4 → Properties → Advanced → IP Settings → Add) and add a second IP address to this NIC- say

Second IP

Since our web server is joined to a domain that is also running a DNS server, the server will automatically add both a A and a PTR record matching the hostname with the new IP address. Indeed, looking at the DNS Manager, we will see both addresses:


A lookup for this hostname will return both IP addresses:

C:\Users\seldon>nslookup kalgan
Server:  giskard.class.tu

Name:    kalgan.class.tu

Of course, this is not the behavior we want. Instead, we will delete the both the original name and the duplicate from the DNS server (from both the forward and the reverse lookup zones), and add new records (both A and PTR) for webtest.unseen.disc.tu at IP address and for hublands.unseen.disc.tu at When we are finished, we can verify that the nameserver works as we expect:

C:\Users\seldon>nslookup kalgan
Server:  giskard.class.tu

Name:    kalgan.class.tu

C:\Users\seldon>nslookup webtest
Server:  giskard.class.tu

Name:    webtest.class.tu

Go to another machine & visit the pages http://kalgan.class.tu and http://webtest.class.tu. The test pages you created should appear.

Go to another machine & visit the pages and What pages appear? Did you expect that result? Clearly, there is more to learn.

The IIS Manager interface

Let us spend some time learning about the different features of the IIS Manager.

Default document

If no document is specified in a URL, then the IIS will attempt to return a default document. The precise document is specified by the Default Document. This can be set at the web server level, or at the level of the individual sites. From IIS Manager, select either the web server (KALGANin this example) or the individual web sites (Default Web Site or WebTest in this example). In each case, you will be able to modify the Default Document. Settings made at the server level will propagate to the individual sites.

The default settings include 5 documents. What are they?

If your site uses a particular document as its index, then that document should be at the top of the list for performance reasons. When IIS looks for a default document, it looks through this list, in the specified order. It will not go on to the next item in the list until it is satisfied that the current list item does not exist, so if your default document is at the top of the list, then IIS will spend less time searching through the list.

Verify this by changing the order of the default document at the server level. Examine the default document order on the two web sites, and verify that the order of the documents has changed.

The ordering can also be specified at the site level. Verify this by changing the order of a site. Note that you will be warned that it will no longer inherit changes made by the parent. Note also that there is an option in the action pane to revert to the inherited default document. See also https://www.iis.net/ConfigReference/system.webServer/defaultDocument

Directory browsing

By default, if a directory is requested (e.g. http://webtest.class.tu/) and no default page exists (as described above), then IIS will return a 403 error. If directory browsing is enabled, then in this case IIS would return a listing of the files in the given directory.

Directory browsing can be enabled at either the server level or at the level of individual sites. To see how this occurs, rename the index.html file for the webtest site to something else- say indx.html. Load the page http://webtest.class.tu both with and without directory browsing enabled.

As an added bonus- What are the contents of the file web.config? (If you have done everything described above and allowed directory browsing at the site level rather than the server level, the file will exist. If not, well, is that my fault?) Will that file be served? What is the content of the file? See also http://www.iis.net/ConfigReference/system.webServer/directoryBrowse

Custom error pages

IIS can be set to provide customized error pages. By default, it provides an error page customized to the language of the browser. These error pages can be set at the server level or at the site level.

We saw above that, if directory browsing is not enabled and if no default page is present in a directory, then IIS will return a 403 error. Modify your system so that it returns a page of your choice when it encounters a 403 error, and verify that this works as expected from a machine other than the server.


In the action pane, notice the link for Edit Feature Settings. It gives three options for error responses

  • Custom error pages
  • Detailed errors
  • Detailed errors for local requests and custom error pages for remote requests.

Earlier you modified your system so that IIS would return a 403 error, as your directory has no default document and directory browsing is turned off. View that same page, but now from a browser on the server. Note the difference that detailed errors make. Note also the security implications of running a site where detailed errors are sent back to remote users.

Detail Error

For more details, see http://learn.iis.net/page.aspx/267/how-to-use-http-detailed-errors-in-iis-70/


Bindings are set on a per-site level, and determine to which requests a particular web site will respond. To see the bindings for a site, click on the site in the IIS manager, and then select bindings from the action pane. View the bindings for the default web site.

From this, we see that

  • Protocol is http
  • IP address is all unassigned
  • Port (TCP) is 80
  • Host name is unspecified
    • Now view the bindings for the new web site we created, webtest.


      Here we see that for the WebTest site,

      • Protocl is http
      • IP address is all unassigned
      • Port is 80
      • Host name is webtest.cs

      Recall the odd behavior we saw above, where we got the right web site if we specified the right name but the IP address always resolved the default web site. Use bindings and correct this issue. [This may not be as obvious as you think! Be sure to test out each of the following cases

      You should get the correct web site each time. To guide your decisions, consider the following questions: To which IP should each site respond? Does the name of the site matter?


      You can set limits on the network resources available to a particular site on your IIS server. To do so, select Limits from the action pane.

      Limit bandwidth usage (in bytes) refers to the number of bytes per second of bandwidth for that site; the default is 4294967295.

      Connection time-out specifies the time that IIS will wait before it disconnects a connection that is considered inactive. The default is 2 minutes.

      Limit number of connections refers to the maximum number of allowable simultaneous connections to the site. The default is 4294967295.

      Advanced topics

      Application pools

      The official documentation at IIS.net says “An application pool defines a group of one or more worker processes, configured with common settings that serve requests to one or more applications that are assigned to that application pool. Because application pools allow a set of Web applications to share one or more similarly configured worker processes, they provide a convenient way to isolate a set of Web applications from other Web applications on the server computer. Process boundaries separate each worker process; therefore, application problems in one application pool do not affect Web sites or applications in other application pools.” (http://www.iis.net/ConfigReference/system.applicationHost/applicationPools)

      We do not have sufficient time to discuss complex web applications in IIS, so we are going to leave this topic here.

      Virtual directories

      Virtual directories can be used in IIS in roughly the same fashion as we used aliases in Apache. In IIS, a virtual directory is a URL path that is mapped to a portion of the file system.

      Let us illustrate this with an example. Create the directory c:\webtest\dir1 and put an index file in that directory. Verify that the URL http://webtest.class.tu/dir1 can be used to retrieve that file.

      Create the new directory c:\outside and put an index file in that directory. Note that this is now outside the document root for either of our web sites.

      From IIS manager, right-click on the web site WebTest, and select Add Virtual Directory. For the alias, select dir2, and for the physical path, select c:\outside.

      Verify that the URL http://webtest.class.tu/dir2 now retrieves the index.html document from C:\outside.

      Investigate the question how IIS was able to gain file access to that file. Hint- if no other user is specified, the system uses the local user “Network Service” to access the file system. What are the effective permissions for that user?


      Command Line tools- appcmd.exe

      This program is located in %SystemRoot%\system32\inetsrv\Appcmd.exe. This is not part of the system path, so the file must be started directly from this directory, or the path variable must be modified.

      This is _the_ command line tool for working with IIS

      It must be run from an administator level command prompt. Note that, just because you started a command prompt as an administrator, this does not mean that you have an administrator command prompt. You must right-click on the entry in the Start Menu, and select “Run as administrator”

      As a simple example of the use of appcmd, run the command

      c:\Windows\system32\inetsrv\appcmd.exe list sites

      Can you determine what the tool did?

      In general, Appcmd looks for a verb and a noun

      Noun Verbs
      site list set add delete start stop
      app list set add delete
      apppool list set add delete start stop recycle
      vdir (virtual directories) list set add delete
      config list set search lock unlock clear reset migrate
      wp (worker processes) list
      request list
      module (web server modules) list set add delete install uninstall
      backup list add delete restore
      trace list configure inspect

      As examples, try
      To list all of the sites that IIS is serving:

      C:\Windows\System32\inetsrv>appcmd.exe list sites
      SITE "Default Web Site" (id:1,bindings:http/,state:Started)
      SITE "WebTest" (id:2,bindings:http/,state:Started)

      To stop IIS serving a particular site

      C:\Windows\System32\inetsrv>appcmd.exe stop site WebTest
      "WebTest" successfully stopped

      To have IIS start serving a particular site

      C:\Windows\System32\inetsrv>appcmd.exe start site WebTest
      "WebTest" successfully started.

      To have IIS list all of the virtual directories in use

      C:\Windows\System32\inetsrv>appcmd.exe list vdir
      VDIR "Default Web Site/" (physicalPath:%SystemDrive%\inetpub\wwwroot)
      VDIR "WebTest/" (physicalPath:C:\WebTest)
      VDIR "WebTest/dir2" (physicalPath:C:\Outside)

      Suppose that we want to change the default document to home.html. Create the document home.html in the main web site (C:\inetpub\wwwroot\home.html); then run the following

      c:\Windows\System32\inetsrv> appcmd.exe set config
      "Default Web Site" /section:defaultDocument /enabled:true

      Check that the default web page has been changed by viewing your default site in a web browser. Go to the Default Document section for the Default Web Site in the IIS Manager and verify that the configuration there has changed.

      Let’s enable directory browsing in the WebTest site. Rename any default documents in your document root; run the following

      C:\Windows\System32\inetsrv>appcmd.exe set config "WebTest" 
      -section:system.webServer/directoryBrowse /enabled:"True" 
      /showFlags:"Date, Time, Size, Extension"
      Applied configuration changes to section "system.webServer/directoryBrowse" for
      "MACHINE/WEBROOT/APPHOST/WebTest" at configuration commit path "MACHINE/WEBROOT/

      Verify the change, both by loading the page and by examining IIS manager.

      Just about anything that can be done through IIS manager can be done through appcmd.exe

      Configuration files.

      The configuration files are kept in a few location in .xml format. IIS is tightly integrated with the .NET framework (which we cannot cover in any significant detail.)

      The .NET framework global settings for the server is


      Though this is a .NET file, this lets IIS 7.0/7.5 share configuration information with ASP.NET

      The IIS 7.0/7.5 global configuration are in:


      This file has two important sections: <system.applicationHost> and <system.webServer>. This file is only modifiable by machine administrators. This is the main configuration file for IIS

      Each web site has its own file web.config in its root directory. This file may be hidden and you may need to enable “Show hidden files and folders” (File Explorer → Tools → Folder Options → View → Advanced Settings) to see
      it. If you compare the web.config file for the Default Web Site and the web.config for webtest, you will see which (if either) allows directory browsing.

      There is a file to allow IIS 7.0/7.5 to load its configuration from a remote location. This way multiple servers can share the same configuration. The file is


      There is a separate file to configure IIS manager; it is


      We will not need to edit these files manually.

      IP Address and Domain Restrictions

      One can deny access to the entire web site or just to a directory (including a virtual directory) or to an application by IP address range. Go to IIS manager and select the component (web site / directory / etc.), then select IPv4 Address and Domain Restrictions. Rules to allow or deny connections can then be simply set
      from the action pane. Rules will match in the order specified in the configuration.

      A rule at one level that contradicts a rule at a lower level appears to cause the server to throw an error (Code 500 rather than 403.6 is sent; checking the rules set will inform you that an error condition exists.)

      Note that if the server is accessible via IPv4 and IPv6 then denying an IPv4 host may let them simply connect via IPv6. It is possible to do IPv6 denials, but not using the tool in IIS manager.

      Try out the feature- choose one web site, and choose two systems to use to browse your site. Add a rule that disallows one site to view the site, and verify that this
      works as expected.


      A valuable IIS Security tool is UrlScan. The current version is 3.1, which supports IIS 5.1, 6.0 and 7.0. It is available online and on the labshare.

      To install URLScan, we need to install IIS Metabase. This is an IIS 6 feature that we have not yet installed. Navigate Start → Administrative Tools → Server Manager. From the tree, select Server Manager → Roles → Web Server. Under Role Services, select “Add Role Services” and choose IIS 6 Metabase Compatibility.


      Once Metabase is installed, URLScan can be installed by simply running the installer. Choose either the 32 bit or the 64 bit version as appropriate.

      The program is located in c:\Windows\System32\inetsrv\urlscan and the main configuration file is UrlScan.ini, in the same directory. A reasonably complete reference to the structure of that file can be found at http://learn.iis.net/page.aspx/938/urlscan-3-reference/

      Let us set up one of our web sites to use UrlScan. To do so, we first need IIS to use ISAPI Filters. This is another feature we have not yet installed. Navigate Start → Administrative Tools → Server Manager. From the tree, select Server Manager → Roles → Web Server. Under Role Services, select “Add Role Services” and choose ISAPI FIlters.

      With the ISAPI filters installed, go back to IIS Manager, and choose one of your web sites (or the entire IIS installation). Double-click on ISAPI Filters. From the action pane for ISAPI filters, select Add. Give this filter a name (UrlScan); for the executable select c:\Windows\system32\inetsrv\urlscan\urlscan.dll.

      2008 R2 x64- Kalgan (IIS)-2013-03-22-18-14-19

      The page http://learn.iis.net/page.aspx/476/common-urlscan-scenarios/
      describes some common ways in which UrlScan can be used.

      UrlScan can be used to filter requests based on the URL. Suppose that we want to automatically drop any request that contains the string “notnow” in the URL. First, create the file notnow.html in your default web site, and verify that it is served. Open the file C:\Windows\System32\inetsrv\urlscan\UrlScan.ini.

      In the section [Options] add the line


      This is case sensitive; don’t put blank spaces around the equals sign. It is easiest to do this on line 175. Read lines 118-173 to understand the syntax of the change we plan to make. Create the section [TestRule]:

      DenyDataSection=TestRule Data

      For the data, we create the section [TestRule Data]:

      [TestRule Data]

      Save the results.

      Now any request that has the text “notnow” in the URL will be filtered. Verify this by requesting the notnow.html page you just created.

      After veriyfing these results, examine the log data, in c:\windows\system32

      Suppose that you wanted to try to prevent SQL injection by scanning the query string to filter any request that contains any of the following

      • select
      • insert
      • update

      What UrlScan rule could you write? [The page http://learn.iis.net/page.aspx/476/common-urlscan-scenarios/ contains an even broader rule.]


      In IIS authorization is the process of determining whether or not IIS is
      allowed to access a particular resource. Unlike Apache, IIS can run as different users.

      Choices are:

      • NTFS ACL based authorization. This approach uses the file system to determine whether access to a resource is to be allowed. This requires IIS to have a valid Windows identity to determine if it has access to the file system. Because this approach uses file system permissions, it makes migrating sites from one host to another more complex.
      • URL Authorization. This is a new feature of IIS 7.0; it is not installed by default, though we did install it. In this approach, authorization rules are stored in the configuration rather than the file system. Rules can be set directly from IIS manager. They can also be set with Appcmd.exe from the command line.
        Appcmd.exe set config /section:system.webServer/security/authorization
      • ASP.NET URL Authorization. Applications in ASP.NET integrated mode can let ASP.NET provide the authorization system.

      We do not have sufficient time to really discuss these different authorization methods in more detail.


      This is the process of determining the identity of a user requesting an IIS resource. In some cases, this will let IIS impersonate that user to access resources (c.f. Authorization above). Choices are:

      • Anonymous authentication. This provides an identity for users who do not present
        credentials. The authenticated user identity will be a Windows anonymous user account. There are now three choices:

        • The built-in IUSR_ComputerName account (deprecated).
        • A custom account that you specify.
        • The identity of the IIS worker process that is processing the request (usually Network Service).

        If you do not want a portion of your web site accessed by anonymous users, then you must disable anonymous authentication for that portion of the web site- even if
        you enable other forms of authentication.

      • Basic authentication. This is the same RFC 2617 HTTP protocol based technique we
        we discussed for Apache. In particular, credentials are sent in plain text. This is not part of the default IIS install; we did install it. Users must authenticate with a valid local or domain account.
      • Digest authentication. This is part of the same RFC 2617 protocol based technique we we discussed for Apache. Because it is not commonly implemented, we will not
        discuss it in detail.
      • Windows authentication. This uses windows techniques for authentication (NTLM or
        Kerberos). This is not part of the default IIS install; we did install it. This does work on e.g. Firefox on Linux or Chrome on Windows (tested) but fails on Konqueror on Linux. This uses a challenge-response system that is more resistant to sniffing. (e.g. Cain & Abel did not sniff the hashes from FF/Linux → IIS).
      • Client certificate mapping authentication or IIS Client certificate mapping authentication. Neither of these were installed on our test system. These map SSL certificates to particular windows accounts which are then used to perform authorization. We will not discuss these in detail.

      To illustrate these principles, let us apply some test cases to our default web site.
      From IIS Manager, select the Default Web Site, then select the Authentication button. Notice that three types of authentication are listed (Anonymous, Basic, and Windows) and that two of the three are disabled.

      Disable Anonymous Authentication, and try to load a page from the web site. What occurs?

      Enable Basic Authentication to the web site and try again. For credentials, try a local account on your IIS Server. Between each attempt, close and restart your
      browser; you do not want to be sending or using cached credentials.

      For credentials, try a domain account, but specify the domain [e.g. for the username, use domain\username]

      Repeat, but for credentials, try a domain account without specifying the domain.

      Use a sniffer to watch this traffic. Can you find the passwords in cleartext? [Hint- Yes.]

      Disable Basic Authentication and enable Windows Authentication. Does anything change? Does it matter if you are using a Windows machine or a Linux machine?

      Now enable both Anonymous Authentication and Basic Authentication. What behavior do you observe?


      Getting a certificate

      Let us create a certificate request, get it signed by our CA, and install it.

      First, we need to make sure that our CA is going to be trusted by the server. In Week 6, we stored the CA Server certificate (not the private key!) in the file /etc/pki/CA/certs/ca.crt. Copy that file from the CA to the web server.

      Installing this certificate in Windows 2008 R2 is much more challenging than it has been in earlier versions of Windows Server. From the Start menu, select Run and choose "mmc"

      From mmc, select Add/Remove Snap-in, and select Certificates. You want the snap-in to manage certificates for the Computer account for the Local Computer. Select OK to be presented with a Window like the following.

      Right-click on Trusted Root Certificates → All Tasks → Import. From the Certificate Import Wizard, select the certificate CA.crt that you brought over from the CA. Be sure that you store the result in the Trusted Root Certification Authorities store.

      Now that we have told the system to trust certificates signed by our CA, we need to create a certificate signing request (.csr) as we did in Apache. To do so, navigate IIS Manager → IIS, and select Server Certificates; this is done at the server level- not the site level. Select Create Certificate Request from the Action Pane. Complete the form, but be sure to use your host name for your site (e.g. hublands.unseen.disc.tu) as your Common Name.


      Select Microsoft RSA SChannel Cryptographic Provider and choose a bit length. Specify the name of the request, say hublands.csr. If you don’t specify a directory, the file ends up in C:\Windows\System32.

      Open the file in notepad and note how this is essentially the same format we saw for Apache.

      Copy the csr to your CA. Sign the certificate as we did in Week 6; e.g.

      [root@smyrna ~]# openssl x509 -req -days 365 
      -in /home/seldon/Desktop/kalgan.csr -CA /etc/pki/CA/certs/ca.crt 
      -CAkey /etc/pki/CA/private/ca.key -set_serial 01 
      -out /etc/pki/CA/newcerts/kalgan.crt
      Signature ok
      subject=/C=US/ST=MD/L=Towson/O=Towson University/OU=Security Laboratory/CN=kalgan.class.tu
      Getting CA Private Key
      Enter pass phrase for /etc/pki/CA/private/ca.key:

      Copy the signed certificate kalgan.crt back to the IIS server.

      Return to IIS Manager → Server Certificates and select Complete Certificate Request from the Action Pane. Complete the form, including the location of the certificate and a “Friendly name” for the result- say KalganSSL.

      At this point, the SSLTest certificate should appear in the list of server certificates.


      Looking at the properties of the certificate, you should see it issued to the common name you selected earlier (kalgan.class.tu) and issued by the common name of the CA, which we called smyrna.cosc.tu.


      Creating the site

      Now let us create a new site that will use SSL and the certificate we just installed.
      To create a new site, we use IIS Manager, and from the tree select IIS → Sites (right click) → Add Web Site. Complete the form. Use any Site name you wish, say KalganSSL

      Let’s create a new directory (C:\SSL) to hold our site. We can continue to use pass-through authentication. Change the binding to use https, on port 443. Be sure to select the IP address that matches the host name (the common name) you selected for your certificate. Speaking of that certificate, select the certificate KalganSSL we had signed earlier.


      Add some content to our web site- say an index.html page

      Be sure to require SSL to visit the site; navigate IIS Manager → Web Site → SSL Settings; select “Require SSL”.


      Client certificates allow the server to trust the client rather than the (traditional) other direction. The client will need a certificate signed by a CA that the server trusts. These are rare, and we can happily ignore them.

      Visit the web page from a browser that has the CA’s certificate listed as trusted. Be sure to specify https in the address!

      Hey- how do we get internet explorer to import our certificate? Navigate IE → Tools → Internet Options; Content → Certificates then select Import. Leave the Intended Purpose as <All>. From the Certificate Import Wizard, select the file that contains the certificate for the CA (ca.crt).

      Windows 8- Olivaw-2013-03-17-15-42-06

      Windows 8- Olivaw-2013-03-17-15-43-46

      For the purpose of our class, you can use as your certificate store the Trusted Root Certification Authorities. Note that Windows will be unable to automatically
      validate the certificate; this is expected behavior.


      Logging can be configured at the site level or at the IIS level. Select Logging from the IIS Manager, either for a site or for the IIS installation as a whole.

      The default location for the logs is %SystemDrive%\inetpub\logs\LogFiles. The logs are plain text files, stored either as UTF-8 (default) or ANSI (which is a superset of ISO 8859-1).

      There are a number of log file formats.

      • W3C (default). You can specify what is logged from the following list
        1. Date
        2. Time
        3. Client IP
        4. User name
        5. Service name
        6. Server name
        7. Server IP
        8. Server port
        9. Method
        10. URI stem
        11. URI query
        12. Protocol status
        13. Protocol substatus
        14. Win32 status
        15. Bytes sent
        16. Bytes received
        17. Time taken
        18. Protocol version
        19. Host
        20. User agent
        21. Cookie
        22. Referer
      • NCSA format is a fixed format that record remote host name, user name, date, time, request type, HTTP status code, and the number of bytes sent by the server. Items are separated by spaces; time is recorded as local time.
      • IIS format is an extension of NCSA that also records elapsed time, number of bytes sent, action and target file. The items are separated by commas.
      • It is possible to use other logging formats by creating a new COM component that implements the ILogPlugin or ILogPluginEx interface. We did not install this feature.

      Logs can also be sent directly to a database via ODBC logging. We did not install this feature.

      Logs can be centralized by having them written to a remote network share.

      Web Application Firewall

      ModSecurity is now available for IIS systems. The windows installer for version 2.7.2 is available on the labshare.

      Before we install ModSecurity though, we need to first install the Microsoft Visual Studio 2010 runtime libraries. There are two different libraries depending on whether the underlying system is 32-bit or 64-bit. The catch here is that if you skip this step, the ModSecurity installation will complete. It won’t actually work, and will cause your website to essentially die and cover your logs with errors, but the installation won’t actually fail, as such.

      After the runtime libraries are installed, the ModSecurity installation process is straightforward. The installer lets you customize a directory for the the installer and the users for which the system is installed, however he default directory and installation for all users suits us well. Agree to the license, and the tool will install.

      To configure ModSecurity, we start in the same fashion we did for our Apache server. The default install sets ModSecurity in C:\inetpub\wwwroot\owasp_crs, which is the location of the configuration file modsecurity.conf. Open that file. As before the first directive is

      SecRuleEngine DetectionOnly

      which tells ModSecurity to only perform detection, but not to take any action to modify or disrupt the connection. Once again, we modify this to read

      SecRuleEngine On

      As we did before, we also add a testing rule to our ModSecurity installation in the form

      SecRule ARGS, "zzz" phase:1,log,deny,status:503,id:1

      We can put this rule at the end of the ModSecurity.conf file. Save the result.

      What? It won’t save. Happy, happy, joy, joy.

      This is caused by a couple of factors. First, the file is marked read-only. You can see that by checking the properties tab for the file

      You can change that property so that the file is no longer read-only if you wish, though it will require UAC elevation. Even so, if you open the file in notepad and try to save, you will still be presented with an Access Denied message, even if you are a Domain Admin. This is because of the (very) restrictive set of permissions used in Windows 2008 R2. I found it simplest to save the file to the Desktop, and then copy it over; this allows for the additional required UAC elevation to take place.

      At this point, we now need to tell IIS to actually use ModSecurity. Suppose that we want to apply ModSecurity to the default web site, located at c:\inetpub\wwwroot. Earlier we saw that configuration changes in IIS manager for that web site would be reflected in the contents of the XML file c:\inetpub\wwwroot\web.config. [If we want to modify a different web site, then we modify the web.config file in the corresponding directory.]

      Update that file to include the contents

      <?xml version="1.0" encoding="UTF-8"?>
              <ModSecurity enabled="true" 
                 configFile="c:\inetpub\wwwroot\owasp_crs\modsecurity_iis.conf" />

      Note that if you have made other changes to he configuration for this web site, they will also be reflected in this file, and the result should be modified appropriately.

      Test the result as we did before. If you visit a web page like http://kalgan.class.tu/index.html?a=zz, then you should receive the correct page, but if you add the third "z" to the GET parameter and request http://kalgan.class.tu/index.html?a=zzz then your request should be blocked:

      Screenshot-Mozilla Firefox

      This will also be recorded in the logs. ModSecurity for IIS uses the Windows Application logs to store its results, and you will see an log entry of the following form to match the block action:


      If you modify the ModSecurity rules (say to remove our testing rule), you need to re-start the web server for the rules changes to take effect. This is not the same as re-starting the web site. From IIS manager, select the host and user (KALGAN(CLASS\seldon)) in this example; then from the Action Pane select restart.

      2008 R2 x64- Kalgan (IIS)-2013-03-17-19-56-28

      Only those rules that are in the directory c:\inetpub\wwwroot\owasp_crs\activated_rules will be used by ModSecurity. You can move additional rules from the base_rules, experimental_rules, optional_rules, or slr_rules subdirectories to the activated_rules subdirectory if you wish to use them; just be sure to re-start.

      Fingerprinting a Web Server

      Now let’s turn around and put on our black attacker’s hats for a moment. One of the first things an attacker wants to do when attacking a web server is to determine the precise version of the target web server. Finding this information out actually is not all that difficult, at least in most cases. How? We simply ask!

      One way to ask is to use telnet; in this case we connect to the web server, and issue a HEAD / HTTP/1.0 request (with two carriage returns!), and read the output:

      root@kali:~# telnet kalgan.class.tu 80
      Connected to kalgan.class.tu.
      Escape character is '^]'.
      HEAD / HTTP/1.0
      HTTP/1.1 200 OK
      Content-Length: 75
      Content-Type: text/html
      Last-Modified: Sun, 17 Mar 2013 14:36:55 GMT
      Accept-Ranges: bytes
      ETag: "403b7edf1c23ce1:0"
      Server: Microsoft-IIS/7.5
      Date: Thu, 21 Mar 2013 20:18:19 GMT
      Connection: close
      Connection closed by foreign host.

      Trying the same thing on our Apache server, we find instead

      root@kali:~# telnet terminus.cosc.tu 80
      Connected to terminus.cosc.tu.
      Escape character is '^]'.
      HEAD /index.html HTTP/1.0
      HTTP/1.1 403 Forbidden
      Date: Thu, 21 Mar 2013 20:20:59 GMT
      Server: Apache/2.2.15 (CentOS)
      Connection: close
      Content-Type: text/html; charset=iso-8859-1
      Connection closed by foreign host.

      Thus, our simple telnet command was able to determine that kalgan.class.tu is running IIS 7.5 (and so is on a Windows 2008 R2 system), while terminus.cosc.tu is running Apache 2.2.15 on a CentOS system. Not bad for telnet!

      You may be wondering why the IIS system returned a 200 (OK) code while the Linux system returned a 403 (Forbidden) Error. Well, ModSecurity was set up on both of these hosts. If you look at the log on the Linux system, you will see that /var/log/httpd/error_log contains the note:

      [Thu Mar 21 13:21:00 2013] [error] [client] ModSecurity: Access denied 
      with code 403 (phase 2). Operator EQ matched 0 at REQUEST_HEADERS. [file 
      [line "29"] [id "960008"] [rev "2"] [msg "Request Missing a Host Header"] 
      [severity "WARNING"] [ver "OWASP_CRS/2.2.7"] [maturity "9"] [accuracy "9"] 
      [tag "OWASP_TOP_10/A7"] [tag "PCI/6.5.10"] [hostname "terminus.cosc.tu"] 
      [uri "/index.html"] [unique_id "UUtrq38AAAEAAAfw6-UAAAAC"]

      showing the ModSecurity blocked the connection because it did not have a host header. It is interesting that this rule (modsecurity_crs_21_protocol_anomalies.conf) is not in the activated rules section for a Windows installation. If you add them, you will see that the request is similarly blocked

      root@kali:~# telnet kalgan.class.tu 80
      Connected to kalgan.class.tu.
      Escape character is '^]'.
      HEAD / HTTP/1.0
      HTTP/1.1 403 ModSecurity Action
      Content-Length: 1233
      Content-Type: text/html
      Server: Microsoft-IIS/7.5
      Date: Thu, 21 Mar 2013 20:31:15 GMT
      Connection: close
      Connection closed by foreign host.

      and as an added bonus we discover that ModSecurity is the reason for the block.

      Of course, you often don’t even need to be this sophisticated. Sometimes just grabbing the wrong page is enough. What happens on our Apache server is we ask for a non-existent page, say http://terminus.cosc.tu/fibble?

      Screenshot from 2013-03-22 17^%35^%03

      Oh look- it’ Apache 2.2.15!

      IIS is not quite so nice by default, but we will certainly know that it is IIS:
      Screenshot from 2013-03-22 17^%37^%17

      Modifying the Server String

      Since the server is providing the information the attacker is using to identify the server version, could we perhaps turn this off? On an Apache system, we can do this by modifying two variables. The ServerTokens variable determines the amount of information returned by the server, while ServerSignature determines the amount of information at the footer of an error page. You can modify these to reduce the amount of information provided, however you cannot perform radical surgery and claim that Apache is e.g. IIS.

      Well, actually you can, but it requires that you re-compile the source for Apache. Let’s not do that.

      What about IIS? If you have installed URLScan (and I know you did, because we covered earlier in the notes), then all you need to do is to modify Line 30 to read


      Now a request for the version yields only

      root@kali:/# telnet kalgan.class.tu 80
      Connected to kalgan.class.tu.
      Escape character is '^]'.
      HEAD / HTTP/1.0
      HTTP/1.1 200 OK
      Content-Length: 75
      Content-Type: text/html
      Last-Modified: Sun, 17 Mar 2013 14:36:55 GMT
      Accept-Ranges: bytes
      ETag: "403b7edf1c23ce1:0"
      Date: Fri, 22 Mar 2013 22:23:25 GMT
      Connection: close
      Connection closed by foreign host.

      Mind you, the error page still gives it away as IIS, but we already saw how to modify those pages as well. You could even make them look like an Apache error page. You know, if you wanted to. Hmmmm.

      Finally we note that you can do some of this in ModSecurity- at least for Apache. If you add the directive

      SecServerSignature "WEB SERVER SOFTWARE"

      to your modsecurity.conf file, then these attempts will use this string to identify the server:

      root@kali:/# telnet terminus.cosc.tu 80
      Connected to terminus.cosc.tu.
      Escape character is '^]'.
      HEAD / HTTP/1.0
      HTTP/1.1 403 Forbidden
      Date: Fri, 22 Mar 2013 22:28:20 GMT
      Accept-Ranges: bytes
      Content-Length: 5039
      Connection: close
      Content-Type: text/html; charset=UTF-8
      Connection closed by foreign host.

      This even holds true for the footer on an error page:
      Screenshot from 2013-03-22 18^%28^%56

      On the other hand, even though ModSecurity works on IIS, it does not (yet) appear that the SecServerSignature directive has any impact on IIS servers- this only appears to work for Apache.

  1. xFreshy
    May 24, 2013 at 12:59 pm

    Amazing article and almost the only one on this topic for IIS and ModSecurity. Nice work and very indepth. Please write more 🙂

  2. Vikas Karunakaran
    November 25, 2013 at 2:24 am

    Can we customize or filter the logs in the web server, created my ModSecuirty in any of the servers either Apache or IIS. If yes, how can I do it…?

  1. May 14, 2013 at 1:39 pm

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: