Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1566650
  • 博文数量: 157
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 4116
  • 用 户 组: 普通用户
  • 注册时间: 2013-06-14 18:26
文章分类

全部博文(157)

文章存档

2014年(67)

2013年(90)

分类: Web开发

2013-07-12 11:49:20

一.  分析过程
花点时间简单分析一下iis对参数串进行url解码的过程。

1.1  Asp.dll解码分析

   由于时间和能力问题,没有弄明白iis对一个url的整个解析过程,仅记录跟该问题有关的的部分。

1.1.1    实验环境

操作系统: Win2003 Standard Edition sp2
软件:      Microsoft-IIS/6.0
Asp.dll版本: 6.0.3790.3959
写一个asp文件内容如下:
<%
name = request("name")
response.write name
%>
因为主要看iis的解析,asp代码比较短,仅将传入的参数name值输出。测试时使用的请求
%%lect

1.1.2  代码调试

   与IIS有关的服务有好几个,经过分析确定W3WP.exe是主要负责响应http请求的。而对asp文件的请求,该程序会调用c:\windows\system32\inetsrv\asp.dll,进行解析。使用od动态跟踪,最终确定asp.dll在获得传入的http请求参数即name=se%%lect会调用CRequest:LoadVariables对参数进行解析。主要看如图2.1所示代码:
 


图2.1 代码

该段代码主要的功能是将传入的参数串name=se%%lect,首先根据字符=进行分割获得参数名name,然后根据字符&进行分割获得参数值。如果请求中含有多个参数,则在此循环。获得的每对参数值会存入一个CLinkElem对象中,调用CHashTable::AddElem函数将CLinkElem存入hash表中。再往后没有跟踪分析,应该就是具体解析执行asp代码。

se%%lect字符串,经过getParamter(被重命名)处理后变成select,因此可以确定该函数是主要负责解析参数,并且会做url解码。具体代码如图2.2所示:

 
图2.2 代码

首先逐个读取待解析字符,与待查找字符进行比较,如果比较成功则跳转,退出函数。否则判断字符,主要有几个分支:1)小于9 对照url表,小于9是控制字符,会判断是否是DBCS编码。2)如果字符大于等于9小于0xd就会被直接忽略3)如果是空格会被直接忽略,4)如果是%,将做如下处理:

 
图2.3 代码

读取下一个字符,判断是否是u,%u的情况这里不跟踪,主要原因经过测试%u后数据即使无效,待分析字符串“指针”不会迁移,即不会忽略任何字符,在此不讨论。继续跟踪%后不是u情况:

 
图2.4 代码

调用isxdigit函数判断%后字符是否是十六进制,根据url编码规则%后为十六进制数。本例中是l不是十六进制数,会进入到判断是否是DBCS编码流程,中间略过一点判断,(同时可以看出,%后第一个字符是十六进制会判断%后第二个字符如果此时第二个字符不是十六进制,则仍然会进入到跳过%字符的流程)具体如下:

 

 
图2.5 代码

可以看出如果%后不是u并且不是十六进制数,则不会进行url解码,而且当前的%也不会被保存,导致出现se%%lect被解码成select。

 
1.1.3  小结

   IIS在响应对asp文件的http请求时,会调用asp.dll下的CRequest::LoadVariables函数,获得提交的到页面的参数名和参数值(包括get、post、cookie请求),而该函数的在对参数串进行url解码时,可能出于兼容错误等考虑(猜测),直接过滤掉09-0d(09是tab键,0d是回车)、20(空格)、%(下两个字符有一个不是十六进制)字符。
 
这样如果防护设置在网络层如waf,并且对请求的数据包不是按照asp.dll的方式进行解码,那么其防护规则很可能被绕过。如果正则匹配两个或两个以上字符,就有可能被绕过,比如下载漏洞发送%./test.txt 在waf中匹配../就会失败,但经过iis解析后变成192.168.7.85:808/down.asp?filename=aa/../test.txt可以正常寻找到文件,下载。
 
 
 
二.  总结
IIS下的asp.dll文件在对asp文件后参数串进行url解码时,会直接过滤掉09-0d(09是tab键,0d是回车)、20(空格)、%(下两个字符有一个不是十六进制)字符。而经过测试其它url解码时是不会过滤掉这些特殊字符,可能是iis的特性。但是这个问题,导致网络上传输的参数串与最终asp使用request等函数获得的参数值可能是不同的。如name=sele%ct在网络上是name=selec%t,而asp获得参数name的值是select,因此网络层的防护如waf,会匹配select失败,最终导致攻击成功。
 
修复建议:如果要从根本上解决这个问题,只能是当接收到是asp请求,对其参数进行解码时,按照iis下asp.dll的方法进行解码,过滤掉09-0d(09是tab键,0d是回车)、20(空格)、%(下两个字符有一个不是十六进制)字符,然后再进行规制匹配。
阅读(1424) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~