.netsecurityiisdirectory-traversalpath-traversal

How can I perform a path traversal attack on this service hosted in IIS?


Background

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.

Kestrel Attack

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

IIS Attack

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.

Question

How can I work around this IIS behavior to perform a path traversal attack on this vulnerable app, hosted in IIS?


Solution

  • 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.

    Encoding

    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:

    When when I perform the encoding twice, my payload does make it through to IIS:

    RequestFilteringModule

    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>
    

    UrlRoutingModule

    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>
    

    Conclusion

    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.