DOM破坏绕过XSSfilter例题

目录

一、什么是DOM破坏

二、例题1

三、多层关系

1.Collection集合方式

 2.标签关系

3.三层标签如何获取

四、例题2

五、例题3

1.代码审计 

2.payload分析


一、什么是DOM破坏

DOM破坏(DOM Clobbering)指的是对网页上的DOM结构进行不当的修改,导致页面行为异常、性能问题、安全风险或其他不良影响的情况。

就是⼀种将 HTML 代码注⼊⻚⾯中以操纵 DOM 并最终更改页面上 JavaScript 行为的技术

这里我们举一些例子就能更好地解释

可以看到打印的结果如下

通过打印<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>标签

所以这两个标签我们可以利用

二、例题1

然后我们来看一道例题Ok, Boomer. | XSS Warmups

XSS Game - Ok, Boomer | PwnFunction

这道题通过get参数将内容写入h2标签内,而且有过滤框架DOMPurify

这个过滤框架由安全团队cure53开发,以我们的技术很难绕过

但是注意setTimeout函数内的ok参数

这里的JS代码是没有任何关于ok参数的定义的,所以我们可以使用DOM破坏

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

payload:

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

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

三、多层关系

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

显然不行,返回undefined 

1.Collection集合方式

既然直接x.y不行,那我们可以用一个集合来做x,然后再获取y

此时x指代了一个集合,既有div也有a标签,然后再获取它的y属性

 

 2.标签关系

要想知道哪些标签能直接调用x.y,可以通过一段代码来获取,但代码有点长,就直接说结果了

  • form---button
  • from---fieldset
  • from---img
  • from---image
  • from---input
  • from---object
  • from---output
  • from---select
  • from---textarea

这九种组合可以直接调用x.y,来获取子标签内容

比如

3.三层标签如何获取

如果有三层标签,就需要要⽤到以上两种技巧来构建了

先分析x.y,x是一个集合,然后获取y,利用了第一种方法--集合方式,获取了第一个form标签

然后x.y.z,因为form和output标签存在关系,可以直接调用y.z,利用了第二种方法--标签关系

最后x.y.z.value就成功拿到output标签内的内容

四、例题2

首先审计代码,data为URL后的hash值,然后创建了一个div标签,把我们输入的hash值放进了div这个标签里面

第一个for循环拿出了div元素的所有后代元素,用el表示

定义了一个空数组attrs

第二个for循环拿出了后代元素的所有属性,用attr表示

然后将属性添加到attrs数组里

第三个for循环拿出了attrs数组里面的属性,用name表示

然后移除掉这个元素的该属性

最后将div添加到body里面去

const data = decodeURIComponent(location.hash.substr(1));
const root = document.createElement('div');
root.innerHTML = data;// 这里模拟了XSS过滤的过程,方法是移除所有属性
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>alert(1)</script>不就行了吗

答案是不可以的,因为innerHTML考虑到安全问题将script过滤掉了

这道题可以使用DOM破坏和CSS来触发XSS

直接来看payload

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

首先定义了一个CSS动画@keyframes x{},然后form表单里面调用这个样式

然后属性onanimationstart执行alert,意思是当animation动画开始时执行alert

CSS样式我已经忘得差不多了,但是大概是这样一个意思

我们再看后面的内容,一个form表单内包含两个id属性为attributes的input标签

看到这个id属性值应该能猜到这是什么作用了,没错,它就是用来破坏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标签,因为此时目的已经达到,删除了属性也无妨

最后成功绕过

五、例题3

XSS Game - Jason Bourne | PwnFunction

