本文要点
- 在游览器地址栏中输入包含特定字符的URL地址时,部分字符,例如大括号"{}"会被URLencode,且不同游览器的行为并不一致。
- 本文根据相关文档,分析了URI的结构与格式。
- 通过搜寻资料,本文粗略地解释了第1条中述及现象的缘由——这一现象与URL在官方文档中的定义没有关系。特定字符是否会被url编码实际上仅由游览器的相关逻辑决定。
- 实际上,该编码策略能够被用于抵御xss攻击。
目录
差异缘由(一种基于URL fragment部分的XSS攻击)
现象描述
今天闲来无事切了一道19年的CTF题,题目的预期解法很简单,就是篡改HTTP头的X-fowarded,实施SSTI攻击,不过发现了一个奇怪的现象:
以下是一份简单的用于测试的PHP代码:
<?php
echo 'HTTP_HOST: '.$_SERVER['HTTP_HOST'].'<br/>';
echo 'REQUEST_URI: '.$_SERVER['REQUEST_URI'];
echo "<br/>";
foreach($_REQUEST as $key => $value)
{
echo "Key:$key; Value: $value<br />\n";
}
?>
以下是测试结果:
# 第一类:从chrome游览器输入url地址并访问!!
#测试1
http://127.0.0.1/0515_smarty.php/?a=123%23
HTTP_HOST: 127.0.0.1
REQUEST_URI: /0515_smarty.php/?a=123%23
Key:a; Value: 123#
测试2
http://127.0.0.1/0515_smarty.php/{}?{}=666
HTTP_HOST: 127.0.0.1
REQUEST_URI: /0515_smarty.php/%7B%7D?{}=666
Key:{}; Value: 666
测试3
http://127.0.0.1/0515_smarty.php/{}()''""?{}()''""
HTTP_HOST: 127.0.0.1
REQUEST_URI: /0515_smarty.php/%7B%7D()''%22%22?{}()%27%27%22%22
Key:{}()''""; Value:
测试4
(Internet Explorer游览器)
http://127.0.0.1/0515_smarty.php/{}()''""?{}()''""
HTTP_HOST: 127.0.0.1
REQUEST_URI: /0515_smarty.php/%7B%7D()''%22%22?{}()''""
Key:{}()''""; Value:
测试1展示了urlencode的正确使用方法:在地址里由urlencode表示的“#”号会在php读取get变量值的过程中被自动解码为正常符号。但是在REQUEST_URI中还是以Urlenocde编码的形式出现。
测试2中“?”字符在url中分割了地址部分和参数部分,我们发现“?”前的“{}”被urlcode了,而其后的"{}"则维持原样。
这是php的某些特性吗?显然不是,web客户端在提交游览请求时,是游览器帮助我们完成对url的编码操作。这一点很好证明,例如在chrome的地址栏中输入上述的url地址,再将url地址复制出来,你就会发现你输入的地址已自动经过urlencode编码处理。
因此,如果使用burpsuite截包,对url地址进行强行修改的话,REQUEST_URI中的特殊符号会照原样显示。
HTTP_HOST: 127.0.0.1
REQUEST_URI: /0515_smarty.php/(){}''""?(){}''""