DOM破坏绕过XSSfilter例题

news2024/11/26 0:39:57

目录

一、什么是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.coloradmin.cn/o/949267.html

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

相关文章

微信小程序请求接口返回的二维码(图片),本地工具和真机测试都能显示,上线之后不显示问题

请求后端接口返回的图片&#xff1a; 页面展示&#xff1a; 代码实现&#xff1a; :show-menu-by-longpress"true" 是长按保存图片 base64Code 是转为base64的地址 <image class"code" :src"base64Code" alt"" :show-menu-by-long…

Linux通信--构建进程通信System-V 消息队列|信号量

文章目录 目录 一、消息队列 二、信号量 1.互斥 2.信号量 一、消息队列 消息队列提供了从一个进程向另一个进程发送数据块的方法每个数据块都被认为是有一个类型&#xff0c;接收者进程接收的数据块可以有不同的类型值IPC资源必须删除&#xff0c;不会随进程自动清楚&#…

软件系统测试的类型和方法有哪些?

在软件开发过程中&#xff0c;系统测试是至关重要的一步&#xff0c;它可以帮助客户确保软件系统的质量和稳定性。本文将从多个角度出发&#xff0c;详细描述软件系统测试的类型和方法。 一、软件系统测试的类型 1、静态测试&#xff1a;在软件开发的早期阶段&#xff0c;通过…

Apollo配置中心介绍

更多内容参看官网文档&#xff1a;https://www.apolloconfig.com/#/zh/README 架构设计 Config Service和Admin Service都是多实例、无状态部署&#xff0c;所以需要将自己注册到Eureka中并保持心跳在Eureka之上我们架了一层Meta Server用于封装Eureka的服务发现接口Client通过…

Python基础算法——反转链表

视频详解&#xff1a;https://www.bilibili.com/video/BV1sd4y1x7KN/?spm_id_from333.788&vd_source11069f01f7471094186b646e3a184ca3 一、反转链表 LeetCode 206题&#xff1a;https://leetcode.cn/problems/reverse-linked-list/description/ 给你单链表的头节点 h…

lab11 net

background 在开始写代码之前&#xff0c;回顾一下xv6book的第五章会有帮助你将使用E1000去处理网络通信 E1000会和qemu模拟的lan通信在qemu模拟的lan中 xv6的地址是10.0.2.15qemu模拟的计算机的地址是10.0.2.2 qemu会将所有的网络包都记录在packets.pcap中文件kernel/e1000.…

【CSS左右上角斜标签】CSS实现左右上角飘带功能,左右上角斜标签(附源码)

文章目录 写在前面涉及知识点实现效果1、实现过程1.1左上角飘带Html代码Css代码效果 1.2右上角飘带Html代码Css代码效果 2、源码分享2.1 百度网盘2.2 123网盘2.3 邮箱留言 总结 写在前面 其实在公司页面开发过程就遇到过&#xff0c;需要在方块右上角展示一个斜的文字或者告警…

gitee上传本地项目bug

&#x1f92e;这个破bug不知道浪费了多长时间&#xff0c;以前没有记录&#xff0c;每次都忘记&#xff0c;这次记下来 问题描述 gitee创建仓库&#xff0c;然后根据它提示的如下命令&#xff0c;但一直报错 原因分析&#xff1a; 把命令复制出来&#xff0c;粘贴到Sublime …

印尼语翻译,如何提升翻译质量

据了解&#xff0c;印尼是东南亚地区的重要国家&#xff0c;与中国有着密切的经济联系。随着中印两国经贸合作的日益加深&#xff0c;印尼语翻译需求也越来越大。那么&#xff0c;印尼语翻译有什么特点&#xff0c;如何提升印尼语翻译质量&#xff1f; 业内人士指出&#xff0c…

百度百科词条怎么更新?怎么能顺利更新百科词条?

企业和个人百度百科词条的更新对于他们来说都具有重要的意义&#xff0c;具体如下&#xff1a; 对企业来说&#xff1a; 塑造品牌形象&#xff1a;百度百科是一个常被用户信任并参考的知识平台&#xff0c;通过更新企业词条可以提供准确、全面的企业信息&#xff0c;帮助企业塑…

