如何对 IIS 中托管的此服务执行路径遍历攻击?

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

背景

我正在尝试对 IIS 中托管的易受攻击的服务执行路径遍历攻击。

服务是这样的:

GET /api/download/{file-name}

底层代码是这样的:

return File.Read("some/directory/" + fileName);

正如所写,此服务显然易受攻击。

红隼攻击

当 运行 在本地使用 dotnet run 时,我可以执行路径遍历攻击,我收集到的是使用 Kestrel Web 服务器。我的攻击有效载荷是..\..\secret.txt,它被编码并在日志中可见:

Request starting HTTP/1.1 GET http://localhost/api/download/..%5C..%5Csecret.txt

IIS 攻击

当托管在 IIS 中时,我无法在同一个应用程序上重现此攻击。看起来 IIS 通过解释 ..\ 以某种方式规范化了 URI,这意味着它永远不会命中我的 API。换句话说,它试图达到以下端点:

GET http://localhost/secret.txt

我为 ..\ 字符序列尝试了多种不同的编码,但没有成功。

问题

如何解决此 IIS 行为以对托管在 IIS 中的此易受攻击的应用程序执行路径遍历攻击?

这在 IIS 内核级别被阻止。

相关内容如下:

Unsafe:

Characters can be unsafe for a number of reasons. The space character is unsafe because significant spaces may disappear and insignificant spaces may be introduced when URLs are transcribed or typeset or subjected to the treatment of word-processing programs. The characters "<" and ">" are unsafe because they are used as the delimiters around URLs in free text; the quote mark (""") is used to delimit URLs in some systems. The character "#" is unsafe and should always be encoded because it is used in World Wide Web and in other systems to delimit a URL from a fragment/anchor identifier that might follow it. The character "%" is unsafe because it is used for encodings of other characters. Other characters are unsafe because gateways and other transport agents are known to sometimes modify such characters. These characters are "{", "}", "|","\", "^", "~", "[", "]", and "`".

All unsafe characters must always be encoded within a URL. For example, the character "#" must be encoded within URLs even in systems that do not normally deal with fragment or anchor identifiers, so that if the URL is copied into another system that does use them, it will not be necessary to change the URL encoding.

因此 IIS 会在核心级别主动阻止此操作,这是一种主动安全措施,可最大限度地减少攻击面。

这个link也有类似的问题。

似乎有几件事阻止了我的路径遍历攻击。我能够通过 (1) 对有效负载进行双重编码和 (2) 删除或破坏 IIS 中的 RequestFilteringModule 和 UrlRoutingModule 模块来执行路径遍历攻击。如果这些模块中的任何一个存在并且完全启用,我就无法重现攻击。

编码

首先,我必须在攻击负载中对 \ 字符进行编码。

当我简单地 URL 编码一次时,IIS(我假设)规范化了 URI,正如我之前观察到的:

  • 在浏览器中观察到的请求:http://localhost/api/download/..%5C..%5Csecret.txt
  • IIS 中的 URI 登录服务器:http://localhost/secret.txt

当我执行两次编码时,我的有效负载确实通过了 IIS:

  • 在浏览器中观察到的请求:http://localhost/api/download/..%255c..%255csecret.txt
  • IIS 中的 URI 登录服务器:http://localhost/api/download/..%5C..%5Csecret.txt

请求过滤模块

RequestFilteringModule 模块以 404 响应响应我的攻击:

The request filtering module is configured to deny a request that contains a double escape sequence.

我们可以通过删除模块或在 web.config 或 IIS 中设置 allowDoubleEscaping 标志来禁用此功能:

<system.webServer>
  <security>
    <requestFiltering allowDoubleEscaping="true" />
  </security>
</system.webServer>

UrlRoutingModule

UrlRoutingModule 模块以 400 响应响应我的攻击:

A potentially dangerous Request.Path value was detected from the client (%).

我们可以通过删除模块或修改 web.config 中的 requestPathInvalidCharacters 设置来禁用此功能:

<system.web>
  <httpRuntime requestPathInvalidCharacters="" />
</system.web>

结论

有问题的代码显然容易受到攻击,应该修复。也就是说,似乎在 IIS 中使用 RequestFilteringModule 或 UrlRoutingModule 模块之一确实有效地防止了我的路径遍历攻击,前提是模块已完全启用。