【bWAPP】XSS总结
XSS-Reflected(GET与POST)解法很常规,low和mediu级别只过滤单引号,high级别用htmlspecialchars()和htmlentities(),总结以下二者区别吧。
htmlspecialchars()与htmlentities()的区别
-
htmlspecialchars()将以下字符转换为HTML实体
&成为
&
"成为
"
'不变 (设置了ENT_QUOTES后编码为
'
或'
)<
变为<
>
变为>
可选类型:
ENT_COMPAT----默认,仅编码双引号
ENT_QUOTES----编码双引号和单引号
ENT_NOQUOTES----不编码任何引号
-
htmlentities()将所有使用的字符转换为HTML实体
将所有html标签和符号,甚至中文全部转换为html实体
1、XSS-Reflected(JSON)
low级别
先扔一个payload:<script>alert(/xss/)</script>
:
看下网页源码:
原来输出点在json代码中。
尝试闭合,构造payload:"}]}';alert(/xss/);//
注意一定要注释后面的js代码//
成功弹窗!
medium级别
看样子是被html实体化编码了,很难绕过。
high级别也是实体化编码。
2、XSS-Reflected(AJAX/JSON)
low和medium级别
本页面是xss_ajax_2-1.php,通过Ajax调用xss_ajax_2-2.php完成查询的
输入:<img src=1 onerror=alert(/xss/)>
或者<svg onload=alert(/xss/)>
但是用<scritp>alert(/xss/)</script>
不行
因为由于根据HTML5规范,innerHTML
中的script
标签会被当做纯文本解释,不会执行(详见)。因此不能直接插入<scrit></script>
high级别
尝试:<img src=1 onerror=alert(/xss/)>
如图所示,已被实体化编码,很难绕过。
源码分析:
//xss_ajax_2-1.php
<?php
if($_COOKIE["security_level"] == "2")
{
?>
JSONResponse = JSON.parse(xmlHttp.responseText);
<?php
}
else
{
?>
JSONResponse = eval("(" + xmlHttp.responseText + ")");
<?php
}
?>
由以上源码可得,low级别和medium级别AJAX传入的json会用eval()去解析,high级别会用JSON.parse()去解析。
总结:
json.parse与eval()的区别:
// JSON.parse()
var json = '{"name":"GDT","age":,"University":"GDUT"}';
var info = JSON.parse(json); //解析为JSON对象
//eval()
var json = '{"name":"GDT","age":,"University":"GDUT"}';
var info = eval('(' + json + ')'); //解析为JSON对象
二者都可将JSON字符串解析为对象
相对于写法格式严格的JSON.parse()来说,eval()可以解析任何字符串,eval是不安全的,因为eval比较宽松,会有潜在的安全性问题。
3、XSS-Reflected(AJAX/XML)
low级别
还是一样本页面为xss_ajax_1-1.php,通过ajax跳转到xss_ajax_1-2.php解析
payload_1:<a xmlns:a='http://www.w3.org/1999/xhtml'><a:body onload='alert(/xss/)'></a>
xmlns是XML Namespaces的缩写,加载网站时执行alert(/xss/)
payload_2:<img src=0 onerror="alert(1)">
medium级别
使用addslashes()对参数进行了转义’、"、\
换一个payload:<img src=0 onerror="alert(1)">
HTML 和 XML 都有一些符号被保留使用,它们不能在 XML 代码中用作内容。例如,< 和 > 符号被用作 XML 标签的开头和结尾。要显示这些特殊字符,就要使用字符实体。有些特殊的字符或符号还不能直接使用键盘输入。可以使用字符实体来显示这些符号或特殊字符。
在这个例子中对payload进行html实体编码绕过了addslashes()的转义,然后再xml中重新还原成了原来的payload从而触发xss。
相关知识点:html实体编码的作用。
high级别
采用了htmlspecialchars()实体化编码,很难绕过。
4、XSS-Reflected(Back Button)
low级别:
点击按钮查看页面源代码
用burp抓包看看:
发现onclick中的值来自referer字段。
修改referer字段的值为:'"><img src=1 onerror=alert(/xss/)>
放包:
mediu级别
这个级别用addslashes()转义了’",但是上面的payload依然可以使用,感觉转义没起作用,有点奇怪,哦对了,反斜杠对js有效,而对html不起作用。
不过用其他方法也可以,比如:javascript:alert(/xss/)
high级别
使用了htmlspecialchars()实体化转义,绕过比较难。
5、XSS-Reflected(Custom Header)
low&medium级别:
根据提示:
添加bWAPP头:
high级别:
依然是htmlspecialchars()编码,很难绕过。
6、XSS-Reflected(Eval)
low&medium级别
老规矩,先输入一个<script>alert(/xss/)</script>
测试一下
查看页面源码发现输出点在script标签内:
调整一下payload:
弹窗成功!
eval函数:如果参数是一个表达式,eval() 函数将执行表达式。如果参数是Javascript语句,eval()将执行 Javascript 语句。eval() 是一个危险的函数,它使用与调用者相同的权限执行代码,所以尽可能的不要去使用它,以防被其他人员植入恶意代码,相似的 Function 就不容易被攻击。
7、XSS-Reflectde(HREF)
low级别
随便输入一个数字:
发现跳转到了一个投票页面:
分析网页源代码,可以看出有两个输出点,一个在p标签内,一个在herf中。
扔一个payload进去试试:<script>alert(/xss/)</script>
发现p标签中的payload已被实体化编码,而herf中丝毫没动。
构造payload闭合a标签:></a><img src=1 onerror=alert(/xss/)>
弹窗成功!
medium级别
使用low级别的payload尝试一下:
发现href中的payload被url编码了。
查看源码:
发现medium级别和high级别都被url编码了。
8、XSS-Reflected(login From)
low级别
是一个登录表单:
尝试使用万能密码:(输入到姓名或密码框都可)
' or 1=1;"<img src=1 onerror=alert(/xss/)>"
实现原理:通过数据库报错将payload回显,从而触发xss
medium级别:
addslashes()转义’、",绕过比较难
high级别:
mysql_real_escape_string () 函数转义,绕过比较难。
受影响字符:\x00、\n、\r、\、’、"、\x1a
9、phpMyAdmin BBCode Tage XSS
显示是一个phpmyadmin上的一个BBcode的XSS,没复现过。
10、XSS-Reflected(PHP_SELF)
low&medium级别
前两个参数随便替换一个:<img src=1 onerror=alert(/xss/)>
high级别
已被htmlspecialchars()实体化编码。
11、XSS-Reflected(Referer)
low&medium级别
页面回显referer字段信息:
用burp抓包,添加referer字段,内容为payload:<img src=1 onerror=alert(/xss/)>
当然其他也可以。
high级别
htmlspecialchars()实体编码。
12、XSS-Reflected(user-Agent)
与上一关类似,不再赘述。
13、XSS-Stored(Blog)
low&medium级别
直接输一个payload点提交:
如图所示,直接弹窗!刷新页面再次弹窗,说明存储型xss的伤害是持久的。
high级别
htmlspecialchars()函数实体化编码。
套路都是一样的,好无聊。。。。
14、XSS-Stored(Change Secret)
low级别
方法一:
在输入框测试payload无果
查看网页源代码,发现有一个名为login的隐藏的输入框。
用burp抓包,发现提交了三个参数:secret、login、action
抓包修改login的参数值以闭合input标签:
方法二:
直接在输入框输入payload:<script>alert(/xss/)</script>
发现已成功插入到数据库中。
登录SQL Injection(Login Form/User)页面时,用bee用户登录,点击提交即触发xss
medium&high级别
抓包发现有token值:
token值是随机的,而且后端有校验,这下裂开。。
尝试输入框输入payload,结果进数据库之前就被实体编码了。
无论是mediu级别还是high级别都进行了html实体编码。
卒。。。
15、XSS-Stored(Cookies)
埋点在cookie篡改
low级别
修改genre参数值就可修改cookie值
medium级别
对genre参数的值进行了html实体编码
high级别
无法通过修改genre来修改cookie
后端进行了白名单过滤。
16、XSS-Stored(User-Agent)
low&medium级别
直接将payload插入User-Agent字段
刷新页面依然弹窗,伤害持久。
high级别
有htmlspecialchars()实体编码。
总结:
关键函数:
php:
htmlspecialchars() 编码<>、’、"、&
htmlentities() 将所有html标签和符号,甚至中文全部转换为html实体
addslashes() 转义’、"、\、null
mysql_real_escape_string () 转义\x00、\n、\r、\、’、"、\x1a
js:
innerHTML
中的script
标签会被当做纯文本解释,不会执行(详见)。json.parse与eval()的区别:
相对于写法格式严格的JSON.parse()来说,eval()可以解析任何字符串,eval是不安全的,因为eval比较宽松,会有潜在的安全性问题。