8种最常用的3D CAD中性格式

CAD&#xff08;计算机辅助设计&#xff09;文件是包含物理对象 3D 和 2D 模型的数字文件。 CAD 文件可以包含几何数据、制造数据、材料属性和其他产品/过程数据等信息。 从设计到生产&#xff0c;一切都从 CAD 文件开始。 推荐&#xff1a;用 NSDT编辑器 快速搭建可编程3D场…

vue项目中使用开源Vditor

Vditor 是一款所见即所得编辑器&#xff0c;支持 Markdown。 支持多种前端框架 这里介绍在vue中使用包括编辑所见即所得模式&#xff0c;以及仅仅预览展示 更多细节和用法请参考 Vditor - 浏览器端的 Markdown 编辑器&#xff0c;谢谢 ❤️ 所见即所得&#xff08;编辑预览状…

Windows安装6s模型

官网给出了详细的安装步骤 第一步&#xff1a;安装编译器 安装GnuWin32&#xff0c;按照提示安装&#xff0c;安装到你想安装的地方&#xff0c;记住目录。 安装G77&#xff0c;下载链接里面的Fort99.zip&#xff0c;将G77文件夹提取到C盘根目录。 将这两个目录的bin目录添加…

低代码/无代码平台:加速应用开发的工具

在数字化时代&#xff0c;软件应用已经成为企业和组织不可或缺的一部分。然而&#xff0c;传统的应用开发过程往往需要大量的时间、资源和专业知识。为了解决这个问题&#xff0c;低代码/无代码平台应运而生&#xff0c;它们为开发者提供了一种更快速、更简便的应用开发方式。本…

Spring Security注销后未正确保存空的SecurityContext漏洞CVE-2023-20862

文章目录 0.前言漏洞Spring Security介绍 1.参考文档2.基础介绍3.解决方案3.1. 升级版本3.2. 临时替代方案 4.Spring Security使用教程简单代码示例 0.前言 背景&#xff1a;公司项目扫描到 Spring-security 组件 注销后未正确保存空的SecurityContext CVE-2023-20862 漏洞 高…

基于 Docker 的 MySQL 主从复制搭建(Mac M1版本)

系统&#xff1a;Macbook M1 镜像版本&#xff1a;mysql:5.7 如果是要查 slave连接不上 master的问题&#xff0c;可以直接跳到文章末尾踩坑处 准备工作 拉取镜像 docker pull mysql:5.7本地数据卷挂载 因为mysql不挂载的话&#xff0c;重启丢失数据&#xff0c;所以在本地创…

低价监测的必要性

当品牌线上数据变多时&#xff0c;监测工作就变得非常重要了&#xff0c;品牌的线上监测工作&#xff0c;一般是围绕价格进行的&#xff0c;监测价格有无低价&#xff0c;也是看渠道是否健康的一种体现&#xff0c;当品牌线上渠道存在很多低价链接时&#xff0c;品牌要及时的进…

得物一面,场景题问得有点多!

题目来源&#xff1a;https://www.nowcoder.com/discuss/525371909735792640 前文 本期是【捞捞面经】系列文章的第 1 期&#xff0c;持续更新中…。 《捞捞面经》系列正式开始连载啦&#xff0c;据说看了这个系列的朋友都拿到了大厂offer~ 欢迎星标订阅&#xff0c;持续更新…

数据艺术:精通数据可视化的关键步骤

数据可视化是将复杂数据转化为易于理解的图表和图形的过程&#xff0c;帮助我们发现趋势、关联和模式。同时数据可视化也是数字孪生的基础&#xff0c;本文小编带大家用最简单的话语为大家讲解怎么制作一个数据可视化大屏&#xff0c;接下来跟随小编的思路走起来~ 1.数据收集和…

电商API数据共享(淘宝拼多多京东1688阿里巴巴国际站Lazada)

国内外主流电商平台二十多个&#xff0c;商品数据订单数据买家卖家数据齐全&#xff0c;支持高并发请求 测试API列表 获取api_key&secret 阿里巴巴国际站商品详情数据 "item": {"num_iid": "60840463360","title": "Slip-o…