当前位置:网站首页>DOM破坏

DOM破坏

2022-08-11 05:21:00 朵拉爱学习

一.DOM

简单来说DOM文档就是一份XML文档,当有了DOM标准之后,DOM便将前端html代码化为一个树状结构,方便程序和脚本能够轻松的动态访问和更新这个树状结构的内容、结构以及样式,且不需要经过服务端,所以DOM型xss在js前端自己就可以完成数据的输入输出,不与服务器产生交互,这样来说DOM型xss也可以理解为反射性xss。JS是通过DOM接口来操作文档的,而HTML文档也是用DOM树来表示。所以在浏览器的渲染过程中,我们最关注的就是DOM树是如何构建的。而当处理script的闭标签时,除了弹出相应item,还会暂停当前的DOM树构建,进入JS的执行环境。换句话说,在文档中的script标签会阻塞DOM的构造,JS环境里对DOM操作又会导致回流,为DOM树构造造成额外影响。而DOM破坏就是利用HTML元素来影响js,通过 JavaScript,可以重构整个 HTML 文档,可以添加、移除、改变或重排页面上的项目,用DOM来把一些东西给覆盖掉。
在这里插入图片描述

二.绕过一次循环移除所有属性过滤(边循环边删除)

在这里插入图片描述
过滤方式:截取#后面的值,创建一个div,把#后面的值赋值给div,然后抓div的子元素,获取它的属性,再把子元素的属性全部删除(不管也没有用全都删除)
我们先输入#aaa看看

在这里插入图片描述
在输入<script>alert(1)</script>看看结果
在这里插入图片描述
这里是因为用innerHTML添加的<script>无法执行
再用<img src=1 onerror=alert(1)>试试
在这里插入图片描述
发现src没见了,但是onerror还在,按道理应该是两个都要删掉,但是这里却留下了onerror没有删掉,所以我们用单步执行看看里面是怎么运行的
在这里插入图片描述
这里data已经抓取到img标签
在这里插入图片描述
这里已经获取到了第一个src在这里插入图片描述
但是到了下一步,却获取不到onerror了
在这里插入图片描述
最后跳出了循环,没有删除onerror
这其中的原因是:本来是要删除2个,第一个src,第二个onerror,当他删除掉了第一个src的同时,第二个便往前移了移位,变到了现在的一个,for循环现在要删掉第二个时,发现第二个已经没有了,本来的第二个现在跑到了第一个,所以直接循环结束,没有删除onerror。

所以我们可以利用这一机制,将img标签中放入其他的属性,删除其他的属性来让我们要输出有用的属性进行输出。下面来验证这一想法
输入<img src=1 onerror=alert(1) title=aaa>
在这里插入图片描述

可以看到我们的想法确实可以实现,但是src也被删除了,所以我们再添加一个属性,然后换个位置,输入<img x=1 src=1 title=aaa onerror=alert(1)>
在这里插入图片描述
在这里插入图片描述
可以看到输出了哦我们要输出的属性并且成功弹窗
其他答案:<svg/a/onload=alert(1)>

三.两次循环(先进数组,在数组里面循环删除)

在这里插入图片描述
这里的两次循环将属性都放入一个新的数组进行删除,就避免了上面一次循环导致的少删一个元素的情况,所以这里有两种思路(1)不进循环 (2)进循环不删除有用的属性
先试试一次循环的答案放在这里看是什么样子
在这里插入图片描述
可以看到只留下了一个img了

(1)进循环不删有用的数据

如果有一个元素可以拦截el.attributes,有可能删除的不是el而是里面的子元素,比如说在div标签里有form和img两个元素,将img的值删掉让form弹窗;要想进循环只有一个元素肯定不行,所以要想办法变成一个数组来进入循环,所以可以写进2个img
在这里插入图片描述

可以看到确实进入了循环,但是form没有触发,这里就需要用onfocus,而onfocus是input的属性,form没有,但是也要把焦点对到input里面,所以要用到tabindex(tabindex 全局属性 指示其元素是否可以聚焦,以及它是否/在何处参与顺序键盘导航)<form tabindex=1 onfocus="alert(1)" autofocus="ture"><input 20name=attributes><input name=attributes></form> tabindex=1聚焦在input的子元素上;autofocus="ture“自动聚焦
在这里插入图片描述
弹窗可以但是这无限聚焦所以点了确定依旧弹窗,所以要加上执行一次就删除onfocus即<form tabindex=1 onfocus="alert(1);this.removeAttribute('onfocus');" autofocus="ture"><input 20name=attributes><input name=attributes></form> 便可以实现

(2)不进循环

答案<svg><svg/onload=alert(1)>
在这里插入图片描述

在这里插入图片描述
我们在循环前后都打上断点,发现是没有进入循环直接输出了
在这里插入图片描述
2个svg会提前执行,一个却不会
JS会把dom树阻塞,如果一个img或者1个svg都会在js执行后才会执行且属性以及被删除了;而2个svg里的最内侧svg是在html赋值的瞬间就把onload事件加载了所以就没有进入到js的删除事件里
img和其他payload的失败原因在于sanitizer执行的时间早于事件代码的执行时间,sanitizer将恶意代码清除了。由于js阻塞dom树,一直到js语句执行结束后,才可以引入img,此时img的属性已经被sanitizer清除了,自然也不可能执行事件代码了。最内层的svg先触发,然后再到下一层,而且是在DOM树构建完成以前就触发了相关事件;最外层的svg则得等到DOM树构建完成才能触发。
套嵌的svg之所以成功,是因为当页面为root.innerHtml赋值的时候浏览器进入DOM树构建过程;在这个过程中会触发非最外层svg标签的load事件,最终成功执行代码

原网站

版权声明
本文为[朵拉爱学习]所创,转载请带上原文链接,感谢
https://blog.csdn.net/qq_31088019/article/details/126097914