<script>/* Helpers */const bootstrapAlert = (msg, type) => {return (`<div class="alert alert-${type}" role="alert">${DOMPurify.sanitize(msg)}</div>`)}document.getAlert = () => document.getElementById('alerts');
</script><script>/* Welcome */let name = (new URL(location).searchParams.get('name')) || "Pamela Landy";document.write(bootstrapAlert(`<b>Operation Treadstone</b>: Welcome <u>${name}</u>.`, 'info'))
</script><!-- alerts -->
<div id="alerts"></div><script>/* Handle to `#alert` */let alerts = document.getAlert();/* Treadstone Credentials */let identification = Math.random().toString(36).slice(2);let code = Math.floor(Math.random() * 89999 + 10000);/* Default Credentials */DEFAULTS = {};DEFAULTS[identification] = code;
</script><script>/* Optional Comment */if (location.hash) {let comment = document.createComment(decodeURI(location.hash).slice(1));document.querySelector('#alerts').appendChild(comment);}
</script><script>/* Use `DEFAULTS` to init `SECRETS` */SECRETS = DEFAULTS/* Increment the `code` before the check */let secretKey = new URL(location).searchParams.get('key') || "TREADSTONE_WEBB";SECRETS[secretKey] += 1;/* Authorization Check */if (SECRETS[secretKey] === SECRETS[identification]) {confirm(`Jesus Christ, it's Jason Bourne!`)} else {confirm(`You ain't David Webb!`)}
</script>

1.代码审计 

首先代码审计一波

第一个script块

首先定义了一个函数bootstrapAlert(msg,type),返回值是一个div标签里面包含着msg输入的东西,还使用了DOMPurify框架进行过滤

之后又定义了一个函数get.Alert,获取id为alerts的元素

第二个script块

首先通过GET传入name参数,如果没有传,默认Pamela Landy

然后调用bootstrapAlert函数,相当于这样

<div class="alert alert-info" role="alert"><b>Operation Treadstone</b>: Welcome <u>${name}</u>
</div>

然后一个id属性为alerts的div标签

第三个script块

首先将函数getAlert()的返回值赋给alerts

之后生成一个0,1的随机数,再将其转换为36进制的字符串,然后切片,去掉前两个字符

再使用Math.random()*89999+10000生成一个10000到89999的随机数赋给code

然后定义了一个DEFAULTS空对象

最后将code赋值给DEFAULTS对象里的identification属性

第四个script块

如果存在location.hash值

那就去掉前面的#号,将hash值取出来,然后以改内容创建注释赋值给comment

最后找到id属性为alerts的标签,将comment添加为它的子元素

第五个script块

首先把对象DEFAULTS赋给SECRETS

之后找到GET参数key,将它赋给secretKey,如果不存在默认为"TREADSTONE_WEBB"

并将secretKey值加1作为属性赋给SECRETS对象

然后if判断SECRETS[secretKey]与SECRETS[identification]是否相等

2.payload分析

初步分析下来我们可以传入三个参数,name、key、location.hash值

由于太菜,自己想了几十分钟没头绪,只有看答案来分析

?name=<img name=getAlert><form id=alerts name=DEFAULTS>&key=innerHTML#--><img src onerror=alert(1337)>

首先传入了一个<img name=getAlert>标签,上面提到getAlert是一个函数

然后传入了一个<form id=alerts name=DEFAULTS>,id和name属性都存在

key传入了innerHTML,可能是想构造.innerHTML,让标签传入

最后传入--><img src οnerrοr=alert(1337)>,前面的-->很有可能是用来闭合注释的

首先解释为什么要传入一个name属性为函数名的标签,是因为想让第三个script块报错

我们是先传入的name,getAlert函数在后面被调用,所以我们可以直接覆盖getAlert函数

此时getAlert就不是一个函数了,而是我们传入的标签,所以就会报错

这样一来整个第三个script代码块就都不会执行

那为什么要让它报错呢?因为报错后,DEFAULTS对象就定义不了

这样一来SECRETS变量就不会被赋值,而是接到我们的form标签,接到我们的标签那就简单了

传入的key值的主要作用是让SECRETS[secretKey]=form.innerHTML,触发我们的弹窗

这段代码很关键,作用是让我们的comment成为id属性为alerts的标签的子标签

document.querySelector('#alerts').appendChild(comment);

而此时的alerts有两个,一个是我们传入的form,还有一个是代码中的div,但是我们是先传入的form,标签顺序在div之前,所以appendChild只会将内容添加到第一个标签内

比如这里,拥有同样id属性的form和div标签,因为form标签在div标签前面,所以被添加了子节点

comment被添加到form后还有一个问题,我认为也是最难理解的,看下面两张图

这张图是没有添加key=innerHTML参数的

这张图是添加了key=innerHTML参数的

前面讲到SECRETS[secretKey]=form.innerHTML,那按照代码来是这样的

