www.cftea.com

短文件名漏洞-引出的 .NET 版本 validateRequest,IIS 集成、经典

ITPOW2018/8/26 12:27:33

有些公司说 IIS 有 8.3 格式命名的漏洞,就是通过不断地猜测文件名前缀可以猜测到是否存在某个文件,虽然对于长文件名,他只能猜测到前面部分,但仍然被列为中危漏洞。可以参考这篇文章:IIS短文件和文件夹泄漏漏洞利用心得

我们在配置不同的 IIS 服务器时,遇到不同的显示结果,所以我决定把几个知识点综合起来讲一下。

先说 .NET 版本校验问题

.NET 2.0 会校验 POST 的值

比如当遇到 POST 内容含有类似 <f> 这种东西,.NET 2.0 就会报错:从客户端中检测到有潜在危险的 Request.Form 值。

关闭方法:web.config 中:<pages validateRequest="false">。请参见:web.config 的 system.web 常用配置节介绍

.NET 4.0 会校验 POST、Path、QueryString、Cookie 等的值

POST 的校验,还是和 2.0 一样,只校验像 HTML 标签一样的东西(<> 中间放点东西)。

Path 的校验,是不允许字符串中出现:<、>、*、&、:,有人说还包括:~、/、|,但是据我测试,这三个是不会校验的。当 Path 校验失败时,就会说:从客户端中检测到有潜在危险的 Request.Path 值。

QueryString 的校验应该是和 POST 类似,只是测试时要注意有时候测试工具会自动转码,比如 <f> 会转码发送,这样服务端就不认为它是危险的,如果工具不转码,服务器端则认为它是危险的。同理,校验失败时,会说:从客户端中检测到有潜在危险的 Request.QueryString 值。

关闭方法:web.config 中:<pages validateRequest="false">、<httpRuntime requestValidationMode="2.0" />,需要两个地方配置。但是,这个虽然放开了 POST 校验,而 Path 值却照样要校验!

再说说集成模式与经典模式,以及 URL 重写

在 IIS 配置应用程序池的时候,都会选择托管管道模式。

  • 集成模式可以理解为 .NET 是 IIS 的有机组成,.NET 的模块和 IIS 的模块共同动作,有些干这一层的事,有些干那一层的事。少了 .NET 模块,整个请求的某些环节都走不通。
  • 经典模式可以理解为 IIS 的附加,IIS 把该干的活干了,然后判断扩展名,该由 .NET 处理,好扔给 .NET。少了 .NET 模块,只是不能处理 ASP.NET 网页。

本文不深究这个东西,如果感兴趣,可以参考:IIS 7 托管管道模式 经典模式(Classic) 集成模式(Integrated) 分析与理解

现在谈 URL 重写,关于 URL 重写,请参考:微软 IIS URL Rewrite(URL 重写)使用教程

综合测试不同 .NET 版本校验、托管管道模式、URL 重写

我们设置一个 URL 重写:当 Path 含有 ~ 时重定向至 403。

我们访问时 Path 中带有 *~,注意加个 *,是为了看看校验响不响应。

在集成模式下:

  • .NET 2.0 中显示的是 403 错误,URL 重写了。或者 400 Bad Request 错误。为什么会有两种错误,后面讲。
  • .NET 4.0 中显示的是:从客中户端检测到有潜在危险的 Request.Path 值。说明校验在 URL 重写之前。

在经典模式下:

  • .NET 2.0 中显示的是 403 错误,URL 重写了。
  • .NET 4.0 中显示的是 403 错误,URL 重写了。我们关闭 URL 重写,才是出现的:从客中户端检测到有潜在危险的 Request.Path 值。注意前面说了 4.0 的 Path 校验是关不掉的,同时验证了经典模式下:URL 重写在前,.NET 校验在后。

前面说了,.NET 2.0 的集成模式下会有两种错误,为什么呢?

第一种、403,是由于路径并不是 .aspx 的,直接由 URL 重写处理的。

第二种、400 Bad Request,是由于路径是 .aspx 的,在交由 URL 重写之前,先交给 .NET 处理,而 .NET 版本是 2.0 的,它并不会显示“潜在危险的 Request.Path 值”,而是显示的“400 Bad Request”。进一步查看详细信息,说的是:ASP.NET detected invalid characters in the URL.,(模块:global.asax,通知:BeginRequest,处理程序:PageHandlerFactory-Integrated)嘿,.NET 2.0 也会判断非法字符,那到底是 ~ 非法还是 * 非法呢?经我们测试是 * 非法,进一步测试,发现完全就是 .NET 4.0 校验的那几个字符啊:<、>、*、&、:。

总结 

  • .NET 2.0 不会校验 Path 值。
  • .NET 4.0 会校验 Path 值,即使使用 <pages validateRequest="false">、<httpRuntime requestValidationMode="2.0" /> 也无法将其关闭。
  • 集成模式下:.NET 先处理请求的值,再来交给 URL 重写。
  • 经典模式下:先由 IIS 处理 URL 重写,再交给 .NET 处理,毕竟,经典模式下,.NET 被认为是一种附加。

为 URL 重写加上 ~ 判断,可以防止请求的 Path 中携带 ~,只是我们测试的时候除了携带 ~,还携带了 *,所以根据不同的 .NET 版本、不同的托管管道模式,会显示不同的结果。不管结果如果,只要配置了 ~ 的 URL 重写,就已经将猜测者挡在了外面。

最后,以一个流程图总结:

IIS 请求

最后,我想说的是,网上说他猜测成功了的,你们是怎么做到的?因为我这边在没有更改任何配置的情况下测试:凡是带有 * 都会返回 400,因为被 .NET 干掉了;凡是带有 ~ 都会返回 404。并不如他们说的如果存在返回 404,如果不存在返回 400。

特殊情况

在集成模式下:

  • 如果 URL 以 ./.aspx 结尾(注意 / 前面有一个点
    • .NET 2.0 中,会说 404 错误,而不会交给 URL 重写。
    • .NET 4.0 中,也会说 404 错误,同样不会交给 URL 重写。
  • 如果 URL 以 ../.aspx 结尾(注意 / 前面有两个点
    • .NET 2.0 中,此时会说 invalid characters,当然也是不会交给 URL 重写的。
    • .NET 4.0 中,会继续说 404 错误,同样不会交给 URL 重写。

难道 .NET 对带点文件夹有特殊处理?

<<返回首页<<