有些公司说 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 配置应用程序池的时候,都会选择托管管道模式。
本文不深究这个东西,如果感兴趣,可以参考:IIS 7 托管管道模式 经典模式(Classic) 集成模式(Integrated) 分析与理解
现在谈 URL 重写,关于 URL 重写,请参考:微软 IIS URL Rewrite(URL 重写)使用教程。
综合测试不同 .NET 版本校验、托管管道模式、URL 重写
我们设置一个 URL 重写:当 Path 含有 ~ 时重定向至 403。
我们访问时 Path 中带有 *~,注意加个 *,是为了看看校验响不响应。
在集成模式下:
在经典模式下:
前面说了,.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 校验的那几个字符啊:<、>、*、&、:。
总结
为 URL 重写加上 ~ 判断,可以防止请求的 Path 中携带 ~,只是我们测试的时候除了携带 ~,还携带了 *,所以根据不同的 .NET 版本、不同的托管管道模式,会显示不同的结果。不管结果如果,只要配置了 ~ 的 URL 重写,就已经将猜测者挡在了外面。
最后,以一个流程图总结:
最后,我想说的是,网上说他猜测成功了的,你们是怎么做到的?因为我这边在没有更改任何配置的情况下测试:凡是带有 * 都会返回 400,因为被 .NET 干掉了;凡是带有 ~ 都会返回 404。并不如他们说的如果存在返回 404,如果不存在返回 400。
特殊情况
在集成模式下:
难道 .NET 对带点文件夹有特殊处理?