当前位置:网站首页>DOM破环和两个实验的复现
DOM破环和两个实验的复现
2022-08-03 03:33:00 【钟情妺喜107】

首先由图可知,我们给button的标签设置一个id=btn
然后在script中用window.btn来抓取button的id
观察结果我们发现他将整个标签的内容都抓取了出来。
首先我们来了解一下DOM和window的关系,如果你在HTML中,设定一个有id的元素之后,在js中就可以直接操作,又由于js的作用域规则,就算直接用btn也可以,因为在当前的作用域找到时就会往上找,一路找到window
只需要记一个规范:不需要getE1ementById, 也不需要queryselector ,只要直接用与1d同名的变量去拿,就能得到。
在html 的说明文档中节选两个重点:
1. the value of the name content attribute for all embed, form, 1img , and object elements that have a non. empty name
content attribute
2. the value of the id content atribute for all HTML elements that have a non.empty id content atribute
也就是说除了id可以直接用window存取,embed, form, img和object这四个标签用name也可以操作:
由此我们总结出:我们是有机会通过HTML元素来影响JS的!
而我们可以把这个手法用在攻击上。
那这个利用HTML元素来影响js,就被我们理解成DOM破坏
那基于上面的例子,我们可以想一下如果是两个元素会怎么样;假设有以下代码
if (window. test1. test2) {
eva1(' ' +window. test1.test2)
}
如果我们想利用Dom破环的技巧来执行任意的js,需要解决两个问题:
1)利用htm标签的属性id,很容易在window对象上创建任意的属性,但是我们能在新对象上创建新属性吗?
2)怎么控制DOM elements被强制转为stringZ后的值,大多数的dom节点被转为string后是[object HTMLInputElement。
让我们从第一个问题开始。最常引用的解决方法是使用<form>标签。标记的每个<input>都属于<form>后代,该属性<form>引用name属性可以取到<input>.
<form id=test1>
<input nane-test2>
</from>
<script>
alert(test1,test2); // alerts " [object HTML InputE 1ement]"
</script>
解决第二个问题就让它遍历HTML中所有可能的元素并检查它们的tostring方法是否继承自
object. prototype或以另一种方式定义。 如果它们不继承自object . prototype,那么可能[object SomeETement] 会返回其他东西。
这样去执行的话,虽然有弹窗,但是返回的是俩个object,而我们想执行的是一个函数,这样返回的话就毫无意义
而在a标签中tostring方法只返回一个href属性值。所以刚刚前面举的例子的解决方案就是,设我们有两个相同的id的值。
<a id =test1>click!</a>
<a id =test1>click2</a>现在又因为我们的id值相同所以返回的结果是HTMLCollection
也就说明window.test1.test1指的就是第一个元素
所以如果再刚刚的a标签中加一个name的属性就ok了
<a id =test1>click!</a>
<a id =test1 name=test2>click2</a>这样的话就可以把两个都取出来
<a id="test1" name= "test2">click2</a>
好,辅助工作做完了,开始我们的第一个实验
先想一下,现在的这个代码出来的结果是什么是只打印一个呢?还是两个都打印出来呢?


可以看到们取出来的是一个集合,但是如果是window.x.x那取出来的就是第一个啦

分析题目setTimeout只接受字符串和函数,首先我们需要找到ok,只能到window里面找,因为script里没有,按照我们之前学的知识,我们只需要利用dom破坏就可以成功了
但是但是但是并没有弹窗,可是按照原理来说,是正确的
允许的uid只有一些,没有我们用的javascript所以我们需要用到里面的白名单
尝试一下用cid
成功弹窗


但是我们发现只删除了一个src,而把这个最不想要的onerror留下了了
这就又涉及到了循环的过程中,attr首先匹配到的是src元素,然后就会直接删除,删除了之后,紧跟着的这个onerror会自动往前移动,来替代了,之前这个位置,这时候我们要知道索引也跟着变化了,所以再循环的时候发现没有了,就跳出了循环,所以留下了这个onerror
再来看我们的两个循环
基于上面的代码添加一个循环,一个用来删除,一个用来循环,两不耽误
可以看到是对的,就剩下我们的ing标签了 接下来我们就可以考虑是删除一些没用的数据让我们的循环正常进行,还是压根不进入循环
首先来分析删除没用的:根据前面讲的,我们利用dom破环可以实现
很明显这个是打印整个标签的例子,所以我们应该插入一个form标签,然后让img进入循环
但是天公不作美,这时候我们发现
还是报错,为什么呢?原因是因为可迭代对象有一个特征就是必须是for循环,现在进入的只有一个元素,不能循环,所以我们得想办法让他变成集合或数组,刚好前面提到到集合,所以我们可以用两个id的值来组成集合
现在img里的问题解决了,但是from里还缺少一个触发事件,那就用onfocus对焦来触发,那我们就需要把img更换为input因为它不是from的的属性,问题又来了,我们还需要一个全局属性来实现自动对焦,查资料发现tabindex可以实现
tabindex:全局属性,以及它是否(在何处)参与顺序键盘导航这个时候就可以正常弹出弹窗了
然后再考虑不进入循环,个人认为,这是最简单的一种方法,也是最好理解的一种,利用两个\<svg>\<svg οnlοad=alert(1)>来绕过
让他在进入循环之前就执行
这就是底层的问题了在DOM树构建完成之后,会触发DOMContentLoaded事件,然后会加载脚本或者图片,最后执行全部加载完成后才会触发load事件。
所以总结来说就是当你为你的页面root.innerHtml赋值的时候。浏览器就会去找dom树底层构建的过程,而这个过程就会触发最外层的svg,所以就会正常的弹窗。
边栏推荐
猜你喜欢

Senior ClickHouse -

【笔记】混淆矩阵和ROC曲线

金仓数据库 Pro*C 迁移指南( 4. KingbaseES 的 Pro*C 迁移指南)

Task Scheduler 计划定时任务,修改时报错: One or more of the specified arguments are not valid

浅谈用KUSTO查询语言(KQL)在Azure Synapse Analytics(Azure SQL DW)审计某DB账号的操作记录

基于flowable的upp(统一流程平台)运行性能优化(2)

Redshift贴logo的方法

Auto.js Pro 编写第一个脚本hello world

15【背景 渐变色】

什么是数据标注? 数据标注公司主要做什么?
随机推荐
我的“眼睛”就是尺!
vscode access denied to unins000.exe
22 ES6 knowledge points
使用docker容器搭建MySQL主从复制
问下有用sql server flink-sql-connector-sqlserver-cdc-2
七夕??继续肝文章才是正道!!Auto.js 特殊定位控件方法
GD32学习笔记(3)NAND Flash管理
【STM32】入门(三):按键使用-GPIO端口输出控制
C语言实验十二 指针(二)
ClickHouse卸载、重安装
【GraphQL】使用Hot Chocolate和.NET 6构建GraphQL应用
DPDK mlx5 驱动使用报错
C语言实验十一 指针(一)
金仓数据库 MySQL 至 KingbaseES 迁移最佳实践(3. MySQL 数据库移植实战)
vant-field中colon属性为true报错
Redshift贴logo的方法
记录学习--Navicat使用自定义数据库列表
工业边缘计算研究现状与展望
iScroll系列之下拉刷新 + 上拉加载更多
js Fetch返回数据res.json()报错问题