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编码第一字节(高字节)的范围是0x81
0xFE,第二字节(低字节)的范围是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  href=" ajvascript:alert(1)">test</a>
是可以在IE、Firefox、Chrome下执行的,但语句:<a  href=" javascript:alert(1)">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平台,在实践中检验:)