6.3 DOM XSS 挖掘
了解DOM渲染后有助于我们更好地进行DOM XSS漏洞的挖掘,本节会介绍一些常见的DOM XSS挖掘思路,这些思路都需要弄清楚输入点(sources)和输出点(sinks)是什么,相关内容在第3章中有过简单的说明。
6.3.1 静态方法
静态方法如果要工具化,可以使用下面这个链接提到的正则表达式来匹配:
http://code.google.com/p/domxsswiki/wiki/FindingDOMXSS
比如,输入点匹配的正则表达式如下:
/(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)?|showModal Dialog|eval|evaluate|execCommand|execScript| setTimeout|setInterval) \s*["'\])*\s*\()/
一旦发现页面存在可疑特征,就进行人工分析,这是静态方法的代价,对人工参与要求很高。这个过程可以利用浏览器来达到这个目的,比如,Firefox下用Firebug能统一分析目标页面加载的所有JavaScript脚本,可以用自带的搜索功能,用正则表达式的方式进行目标的搜索非常方便。
6.3.2 动态方法
动态方法很难完美地实现检测引擎,这实际上是一次JavaScript源码动态审计的过程。从输入点到输出点的过程中可能会非常复杂,需要很多步骤,如果要这样一步步地动态跟踪下去,其代价是很高的,如果仅关注输入点与输出点,不关注过程,那么一些逻辑判断的忽视可能会导致漏报,比如,过程中会判断输入点是否满足某个条件,才会进入输出点。
下面先来看一些简单的模型,这有助于我们理解这个动态方法。
比如,如何检测出下面这个DOM XSS?
<script> eval(location.hash.substr(1)); </script>
1)思路一
借用浏览器自身的动态性,可以写Firefox插件,批量对目标地址发起请求(一个模糊测试过程),请求的形式是:在目标地址后加上#fuzzing内容,比如其中一个模糊测试内容是:varx='d0mx55'。
在响应回来时,我们需要第一时间注入一段脚本劫持常见的输出点函数,劫持方式可以参考2.5.7节的“JavaScript函数劫持”,比如,劫持了eval函数如下:
var _eval=eval; eval = function(x){ if(typeof(x)=='undefined'){return;} if(x.indexOf('d0mx55')!=-1){ alert('found dom xss'); } _eval(x); };
当eval(location.hash.substr(1));执行时,实际上是执行我们劫持后的eval,它会判断目标字符串d0mx55是否存在,若存在,则报DOM XSS。
在JavaScript层面劫持innerHTML这样的属性已经没那么容易了,常用的属性劫持可以针对具体的对象设置defineSetter方法,比如,如下代码:
window.__defineSetter__('x',function(){ alert('hijack x')} ); window.x ='xxxxyyyyyyyyyyyy';
当x赋值的时候,就会触发事先定义好的Set-ter方法。innerHTML属性属于那些节点对象,想劫持具体节点对象的innerHTML,需要事先知道这个具体节点的对象,然后设置defineSetter方法。
这样,如果要检测DOM XSS,就要劫持所有的输出点,比较麻烦,有没有更简单的方法?看思路二。2)思路二
仍然借用浏览器动态执行的优势,写一个Fire-fox插件,我们完全以黑盒的方式进行模糊测试输入点,然后判断渲染后的DOM树中是否有我们期待的值,比如,模糊测试提交的内容都有如下一段代码:
document.write('d0m'+'x55')
如果这段代码顺利执行了,当前DOM树就会存在d0mx55文本节点,后续的检测工作只要判断是否存在这个文本节点即可,代码如下:
if(document.documentElement.innerHTML.indexOf('d0mx55')!=-1){ alert('found dom xss'); };
这个思路以DOM树的改变为判断依据,简单且准确,不过同样无法避免那些逻辑判断上导致的漏报。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论