关于xss漏洞点的挖掘

0x00 引言

  这篇文章主要是简单介绍一些常见的XSS漏洞点,我也在本地搭建了一个XSS练习靶场(github上的一个项目,来源戳这),以供大家学习 : )

0x01 XSS

  • XSS(跨战脚本攻击)大体可分为 反射型XSS、存储型XSS以及DOM XSS,而XSS漏洞挖掘最重要的就是找到反射点。
  • 前两种的漏洞基本上是需要通过与服务器的交互,exploiter(漏洞挖掘者)需要判断用户输入会在哪里输出(如果可以输出<script>标签,浏览器会对其进行解析进而执行其中的脚本);而DOM XSS可认为完全是客户端的事,触发XSS靠的是浏览器解析DOM。

0x02 HTML

  • 标签之间:<div id="xss is here">[输出]</div>
    比如说第一关,后端的判断如下
  • 而输出出现在下面标签中:
      <title></title>  
    <textarea></textarea>  
    <xmp></xmp>  
    <iframe></iframe>  
    <noscript></noscript>  
    <noframes></noframes>  
    <plaintext></plaintext>  
     例如,<title><script>alert(1)</script></title>不会弹出提示框。但是,payload也可以这样写</title><script>alert(1)</script>
  • 标签之内:<input type="text" value="[输出]"/>(payload可以考虑闭合引号,也可考虑闭合标签等,比如说google的xss-game第三关以及第三关
  • js代码:<script>var username="[输出]";……</script>
  • CSS代码:<style>button { border-radius:[输出]px }</style>

0x03 字符集编码

《web前端黑客技术揭秘》一书中提到

有些安全问题的罪魁祸首是字符集的使用(即字符集编码与解码)不正确导致的,字符集本身也有一些问题,比如,各种说不清道不明的原因导致字符集之间的交际分歧。

  • 宽字节编码
     例如在magic_quotes_gpc=On的情况下如何触发XSS?
    <?php header("Content-Type: text/html;charset=GBK");?>
    <head>
    <title>gb xss</title>
    </head>
    <script>
      a = "<?php echo $_GET['x']?>";
    </script>

  先会想到闭合双引号:
  gb.php?x=1";alert(1)//
  双引号会被转移成",导致闭合失败:
  a = "1\";alert(1)//";
这本书提供了一种思路:

这个网页头部响应指明了这是GBK编码,GBK编码第一字节(高字节)的范围是0x810xFE,第二字节(低字节)的范围是0x400x7E与0x80~0xFE,这样的十六进制表示。而\符号的十六进制表示为0x5C,正好在GBK的低字节中,如果之前有一个高字节,那么正好会被组成一个合法字符。

  gb.php?x=1%81";alert(1)//
  双引号会继续被转移成",最终如下:
  a="1[0x81]\";alert(1)//";

[0x81]\组成了一个合法字符,于是之后的双引号就会产生闭合,这样我们就成功触发了XSS。

  • UTF-7
      UTF-7编码问题主要出现在老版本的IE浏览器下,在IE6/7时代,如果没声明HTTP响应头字符集编码方式或者声明错误,同时,<meta http-equiv>未指定charset或指定错误,那么IE浏览器会判断相应内容中是否出现UTF-7编码的字符串,如果有,浏览器将解析该字符串。

    0x04 绕过

  • HTML中
     1.标签
      - 黑名单绕过(有些html过滤器是基于黑名单的)
      - 注释绕过(有些HTML Parser对于注释的判断)
        - 会去判断当前代码段是否存在于注释中,如果这些过滤器的判断方法为:<!--.*-->,那么注释可这么写:bbb<!-- aaa<!--aaa--> ccc-->bbb,这样,“ccc”代码就暴露出来可以执行了。(这地方还不是很懂判断细则是怎样的(尴尬…) )
        - 不关心是否有注释。但由于注释优先级较高,可以这么写:<!--<a href="--><img src=x onerror=alert(1)//">test</a> 扫描器忽略了HTML注释之后,会认为下面这一段是一个完整的HTML语句:<a href="--><img src=x onerror=alert(1)//">test</a> 那么下面这段就被认为是属性href的值:"--><img src=x onerror=alert(1)//",从而对这段代码放行。但实际上对于浏览器来说,<!--<a href="-->是注释内容,<img src=x onerror=alert(1)//">则是一个完整的img标签,而onerror则成了一个独立的事件属性得以执行。
        - IE下:

    <!--[if IE]> 所有的IE可识别<![endif]-->
    <!--[if IE 6] 仅IE6可识别<![endif]-->
    <!--[if lt IE 6] IE6以及IE6以下版本可识别<![endif]-->
    <!--[if gte IE 6] IE6以及IE6以上版本可识别<![endif]-->

  - 利用标签优先级的绕过,有些标签如<textarea>、<title>、<style>、<script>、<xmp>等具有非常高的优先级,使得其结束标签甚至可以直接中断其他标签的属性。

    2.属性
     - 标签和属性之间、属性名和等号之间、等号和属性值之间可以用空格、换行符、回车符或者tab,并且个数不受限制。
     - 另外,还可以在属性值的头部和尾部(引号里面)插入系统控制字符,即ASCII值为1~32这32个控制字符,不同浏览器都有各自的处理方式,如下语句: <a &#8 href="&#32ajvascript:alert(1)">test</a>是可以在IE、Firefox、Chrome下执行的,但语句:<a &#8 href="&#32javascript:alert(1)&#27">test</a>就仅可以在IE和Firefox下执行。

  • CSS
     1. 资源类属性可嵌入xml、css、js等
     2. @import
     3. expression(IE独有的CSS属性,可结合UTF-7)
  • JS
     1. JSON
      - 通过callback函数名的参数调用Object的形式
       - 此时,如果数据提供方没有对callback函数名做安全过滤,并且页面本身也没有对HTTP响应头中的Content-Type做限制,那么我们便跨域直接对callback参数进行利用,如:get_json.php?id=123&callback=<script>alert(1);</script>
     2. js中eval可执行 oct、hex编码的字符串,不可执行 十进制(但是可通过String.fromCharCode(,,,)转换,js下三套编解码的函数: escape/unescape;encodeURI/decodeURI;encodeURIComponent/decodeURIComponent。

0x05 页脚

  • 其实xss的挖掘点数不胜数,各大浏览器都会出现或多或少的安全问题,同时xss漏洞也逐渐引起高度的重视。《web前端黑客技术揭秘》里提到一点:

    标准总是过于美好,但是每个浏览器在实施这些标准时不一定就能很好地实施,所以不要轻信它们不会出现BUG。

在这里也安利两个书中提到的网站:经典的混淆CheckList 和 在线fuzzing平台,在实践中检验:)