xss-domcobble绕过XSSfilter

目录

DOM破坏的原理

例题

多层标签

HTMLCollection

一些常见的标签的关系

三层标签如何获取

例题


DOM破坏的原理

DOMClobber是一种攻击技术,它利用了DOM(文档对象模型)的特性来破坏或修改网页的结构和功能。

DOMClobber攻击通常发生在Web应用程序中,其中攻击者能够注入恶意代码或修改网页的DOM结构。DOMClobber攻击的目标是修改网页中的关键元素,例如修改表单的提交目标、修改链接的目标URL等。

攻击者可以通过修改网页的DOM结构来欺骗用户或实施其他恶意行为。例如,攻击者可以修改网页中的表单目标,使用户的输入数据被发送到攻击者控制的服务器,从而窃取用户的敏感信息。攻击者还可以修改网页中的链接,使用户被重定向到恶意网站。

为了防止DOMClobber攻击,开发人员应该对用户输入进行充分的过滤和验证,并使用安全的编码方式来处理和显示用户输入。此外,开发人员还应该使用安全的DOM操作方法,避免使用直接的innerHTML或eval等危险的操作。

我们来举一个例子

打印出来如下

通过打印<img>标签中的id或者name属性值,我们获取到了整个<img>标签,从中我们也发现了规律,直接打印x,y不管是id还是name都可以打印出来,而通过document来获取x,y只能打印出name属性的标签,window和直接打印的结果是一样的,都可以打印。

再看下面的例子

下面这个例子可以看到cookie开始是空值,然后创建了一个div元素,在div里面添加了<img name=cookie>标签,然后添加到body里面去,这时候再打印cookie,发现变成了<img name="cookie">,这个例子成功地让本来为空值的cookie有了值,而且是我们可以控制的。

然而得到一个标签对象并不是我们想要的,有些函数的参数并不是一个对象,而是字符串这就需要函数在调用自己时,自己本身有一个ToString函数能够转换为字符串,然后让函数执行,所以我们需要一个自身拥有ToString函数的标签,而不是继承父类Object的ToString函数

可以看到一个对象调用父类的toString函数就会返回[object object],所以我们需要一个本身有toString函数的标签,通过下面的脚本过滤出了自身拥有toString函数的标签,HTMLAreaElement()和HTMLAnchorElement(),也就是<textarea>和<a>标签,所以这两个标签我们可以利用。

所以我们可以通过以下代码来进⾏fuzz 得到可以通过toString ⽅法将其转换成字符串类型的标签

Object.getOwnPropertyNames(window)
.filter(p => p.match(/Element$/))
.map(p => window[p])
.filter(p => p && p.prototype && p.prototype.toString 
!== Object.prototype.toString)

例题

这道题通过get参数将内容写入h2标签内,而且有过滤框架DOMPurify,这个过滤框架由安全团队cure53开发,以我们的技术很难绕过,但是注意setTimeout函数内的ok参数,这里的JS代码是没有任何关于ok参数的定义的,所以我们可以使用DOM破坏。XSS Game - Ok, Boomer | PwnFunction

构造ok参数,因为setTimeout函数执行字符串,所以需要用到<a>或者<textarea>标签

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

因为DOMPurify框架过滤了javascript,所以我们用tel,tel也可以执行script脚本

多层标签

如果我们需要获取一个标签下的子标签的内容,怎么获取呢?可以直接x.y吗?

很可惜,无法获取。

HTMLCollection

上述结果中,让我们值得注意的是我们可以通过 collection[name] 的形式来调⽤其中的元素,所以我们似乎可以通 ,过先构建⼀个HTMLCollection ,再通过 collection[name] 的形式来调⽤。
<div id = "x" >
<a id = "x" name = y href = "1:hasaki" ></a>
</div>
此时x指代了一个集合,既有div也有a标签,然后再获取它的y属性。

一些常见的标签的关系

form->button  form->fieldset  form->image  form->img   form->input  form->object            form->output

三层标签如何获取

那么三层标签又该如何处理呢?

如果有三层标签,就需要要⽤到以上两种技巧来构建了,先分析x.y,x是一个集合,然后获取y,利用了第一种方法--集合方式,获取了第一个form标签然后x.y.z,因为form和output标签存在关系,可以直接调用y.z,利用了第二种方法--标签关系最后x.y.z.value就成功拿到output标签内的内容。


这个先⽤⼀个HTMLCollection 获取第⼆级,再在第⼀个表单中⽤output 标签。

例题2

以下是他的js代码。


const data = decodeURIComponent(location.hash.substr(1));
const root = document.createElement('div');
//data为URL后的hash值,然后创建了一个div标签,把我们输入的hash值放进了div这个标签里面.
root.innerHTML = data;
 
// 这里模拟了XSS过滤的过程,方法是移除所有属性
for (let el of root.querySelectorAll('*')) {
    let attrs = [];//第一个for循环拿出了div元素的所有后代元素,用el表示,并且定义了一个空数组attrs.
    for (let attr of el.attributes) {
        attrs.push(attr.name);//第二个for循环拿出了后代元素的所有属性,用attr表示,然后将属性添加到attrs数组里.
    }
    for (let name of attrs) {
        el.removeAttribute(name);
    }//第三个for循环拿出了attrs数组里面的属性,用name表示,然后移除掉这个元素的该属性.
}
 
document.body.appendChild(root); //最后将div添加到body里面去.
我们可以直接看下面这个例子
你的img的所有值被删除,这就是上述js代码的功能,移除掉我们输入标签的所有属性。如果还不理解可以进行断点调试。
我们最主要的想法就是让el.attributes不要去实现他原有的功能,而是被我们的自定义代码所取代。
那么我们来看一下playload
 <style>@keyframes x{}</style><form style="animation-name:x" onanimationstart="alert(1)"><input id=attributes><input id=attributes></form>

这段代码的主要作用是创建一个带有两个输入字段的表单,并在表单元素的动画开始时触发一个警告框,但实际上由于CSS动画为空,所以没有实际的动画效果,即表单元素的动画开始时,将触发alert(1)。

这是chatgpt对于这段代码的解读,我们这样写就是用来破坏el.attributes属性的,而上文我们的标签关系中有form和input这个关系属性的,可以直接调用x.y,所以代码中的el.attributes正好是我们的input标签,那为什么不用一个input标签,而是两个呢?

因为在for循环中el.attributes需要是可迭代的,而一个input标签只是一个对象,所以是不可迭代的

报错如下

所以我们需要两个input标签来组成一个集合,这时,集合就是可迭代的了根据代码,首先到style标签,没有属性可删,然后到form标签因为迭代对象变成了input标签集合,此时attr就变成了undefined,所以attr.name也就不存在,此时attrs数组获取不到form标签里的任何属性,自然下面的for循环也不会删除form表单的任何属性。

最后到我们的两个input标签,因为此时目的已经达到,删除了属性也无妨,最后成功绕过。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值