这篇文章在很多博客上看到,觉得很有意思,学习一波;
其实通过细读陆队和一些其他的文章,Dom clobbering xss的本质就是利用id或者name去对全局变量的劫持覆盖;在目标站点的script代码中如果有相应的引用;就会造成漏洞;
先来看一下如何进行劫持;简单看一下图:
通过这个图不难理解,我们成功劫持掉了cookie;document.cookie已经成功被我们的标签给覆盖了;但是如果这里写入的是<img id=cookie>
则无法success;具体的原因可以看下图:
这里显然易见我们可以通过id和name在document和window对象下创建一个新的对象;但是值得注意的是使用id的时候是无法被document来获取到的;需要用document.getElementById来进行获取所以这也是为什么当标签设置为<img id=cookie>
的时候无法success的原因;
可以很清楚的看到利用form和input进行覆盖函数,导致在后续的代码中无法识别函数;
要想利用这个漏洞还是需要进一步的进行深入,因为当前测试的结果返回的仅仅是一个对象,无法返回string;当然我们可以测试一下强制类型进行转换;
如果进行强制类型转换,那么会回显为字符类型的object HTMLImageElement;用此去进行xss攻击显然是不现实的;
所以现在的想法就是如何去将其内容控制为返回的字符串;
那么就需要去进行遍历,遍历到合适的标签让我们可以返回相应的string;
1 | var s1mple = Object.getOwnPropertyNames(window) |
用此代码去进行遍历,最后回显的结果为两种标签对象:
对应的就是area和a标签;利用这两种标签对象就可进行返回String;从而可进行xss;看一个测试图:
证明是在a标签下可以利用href进行强制类型转换;至于area,换个标签就可;也可以实现弹窗;是会返回其href属性的value;
上面的实验仅仅是建立在一层的基础之上,那么如果是两层甚至多层又如何触发xss?简单分析一下;
两层的一般形式就是x.y这种,需要去更内部去触发;
这里两层可以引入name属性去进行承接;
我们可以通过相同id的标签创建来实现HTMLCollection的创建,如下:
就可实现双层的Dom clobbering点利用;area标签是一样的原理;
在不用HTMLCollection的情况下也可采用html的层级关系来实现层级访问;整体fuzz一遍看看哪些组合可以实现层级访问;
1 | var log=[]; |
可以得到以下的关系:
1 | form->button |
这也是为什么第四张图劫持函数可以成功的原因;
用此构建成x.y;结合之前的返回string;就可以构造出相应的payload;
1 | <form id=x> |
这种方法无法拿到其value;也算是有点欠佳的方法;尽管有些标签可以返回value;但是也是需要借助value属性才可返回,比如:
所以其利用方式也是很局限的;实际中还是最好利用两层同id去造成HtmlCollection然后利用name承接,进行a href的利用较好;
三层利用的关系就需要我们结合上面两种方式;
1 | <div id="x"> |
理解一下也不难,先利用同id去造成HtmlCollection去获取第二层,然后在利用form和output来进行第三层的获取;
不过缺点和之前一样,因为套了form->output所以也是无法直接拿到value;
三层以上的访问可以通过iframe与srcdoc来实现
1 | <iframe name=a srcdoc=" |
这种方式可以直接拿到value;
如果不想通过setTimeout进行延时的话,还可以通过<style>
标签或者<script>
等进行网络请求造成延时,使得iframe加载完毕;因为在iframe没有记载完毕的时候他的document和加载完之后的document是不一样的;
1 | <iframe name=a srcdoc=" |
这里可以用以下的脚本进行fuzz;fuzz一下看看有没有字符串类型的属性可以让我们使用;
1 | var html = [...]//HTML elements array |
可以得到两个有趣的可利用属性 为username和password,但是这两个并非HTML属性,利用如下:
1 | <a id=x href="http://Clobbered-username:Clobbered-Password@a"> |
除此之外,还有其他的一些标签结合属性名称,比如a:title,也都挺有趣的;
1 | <a id=x title="x:alert(1)"> |