form.innerHTML=form.innerHTML+1,关键是这个1的作用是什么?

我的理解是当传入--><img src οnerrοr=alert(1)>时,前面的注释确实是闭合了,但是后面还有一个-->

此时如果没有1,那么-->就会跟在标签后面,而注释会选择最后的-->,所以img标签还是注释没有生效

如果有1,html会认为"-->1"是一个字符串,会换行到下一行,这样img标签就不会被注释掉了

最后触发弹窗

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/57664.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Redis之GEO类型解读

目录 基本介绍 基本命令 geoadd 命令 geopos 命令 geodist 命令 georadius 命令 georadiusbymember 命令 geohash 命令 基本介绍 GEO 主要用于存储地理位置信息&#xff08;纬度、经度、名称&#xff09;添加到指定的key中。该功能在 Redis 3.2 版本新增。 GEO&…

C++炸弹小游戏

游戏效果 小人可以随便在一些元素&#xff08;如石头&#xff0c;岩浆&#xff0c;水&#xff0c;宝石等&#xff09;上跳跃&#xff0c;“地面”一直在上升&#xff0c;小人上升到顶部或者没有血的时候游戏结束&#xff08;初始20点血&#xff09;&#xff0c;小人可以随意放炸…

计算机网络MTU和MSS的区别

在计算机网络中&#xff0c;MTU代表最大传输单元&#xff08;Maximum Transmission Unit&#xff09;&#xff0c;而MSS代表最大分节大小&#xff08;Maximum Segment Size&#xff09;。 1.MTU&#xff08;最大传输单元&#xff09;&#xff1a; MTU是指在网络通信中&#x…

原神世界中的顺序表:派蒙的趣味数据结构讲解

派蒙&#xff0c;那个总是带着疑问眼神的小家伙&#xff0c;是原神世界中的小精灵。他总是充满好奇心&#xff0c;无论是对新的冒险者&#xff0c;还是对各种奇妙的现象。而他的另一个身份&#xff0c;则是原神世界中的数据结构大师。 一天&#xff0c;派蒙遇到了旅行者小森&a…

对开源自动化测试平台MeterSphere的使用感触

1&#xff1a;该平台可以通过接口&#xff0c;参数&#xff0c;配置的维护&#xff0c;然后继续接口自动化“一键测试”&#xff0c;功能还是挺强大的&#xff0c;具体的使用需要研究 MeterSphere的官网&#xff1a;MeterSphere - 专业测试云 2&#xff1a;一键测试在生产环境…

网络服务第二次作业

[rootlocalhost ~]# vim /etc/httpd/conf.d/vhosts.conf <Virtualhost 192.168.101.200:80> #虚拟主机IP及端口 DocumentRoot /www/openlab #网页文件存放目录 ServerName www.openlab.com #服务器域名 </VirtualHost> …

python实现/直播服务器/聊天服务器/的多种解决方案

python有哪些技术栈 实现直播服务器 在Python中&#xff0c;您可以使用以下技术栈来实现直播服务器&#xff1a; Flask&#xff1a;Flask是一个轻量级的Web框架&#xff0c;可用于构建直播服务器的后端。您可以使用Flask编写API端点来处理直播流的控制和管理。 Django&#xf…

两种数据库引擎和聚簇(非聚簇)索引

一&#xff1a;两种数据库引擎区别及如何选择&#xff1f; InnoDB和MyISAM的区别&#xff1f; 1&#xff1a;InnoDB支持事务&#xff0c;而MyISAM不支持事务。这是MYSQL将默认引擎从MYISAM变为INNODB的重要原因之一。 2&#xff1a;INNODB支持外键&#xff0c;而MYISAM不支持…

易云维®FMCS厂务系统创造工厂全新的“数字低碳智能”应用场景

近年来&#xff0c;新一代信息技术的高速发展为传统工业与制造业领域带来了新的机遇。信息技术加持下的制造技术发展出了新的生产方式、产业形态与管理模式。通过搭建FMCS厂务系统进行数字化转型来实现数据互联互通与业务高效协同&#xff0c;助力企业向安全、绿色、节能、高效…

上海港股通开通条件是什么?港股通交易佣金最低多少?

