XSS---DOM破坏

文章目录


一.什么是DOM破坏

        在HTML中,如果使用一些特定的属性名(idname)给DOM元素命名,这些属性会在全局作用域中创建同名的全局变量,指向对应的DOM元素。这种行为虽然有时可以方便地访问元素,但也会引发一些潜在的问题,特别是在元素的属性名与JavaScript全局对象的属性名冲突时,可能会破坏正常的DOM操作或脚本运行。这种现象被称为DOM破坏(DOM clobbering)。

二.DOM破坏的原理

  1. 全局变量自动创建

    • 当DOM元素拥有idname属性时,浏览器会自动在全局作用域(即window对象上)创建一个同名的属性,指向该DOM元素。例如,<div id="foo">会创建一个window.foo属性,指向这个div元素。
  2. 属性名冲突

    • 如果元素的idname属性与已有的JavaScript全局对象或内置属性名冲突,会覆盖原有的JS代码。例如,如果有一个<input id="location">,它会覆盖window.location,这会导致脚本中试图访问window.location时得到<input>元素,而不是期望的Location对象。
  3. 影响脚本执行

    • 由于全局变量被覆盖,脚本在访问这些全局变量时会得到意外的结果,导致错误或不可预测的行为。

举个例子 1:

<body>
<img id="x">
<img name="y">
<script>
console.log(x)
console.log(y)
console.log(document.x)
console.log(document.y)
console.log(window.x)
console.log(window.y)
</script>
</body>

 运行结果:

<img id="x">
<img name="y">
<img id="x">
undefined
<img id="x">
<img name="y">

上述案例中,DOM元素<img>拥有id属性=“x”,浏览器会自动在document对象上创建一个同名的属性document.x指向该DOM元素<img>,因此使用document.x可以直接抓取<img>标签,无需通过 getElementById 抓取<img>标签。

案例 1 直观体现了id/name属性的便捷性,而案例 2 会直观体现案例 1 中的便捷性是如何覆盖JS代码原有作用的。

案例 2:

  • 第一步:执行一个document.cookie读取当前网页的cookie值,没有输出任何值
  • 第二步:在新创建的<div>标签中插入一个<img>标签并将该<div>标签插入到<body>中
<body>
    <img name="cookie">
</body>
  • 第三步:我们利用document.cookie函数输出网页的cookie时,输出的结果却由空值改变成<img>标签,
  • 造成这一现象的原因:<img>标签拥有name属性=“cookie”,浏览器会自动在document对象上创建一个同名的属性document.cookie指向该DOM元素<img>
  • 浏览器创建的同名name=cookie属性与已有的JavaScript内置属性名cookie冲突,会覆盖原有的JS代码的作用即执行document.cookie时不是获取当前网页的cookie值而是抓取<img>标签

最后通过案例3来验证一下:

 案例3中,JS代码想要在<body>标签中插入新建的<div>标签,然而执行时却显示找不到函数document.body.appendchild 的执行方法,报错原因是这段JS代码从原来的作用:插入标签 变为抓取<img>标签  浏览器执行的实际代码为:

<img id-"appendChild">(div)

        通过案例1,2,3,不难发现这种行为虽然有时可以方便地访问元素,但也会引发一些潜在的问题,特别是在元素的属性名与JavaScript全局对象的属性名冲突时,可能会破坏正常的DOM操作或脚本运行。这种现象被称为DOM破坏。

        在黑客的攻击行为中,往往会利用DON破坏的特点,构造一个含有恶意脚本的恶意标签从而与已有的JavaScript全局对象或内置属性名冲突,覆盖原有的JS对象,输出恶意标签

        说到这里可能会有疑惑,恶意标签按照原样输出有什么用?回答是:当然没用啦,黑客通常会利用一些标签的特点如:在HTML标签中<a>标签与<textarea>被调用时标签同时会调用自带的toString方法,返回一个表示<a>标签的【字符串】即href属性中的值。

