URL编码是一种多功能技术,可以通过它来战胜多种类型的输入过滤器。URL编码的最基本表示方式是使用问题字符的十六进制ASCII编码来替换它们,并在ASCII编码前加%。例如,单引号字符的ASCII码为0x27,其URL编码的表示方式为%27。
2007年在PHP-Nuke应用中发现的一个漏洞(http://secunia.com/advisories/24949/)所使用的过滤器能够阻止空白符和内联注释序列/*,但无法阻止注释序列的URL编码表示。对于这种情况,可以使用下列攻击来避开过滤器:
- '%2f%2a*/UNION%2f%2a*/SELECT%2f%2a*
/password%2f%2a*/FROM%2f%2a*/tblUsers%2f
- %2a*/WHERE%2f%2a*/username%2f%2a*/LIKE%2f%2a*/'admin'--
这种基本的URL编码攻击对其他情况不起作用,不过可以通过对被阻止的字符进行双URL编码来避开过滤器。在双编码攻击中,原攻击中的%字符按正常方式进行URL编码(即%25)。所以,单引号字符在双URL编码中的形式是%2527。如果将上述攻击修改成双URL编码,那么其格式将如下所示:
- '%252f%252a*/UNION%252f%252a*/SELECT%252f%252a*/password%252f%252a*/
- FROM%252f%252a*/tblUsers%252f%252a*/WHERE%252f%252a*/username%252f%252a*/
- LIKE%252f%252a*/'admin'--
双URL编码有时会起作用,因为Web应用有时会多次解码用户输入并在最后解码之前应用其输入过滤器。在上面的例子中,涉及的步骤如下所示:
(1) 攻击者提供输入'%252f%252a*/UNION…
(2) 应用URL将输入解码为'%2f%2a*/UNION…
(3) 应用验证输入中不包含/*(这里确实未包含)
(4) 应用URL将输入解码为'/**/ UNION…
(5) 应用在SQL查询中处理输入,攻击成功。
要对URL编码技术做进一步修改,可使用Unicode来编码被阻止的字符。就像使用两位十六进制的ASCII码来表示%字符一样,也可以使用字符的各种Unicode码来表示URL编码。进一步讲,考虑到Unicode规范的复杂性,解码器通常会容忍非法编码并按照"最接近匹配(closest fit)"原则进行解码。如果应用的输入验证对特定的字母和采用Unicode编码的字符串进行检查,则可以提交被阻止字符的非法编码。输入过滤器会接收这些非法编码,不过它们会被正确解码,从而发动成功的攻击。
表7-1列出了一些常用字符的各种标准的和非标准的Unicode编码,执行SQL注入攻击时它们会非常有用。
表7-1 一些常用字符的标准的和非标准的Unicode编码
编码前的字符
|
编码后的等价形式
|
'
|
%u0027
%u02b9
%u02bc
%uu02c8
%u2032
%uff07
%c0%27
%c0%a7
%e0%80%a7
|
–
|
%u005f
%uff3f
%c0%2d
%c0%ad
%e0%80%ad
|
(续表)
编码前的字符
|
编码后的等价形式
|
/
|
%u2215
%u2044
%uff0f
%c0%2f
%c0%af
%e0%80%af
|
(
|
%u0028
%uff08
%c0%28
%c0%a8
%e0%80%a8
|
)
|
%u0029
%uff09
%c0%29
%c0%a9
%e0%80%a9
|
*
|
%u002a
%uff0a
%c0%2a
%c0%aa
%e0%80%aa
|
[space]
|
%u0020
%uff00
%c0%20
%c0%a0
%e0%80%a0
|
【责任编辑: 云霞 TEL:(010)68476606】
|