XSS- DOMclobbering与svg深度利用

目录

源码展示

[解法一:绕过过滤-DOM clobbering](#解法一:绕过过滤-DOM clobbering)

[什么是DOM clobbering](#什么是DOM clobbering)

[DOM clobbering原理](#DOM clobbering原理)

全局变量自动创建

属性名冲突

影响脚本执行

逐过程分析


源码展示

html 复制代码
<script>
 const data = decodeURIComponent(location.hash.substr(1));;
 const root = document.createElement('div');
 root.innerHTML = data;

 // 这里模拟了XSS过滤的过程,方法是移除所有属性,sanitizer
 for (let el of root.querySelectorAll('*')) {
  let attrs = [];
  for (let attr of el.attributes) {
   attrs.push(attr.name);
  }
  for (let name of attrs) {
   el.removeAttribute(name);
  }
 }    
  document.body.appendChild(root); 

</script>

题目分析:可以看到这是个明显的DOM XSS,用户的输入会构成一个新div元素的子结点,但在插入body之前会被移除所有的属性(例如:<img src=x οnerrοr=alert(1)> 经过上述代码过滤后会变为<img>,使得我们传入的数据失效)

解法一:绕过过滤-DOM clobbering

什么是DOM clobbering

DOM clobbering主要是用来进行DOM型的XSS攻击,其可以篡改JS函数原本的属性恶意插入一些XSS代码到页面的JS中去,它的特征就是利用了元素配置id或name属性后可以使用包括document、window、自己名称的形式进行访问(假如我们写了一个a标签,给他了一个id和name,那么我们就可以通过id或name来拿到这个a标签)。其可以对document的属性进行恶意的替换。特别是在元素的属性名与JavaScript全局对象的属性名冲突时,可能会破坏正常的DOM操作或脚本运行从而影响dom树的结构造成破坏。也是这一特性让它有了DOM COLBBERING这个名号。

DOM clobbering原理

全局变量自动创建

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

属性名冲突

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

影响脚本执行

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

实例讲解1:

控制台打印的结果为:

通过上述结果分析可得:id和name中的值可以直接引用,引用的值即为标签的全部,但使用document可进行name引用,不可进行id引用。 DOM元素<img>拥有id属性="x",浏览器会自动在document对象上创建一个同名的属性document.x指向该DOM元素<img>,因此使用document.x可以直接抓取<img>标签,无需通过 getElementById 抓取<img>标签。

实例讲解2:

可以看到输出值为空

而当我们新创建的<div>标签中插入一个<img>标签并将该<div>标签插入到<body>中后,再利用document.cookie函数输出网页的cookie时,输出的结果却由空值改变成<img>标签

造成这一现象的原因:

<img>标签拥有name属性="cookie",浏览器会自动在document对象上创建一个同名的属性document.cookie指向该DOM元素<img>

浏览器创建的同名name=cookie属性与已有的JavaScript内置属性名cookie冲突,会覆盖原有的JS代码的作用即执行document.cookie时不是获取当前网页的cookie值而是抓取<img>标签

这种行为虽然有时可以方便地访问元素,但也会引发一些潜在的问题,特别是在元素的属性名与JavaScript全局对象的属性名冲突时,可能会破坏正常的DOM操作或脚本运行。我们可以利用这种方法。

逐过程分析

html 复制代码
<script>
 const data = decodeURIComponent(location.hash.substr(1));;
 const root = document.createElement('div');
 root.innerHTML = data;

 // 这里模拟了XSS过滤的过程,方法是移除所有属性,sanitizer
 for (let el of root.querySelectorAll('*')) {
  let attrs = [];
  for (let attr of el.attributes) {
   attrs.push(attr.name);
  }
  for (let name of attrs) {
   el.removeAttribute(name);
  }
 }    
  document.body.appendChild(root); 

</script>

payload:

html 复制代码
<style>@keyframes x{}</style><form style="animation-name: x" onanimationstart="alert(1)"><input id=attributes><input id=attributes>

对代码进行调试(n+f12):

当程序走进第一个style标签中,因为没有属性,所以不会进行过滤

当走进form标签中时,因为form中还嵌套了两个input标签,而他们的id刚好为attributes,所以程序中的el.attributes刚好把两个input标签拿到了,变成一个数组[0:input#attributes,1:intup#attributes]

然后attr拿出了数组中的第一个元素:input#attributes ,但此时input#attributes中的name为" ",所以下面的代码就不会移除name

然后再拿出数组中第二个元素,name也为空

当循环完成后,程序又走进input标签中,此时input的name会被程序过滤掉

所以最后的结果就变为

html 复制代码
<style>@keyframes x{}</style><form style="animation-name: x" onanimationstart="alert(1)"><input><input>

可以看到我们的恶意代码并没有被过滤掉,弹窗成功!

相关推荐
东方翱翔4 分钟前
CSS的三种基本选择器
前端·css
Fan_web27 分钟前
JavaScript高级——闭包应用-自定义js模块
开发语言·前端·javascript·css·html
yanglamei196235 分钟前
基于GIKT深度知识追踪模型的习题推荐系统源代码+数据库+使用说明,后端采用flask,前端采用vue
前端·数据库·flask
千穹凌帝35 分钟前
SpinalHDL之结构(二)
开发语言·前端·fpga开发
冯宝宝^39 分钟前
基于mongodb+flask(Python)+vue的实验室器材管理系统
vue.js·python·flask
dot.Net安全矩阵1 小时前
.NET内网实战:通过命令行解密Web.config
前端·学习·安全·web安全·矩阵·.net
Hellc0071 小时前
MacOS升级ruby版本
前端·macos·ruby
前端西瓜哥1 小时前
贝塞尔曲线算法:求贝塞尔曲线和直线的交点
前端·算法
又写了一天BUG1 小时前
npm install安装缓慢及npm更换源
前端·npm·node.js
cc蒲公英1 小时前
Vue2+vue-office/excel 实现在线加载Excel文件预览
前端·vue.js·excel