上海港股通权限开通条件有&#xff1a; 1、申请权限开通前20个交易日证券账户日均资产不低于50万元; 2、进行港股知识测试&#xff0c;且测试分数不低于80分; 3、风险承受能力等级需要匹配&#xff0c;无投资经验期限的门槛 港股通的股票范围是香港联合交易所恒生综合大型股…

MATLAB图论合集(二)计算最小生成树

今天来介绍第二部分&#xff0c;图论中非常重要的知识点——最小生成树。作为数据结构的理论知识&#xff0c;Prim算法和克鲁斯卡尔算法的思想此处博主不详细介绍&#xff0c;建议在阅读本帖前熟练掌握。 对于无向带权图&#xff0c;在MATLAB中可以直接以邻接矩阵的方式创建出来…

Flutter实现StackView

1.让界面之间可以嵌套且执行动画。 2.界面的添加遵循先进后出原则。 3.需要使用AnimateView&#xff0c;请看我上一篇博客。 演示&#xff1a; 代码&#xff1a; Stack: import package:flutter/cupertino.dart;///栈&#xff0c;先进后出 class KqWidgetStack {final Lis…

JVM知识点(一)

1、JVM基础概念 &#xff08;1&#xff09;JVM、JRE、JDK JRE&#xff1a;JVM基本类库组成的运行环境就是JRE。JVM自己是无法完成一次编译&#xff0c;处处运行的&#xff0c;需要有一个基本类库告诉JVM如何操作运行&#xff0c;如如何操作文件&#xff0c;连接网络等&#x…

JVM 给对象分配内存空间

指针碰撞空闲列表TLAB 为对象分配空间的任务实际上便等同于把一块确定大小的内存块从Java堆中划分出来。 指针碰撞&#xff1a;&#xff08;Bump The Pointer&#xff09; 堆的内存是绝对规整的&#xff0c;内存主要分为两部分&#xff0c;所有使用过的内存被放在一边&#x…

LeetCode每日一题:823. 带因子的二叉树(2023.8.29 C++)

目录 823. 带因子的二叉树 题目描述&#xff1a; 实现代码与解析&#xff1a; dp hash 原理思路&#xff1a; 823. 带因子的二叉树 题目描述&#xff1a; 给出一个含有不重复整数元素的数组 arr &#xff0c;每个整数 arr[i] 均大于 1。 用这些整数来构建二叉树&#x…

达梦SQL书写注意事项

模糊查询 模糊查询like后面的字段要求用单引号引用&#xff0c;不能使用双引号 select * from user where name like %小组 分组查询 select查询的列字段必须在分组中的字段存在 正确&#xff1a; select name,age from user group by name,age 错误&#xff1a; select * f…

UE 透明物体绘制准备

PassProcessor注册&#xff1a; Engine/Source/Runtime/Renderer/Private/BasePassRendering.cpp透明的5个PassProcessor都继承BassPassProcessor。透明物质绘制&#xff0c;也是走的basepasspixelshader。 REGISTER_MESHPASSPROCESSOR_AND_PSOCOLLECTOR(BasePass, CreateBas…

华为OD机试 - MELON的难题 - 动态规划(Java 2023 B卷 100分)

目录 一、题目描述二、输入描述三、输出描述四、动态规划五、解题思路六、Java算法源码七、效果展示1、输入2、输出3、说明 华为OD机试 2023B卷题库疯狂收录中&#xff0c;刷题点这里 一、题目描述 MELON有一堆精美的雨花石(数量为n&#xff0c;重量各异)&#xff0c;准备送给…

类和对象(上)

&#x1f493;博主个人主页:不是笨小孩&#x1f440; ⏩专栏分类:数据结构与算法&#x1f440; C&#x1f440; 刷题专栏&#x1f440; C语言&#x1f440; &#x1f69a;代码仓库:笨小孩的代码库&#x1f440; ⏩社区&#xff1a;不是笨小孩&#x1f440; &#x1f339;欢迎大…

socket

Socket是一种用于网络通信的编程接口&#xff0c;它提供了在计算机网络中进行数据传输的方法。通过Socket&#xff0c;可以在不同主机之间建立网络连接&#xff0c;并通过发送和接收数据来进行通信。在C语言中&#xff0c;可以使用Socket函数库&#xff08;如BSD Socket或Winso…