I am attempting to perform a path traversal attack on a vulnerable service hosted in IIS.
The service is something like this:
GET /api/download/{file-name}
The underlying code is something like this:
return File.Read("some/directory/" + fileName);
As written, this service is clearly vulnerable.
I can perform a path traversal attack when running locally using dotnet run
, which I gather uses the Kestrel web server. My attack payload is ..\..\secret.txt
, which is encoded and visible in the log:
Request starting HTTP/1.1 GET http://localhost/api/download/..%5C..%5Csecret.txt
I cannot reproduce this attack on the same app when hosted in IIS. It appears that IIS somehow normalizes the URI by interpreting the ..\
, which means it never hits my API. In other words, it attempts to hit the following endpoint:
GET http://localhost/secret.txt
I have tried a variety of different encodings for the ..\
character sequence, but no luck.
How can I work around this IIS behavior to perform a path traversal attack on this vulnerable app, hosted in IIS?
There appear to be several things preventing my path traversal attack. I was able to perform a path traversal attack by (1) double-encoding the payload and (2) removing or undermining the RequestFilteringModule and UrlRoutingModule modules in IIS. I was not able to reproduce an attack if either of these modules was present and fully-enabled.
First, I had to encode the \
character in my attack payload.
When I simply URL encode once, IIS (I assume) normalizes the URI, as I observed before:
http://localhost/api/download/..%5C..%5Csecret.txt
http://localhost/secret.txt
When when I perform the encoding twice, my payload does make it through to IIS:
http://localhost/api/download/..%255c..%255csecret.txt
http://localhost/api/download/..%5C..%5Csecret.txt
The RequestFilteringModule module responds to my attack with a 404 response:
The request filtering module is configured to deny a request that contains a double escape sequence.
We can disable this feature by removing the module or setting the allowDoubleEscaping
flag in web.config
or IIS:
<system.webServer>
<security>
<requestFiltering allowDoubleEscaping="true" />
</security>
</system.webServer>
The UrlRoutingModule module responds to my attack with a 400 response:
A potentially dangerous Request.Path value was detected from the client (%).
We can disable this feature by removing the module or modifying the requestPathInvalidCharacters
setting in web.config
:
<system.web>
<httpRuntime requestPathInvalidCharacters="" />
</system.web>
The code in question is clearly vulnerable and should be fixed. That said, it appears that using either one of the RequestFilteringModule or UrlRoutingModule modules in IIS does effectively prevent my path traversal attack, provided the module(s) are fully-enabled.