挖掘XSS漏洞的关键在于寻找没有被过滤的参数,且这些参数传入到输出函数,常用的输出函数列表如下:print、print_r、echo、printf、sprintf、die、var_dump、var_export
,所以我们只要寻找带有变量的这些函数即可
XSS漏洞在浏览器环境对利用的影响非常大,所以最重要的还要掌握各种浏览器容错、编码等特性和数据协议,这也是有时候必须换浏览器才能注入成功的道理
白盒审计中,我们只需要寻找带有参数的输出函数,然后根据输出函数对输出内容回溯输入参数,观察有没有经过过滤
举例一个反射型XSS漏洞的大致形式,代码如下:
// 以下是QQ私密接口
if($_GET["openid"]){
// 授权成功后,会返回用户的openid
// 检查返回的openid是否是合法id
// echo $_GET["oauth_signature"];
if (!is_valid_openid($_GET["openid"], $_GET["timestamp"], $_GET["oauth_
signature"]))
{
showerr('API帐号有误!');
// demo对错误简单处理
echo "###invalid openid\n";
echo "sig:".$_GET["oauth_signature"]."\n";
exit;
}
代码中echo"sig:".$_GET["oauth_signature"]."\n";
直接将$_GET["oauth_signature"]
的值输出到浏览器中,则可以直接用GET方式注入代码
要挖掘存储型XSS也是要寻找未过滤的输入点和未过滤的输出函数,这个最终的输出点可能跟输入点完全不在一个业务流上,对于这类可以根据当前代码功能去猜,或者老老实实去追哪里有操作过这个数据,使用表名、字段名去代码里面搜索
一般的XSS漏洞都是因为没过滤特殊字符,导致可以通过注入单双引号以及尖括号等字符利用漏洞,比如一个图片标签如下<img src="$_GET['a']"/>
,则可以通过输入双引号来闭合第一个单引号利用漏洞,防御这类的XSS漏洞只需要过滤掉相关的特殊字符即可,特殊字符列表如下:
最好的过滤方式是在输出和二次调用的时候进行如HTML实体一类的转码,防止脚本注入的问题。
我们还得加标签事件的黑名单或者白名单,这里更推荐用白名单的方式,实现规则可以直接用正则表达式来匹配,如果匹配到的事件不在白名单列表,就直接拦截掉,而不是替换为空