前言
大多数现代网站都使用多个JavaScript库,并且有很多行复杂的压缩代码,这使得对DOM XSS的测试变得非常令人头痛,PortSwigger安全研究部门专门开发了DOM Invader,使对DOM XSS的测试更加容易
Dom Invader会自动识别页面所有可控的Source(源)和Sink(汇)并将Canary(金丝雀)注入后按照危害程度进行高到低排序
DOM Invader 探测目标的 DOM,拦截它可能遇到的任何 JavaScript 源和汇,并将它们组织起来供你使用
DOM Invader会对汇(Sinks)进行排序,使最有价值的的汇(Sinks)排列在最前面
source:表示任何允许用户控制的输入的JavaScript对象,例如:location.search
sink:表示任何允许JavaScript/HTML执行的函数或设置器,例如:eval、document.write
canary:这也是BurpSuite定义的一个概念,这里你可以理解为是一个字符串,是一个独特的字符串,用于查看用户输入在汇(Sinks)中的反映,默认情况下,DOM Invader使用一个随机的金丝雀(canary),不过你也可以将这个值自定义为你喜欢的任何值
从Burp 2021.7版本,burp自带的浏览器就集成了该插件
不过默认情况下DOM Invader是关闭的,你需要手动开启
使用
开启插件后f12查看是否可以使用
当你打开后
它显示任何包含金丝雀(Canary)值的源(Sources)和汇(Sinks),以及所有可用的源(Sources)和汇(Sinks)的树状视图。
当你找到一个有趣的汇(Sinks),你可以看到其中包含的值,以及堆栈跟踪,并会突出显示你的金丝雀(Canary),通过Augmented DOM,你也可以检查你自定义的金丝雀(Canary)值是否被正确编码。
其他有用的功能包括能够搜索发送到汇(Sinks)的值,以及自动将金丝雀(Canary)注入到URL参数和表单元素中
portswigger官方靶场
http://portswigger-labs.net/dom-invader/
https://portswigger-labs.net/dom-invader/testcases/augmented-dom-eval/index.php url注入pikachu靶场 表单注入
URL注入
首先单击Test 发现为get请求,url多了x参数。
将Canary 注入到URL
发现Sinks中有个标红的eval(),单击右边蓝色的Stack Trace进行跟踪,具体位置它会显示在console窗口
跟进来发现是eval(x)出了错
表单注入
pikachu靶场
这里是基于表单的DOM XSS
所以我们将金丝雀,也就是payload注入表单即可
随后发现Sinks中有个标红的innerHTML参数
单机右边蓝色的Stack Trace可进行追踪。具体位置他会显示在console窗口中
跟踪进来以后发现出现问题的地方
事件监听器与重定向
开启自动点击事件与禁止重定向
click事件触发时候会执行location.replace(x)当前页面会进行文档替换(刷新),并且禁止回退。所以js中的堆栈数据刷新了自然就没有数据了
比如在这个靶场中我们不开启这个功能,会什么都查询不到
消息拦截器
靶场
https://portswigger-labs.net/dom-invader/testcases/postmessage-eval-iframe-multiple/
此功能需要开启Postmessage interception功能
三个子功能可以不开启,不过开启后,危害效果更佳明显
查看堆栈eval(x)
直接修改payload选择发送
Build POC,能将payload改成恶意代码后生产一个iframe加载,复制到剪贴板上
点击就会跳转弹窗
<!doctype html>
<html>
<head>
<!-- DOM XSS PoC - generated by DOM Invader part of Burp Suite -->
<meta charset="UTF-8" />
<title>Postmessage PoC</title>
<script>
function pocLink() {
let win = window.open('https://subdomain1.portswigger-labs.net/dom-invader/testcases/postmessage-eval-iframe-multiple/external.html');
let msg = "javascript:alert(1)";
setTimeout(function(){
win.postMessage(msg, '*');
}, 5000);
}
function pocFrame(win) {
let msg = "javascript:alert(1)";
win.postMessage(msg, '*');
}
</script>
</head>
<body>
<a href="#" onclick="pocLink();">PoC link</a>
<iframe src="https://subdomain1.portswigger-labs.net/dom-invader/testcases/postmessage-eval-iframe-multiple/external.html" onload="pocFrame(this.contentWindow)"></iframe>
</body>
</html>