因此我们可以通过如下案例深入了解一下:

   上述案例中存在一个防御框架 DOMPurify,因此想要成功实现攻击只能利用setTimeout函数,该函数将第一个字符串类型的参数ok延迟两秒执行,利用此执行执特点,再配合DOM破坏可以构造如下恶意标签 

<a id="ok" href="tel:alert(1)">

 上述恶意pyload利用DOM破坏原理,通过构造与setTimeout函数参数名相同的标签id,浏览器执行setTimeout函数时会查找HTML中id=ok的字符串类型的标签,而<a>标签被调用时回一个表示<a>标签的【字符串】即href属性中的值,因此setTimeout函数执行时会将<a>标签中href属性的值【tel:alert(1)】当作代码来执行(这里若使用javascript会被防御框架过滤,因此利用该框架中1白名单函数tel,也可以执行JS脚本)。

三.嵌套标签的DOM破坏

常见的网页源代码通常会出现x.y形式的JS代码?如果碰见这种两层结构我们应该怎么办呢?我们可以试试上面的方法:

<div id="x">
	<a id="x" name="y" href="1:XSS">
</div>
<script>
	console.log(x);
</script>

        显然,当我们试图用id=x进行DOM破坏时,浏览器无法确定我们需要获取的标签是哪一个,因此会显示既可获取<div>标签又可获取<a>标签。

        现在让我们试试用两个id=x是否能够通过DOM破坏获取<div>标签和<a>标签集合呢?

<div id="x">
	<a id="x" name="y" href="1:XSS">
</div>
<script>
	console.log(x.x);
</script>

 显然利用两次ID=x是能够获取<div>标签和<a>标签的集合,然而在DOM破坏中我们并非要获取标签而是要获取标签中的字符串从而能够完成恶意攻击,因此我们首先需要获取<a>标签,方法如下

<div id="x">
	<a id="x" name="y" href="1:XSS">
</div>
<script>
	console.log(x.y);
</script>

演示案例:

let defaultAvatar = window . defaultAvatar /|
{ avatar :'/ resources / images / avatarDefault . svg '}

 let avatarImgHTML ='< img class =
" avatar " src ="+( comment . avatar ? escapeHTML .( comment.avatar ):
 defaultAvatar.avatar )+'">;

这段JS代码的作用是在评论中显示用户的头像图片。代码中使用了两个变量:defaultAvataravatarImgHTML

defaultAvatar是一个对象,它包含了一个属性avatar,其值为头像的默认路径'/resources/images/avatarDefault.svg'

avatarImgHTML是一个字符串,它表示要显示的头像图片的HTML标签。字符串中使用了三元运算符来判断评论对象comment是否有avatar属性。如果有,则使用comment.avatar作为头像路径;如果没有,则使用defaultAvatar.avatar作为头像路径。这里还调用了一个函数escapeHTML,用于转义HTML字符串中的特殊字符。

最终生成的HTML标签会把头像图片的路径插入到src属性中,显示在评论中。

在上面这个嵌套标签defaultAvatar.avatar的形式是x.y,我们可以在评论区中输入XSS-pyload:

<a id=defaultAvatar>
<a id=defaultAvatar name=avatar href="cid:&quot;onerror=alert(1)//">

当我们再次访问插入pyload的网页时,会执行window . defaultAvatar获取我们插入的pyload,接着执行下面的代码:

 let avatarImgHTML ='< img class =
" avatar " src ="+( comment . avatar ? escapeHTML .( comment.avatar ):
 defaultAvatar.avatar )+'">;

创建一个<img>标签,当使用defaultAvatar.avatar作为头像路径时,会取出恶意pyload中第二个<a>标签中的href属性(<a>标签被调用时,以字符串形式输出href中的值),最终形成如下形式的<img>标签,由于src不正确,自动执行onerror中的JS攻击代码。

<img src="cid" onnerror=alert(1)//">

//:注释后面的引号"


总结

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

北 染 星 辰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值