当前位置: 首页 > news >正文

XSS | DOM 型 XSS 攻击

关注这个漏洞的其他相关笔记:XSS 漏洞 - 学习手册-CSDN博客

0x01:DOM 型 XSS —— 理论篇

DOM 全称 Document Object Model,使用 DOM 可以使程序和脚本能够动态访问和更新文档的内容、结构及样式。

DOM 型 XSS 是一种特殊类型的反射型 XSS,它是基于 DOM 文档对象模型的一种漏洞。

0x0101:知识前导 - DOM

HTML 的标签都是节点,而这些节点组成了 DOM 的整体结构 —— 节点树。通过 HTML DOM,树中的所有节点均可通过 JavaScript 进行访问。 所有 HTML 元素(节点)均可被修改,也可以创建或者删除节点。

比如下面这个 HTML 代码:

 <!DOCTYPE html><html lang="en"><head><title>网页标题</title></head><body><h1>我的标题</h1><a href="">我的链接</a></body></html>

其对应的 HTML DOM 树的结构如下图所示:

在网站页面中有许多元素,当页面到达浏览器,浏览器会为页面创建一个顶级的 Document object 文档对象,接着生成各个子文档对象,每个页面元素对应一个文档对象,每个文档对象包含属性、方法和事件。

可以通过 JS 脚本对文档对象进行编辑,从而修改页面的元素。也就是说,客户端的脚本程序可以通过修改 DOM 动态修改页面内容,从客户端获取 DOM 中的数据并在本地执行。

由于 DOM 是在客户端修改节点的,所以基于 DOM 型的 XSS 漏洞不需要与服务器端交互,它只发生在客户端处理数据的阶段。

0x0102:DOM 型 XSS 攻击流程

常见的攻击方式: 用户请求一个经过专门设计的 URL,它由攻击者发布,而且其中包含 XSS 代码。服务器的响应不会以任何形式包含攻击者的脚本。当用户的浏览器处理这个响应时,DOM 对象就会处理 XSS 代码,导致存在 XSS 漏洞。

其攻击流程如下图所示:

其整体攻击流程与反射型 XSS 很相似,只不过是因为 DOM 型 XSS 形成的原因比较特别,发现它的安全专家专门提出了这种类型的 XSS。出于历史原因,就把它单独作为一个分类了。

0x02:DOM 型 XSS —— 实战篇

实验工具准备

  • PHP 运行环境:phpstudy_x64_8.1.1.3.zip(Apache2.4.39 + PHP 5.3.29nts)

  • 实验源码包(附配置流程):DOMBasedXSSLab.zip

实验环境的搭建流程我放在了 DOMBasedXSSLab.zip 中了,这里就不多说了,下面直接开始演示。

0x0201:DOM 型 XSS 攻击

在浏览器的导航栏中输入下面的网址,访问实验环境:

 http://127.0.0.1/DOMBasedXSSLab/

可以发现页面发生了跳转,跳转到了一个 404 Not Found 的页面。值得注意的是,该页面回显的 404 - Page XXX Not Found 中的 XXX 部分的内容似乎是通过浏览器 URL 中的 error 参数控制的。

我们可以修改一下导航栏中 error 字段的内容,并重新访问:

 http://127.0.0.1/DOMBasedXSSLab/404.html?error=Blue17

可以发现,error 字段的内容果然会直接回显回页面中,我们右击页面查看网页源码,看看回显的位置:

发现我们传递的参数直接回显在了 <h1> 标签中,那么攻击者可以尝试构造下面的 Payload,来攻击用户:

 http://127.0.0.1/DOMBasedXSSLab/404.html?error=<img src=1 onerror="alert(/You've Been Tricked/)" hidden/>

可以看到,页面成功加载了攻击者传入的 XSS 代码并运行。如果点击了 “确定” 按钮,可以看到,页面基本没有啥影响(弹窗只是为了演示脚本确实被执行了,真攻击没人给你弄这种弹窗):

至此,一个 DOM 型 XSS 攻击的全流程已经演示完毕了。整体流程和反射型其实是差不多的,主要是代码处理方面的问题,反射型 XSS 是后端语言处理用户提交的数据后,将 XSS 攻击代码携带进返回包中传递给客户端;而 DOM 型则是利用用户客户端的 JavaScript 脚本进行触发的,后端返回的数据包中并不包含 XSS 攻击代码,如下图所示:

可以发现,后端返回的数据包中只有页面标签的布局,<h1> 标签中是没有任何内容的,这符合了我们上面讲的 DOM 型 XSS,后端返回的数据包中不包含 XSS 攻击代码的特点。

0x0202:DOM 型 XSS 代码分析

下面是触发 DOM 型 XSS 漏洞的关键代码:

 <h1 id="dom_output"></h1><script>const urlParams = new URLSearchParams(window.location.search); // 获取链接中 ? 号后面参数的部分if (urlParams.has('error')) { // 如果用户传递了 error 参数const errorInfo = urlParams.get('error'); // 获取 error 参数的内容document.getElementById("dom_output").innerHTML = "404 - Page " + errorInfo + " Not Found 未找到"; // 输出回标题}  else { // 如果用户没有传递 error 参数document.getElementById("dom_output").innerHTML = "404 - Page Not Found 未找到";  // 输出回标题}</script>

DOM 型 XSS 程序只有 HTML 代码,并不存在服务器端代码,所以此程序并没有与服务器端进行交互,是一个纯粹的运行在客户端的 JavaScript 脚本代码触发的 XSS 漏洞。

用户访问实验环境后,会跳转到 404 页面,并向该页面传递参数 error=xxxurlParams 识别用户传递过来的参数并进行保存,如果用户传递了 ?error=xxx,则获取 xxx 具体的内容,并通过 document.getElementById("dom_output").innerHTML 的方式,找到 iddom_output 的标签(也就是 <h1> 标签),将用户传递过来的参数拼接并回显。如果用户没有传递 error 参数,则回显默认的内容:404 - Page Not Found 未找到

程序逻辑很简单,就是获取 error 字段的内容并回显,没有做任何过滤,导致了 XSS 漏洞。

当用户对 error 传入 <img src=1 onerror="alert(/You've Been Tricked/)" hidden/> 时, 输出到 <h1> 标签中的内容实际是:

 <h1>404 - Page <img src=1 onerror="alert(/You've Been Tricked/)" hidden/> Not Found 未找到</h1>

此 HTML 代码中包含了一个 <img> 图片标签,链接到地址 1 的图片,这个图片必然不存在,所以导致图片加载错误触发了 onerror 部分的内容,该部分又是一个 JavaScript 代码,此代码会引起浏览器的弹窗,而末尾的 hidden 仅仅是为了隐藏 <img> 标签,让其在页面上不那么显眼而已。

0x03:DOM 型 XSS —— 后记

在构造攻击语句的时候,笔者一开始并没有想用 <img> 标签来触发,笔者一开始构造的链接如下:

 http://127.0.0.1/DOMBasedXSSLab/404.html?error=<script>alert(/You've Been Tricked/)</script>

可以发现,JavaScript 脚本被成功内嵌进了页面,但是却并未被执行。笔者的思考是:由于浏览器解析网页的顺序是从上往下的,所以其执行顺序如下图所示(不知道对不对,反正笔者把自己说服了):

下面是文心一言给的参考中,我觉得最符合情况的一条:

浏览器 DOM 解析和渲染机制 当浏览器解析 HTML 文档时,它会识别 <script> 标签并尝试执行其中的脚本。但是,当脚本是通过 JavaScript 动态添加到 DOM 中时,浏览器会采取不同的策略。特别是,当脚本内容通过 innerHTMLdocument.write() 或其他类似方法动态添加到文档中的,浏览器不会立即执行这些脚本。这是因为浏览器需要区分 “正常的” HTML 解析过程中加载的脚本和后来通过脚本动态添加的脚本。

0x04:参考文献

  • 《Web 安全攻防:渗透测试实战指南》 ISBN 978-7-121-34283-7

相关文章:

  • 828华为云征文|Flexus云服务器X实例实践:部署2048网页小游戏
  • 基于单片机的小车行走加温湿度检测系统
  • 尚硅谷----智尚代驾项目----Day7(续)------预估乘客订单数据之Drools
  • 第五届计算机科学与管理科技国际学术会议(ICCSMT 2024)
  • ROS与无人驾驶学习笔记(一)——ROS基本操作
  • KRTS虚拟网络适配器和 Windows 连接
  • 相机、镜头参数详解以及相关计算公式
  • 2024 Python3.10 系统入门+进阶(十六):正则表达式
  • Eureka原理实践:构建高可用、可扩展的微服务架构
  • 《C++无锁编程:解锁高性能并发的新境界》
  • day01——登录功能
  • npm切换到淘宝镜像
  • Redis——缓存
  • 15年408-数据结构
  • Stable Diffusion绘画 | SDXL模型的优缺点及模型推荐
  • [译] 理解数组在 PHP 内部的实现(给PHP开发者的PHP源码-第四部分)
  • 《剑指offer》分解让复杂问题更简单
  • ES2017异步函数现已正式可用
  • isset在php5.6-和php7.0+的一些差异
  • Linux Process Manage
  • Linux各目录及每个目录的详细介绍
  • node.js
  • vue 个人积累(使用工具,组件)
  • 服务器之间,相同帐号,实现免密钥登录
  • 问题之ssh中Host key verification failed的解决
  • 学习Vue.js的五个小例子
  • Nginx惊现漏洞 百万网站面临“拖库”风险
  • Spark2.4.0源码分析之WorldCount 默认shuffling并行度为200(九) ...
  • ​软考-高级-系统架构设计师教程(清华第2版)【第9章 软件可靠性基础知识(P320~344)-思维导图】​
  • ‌U盘闪一下就没了?‌如何有效恢复数据
  • # Panda3d 碰撞检测系统介绍
  • # windows 安装 mysql 显示 no packages found 解决方法
  • #我与Java虚拟机的故事#连载09:面试大厂逃不过的JVM
  • (Redis使用系列) Springboot 使用redis实现接口幂等性拦截 十一
  • (Spark3.2.0)Spark SQL 初探: 使用大数据分析2000万KF数据
  • (附源码)计算机毕业设计SSM疫情居家隔离服务系统
  • (免费领源码)Java#Springboot#mysql农产品销售管理系统47627-计算机毕业设计项目选题推荐
  • (四)c52学习之旅-流水LED灯
  • (五) 一起学 Unix 环境高级编程 (APUE) 之 进程环境
  • (已解决)Bootstrap精美弹出框模态框modal,实现js向modal传递数据
  • .mp4格式的视频为何不能通过video标签在chrome浏览器中播放?
  • .net 发送邮件
  • .netcore 如何获取系统中所有session_ASP.NET Core如何解决分布式Session一致性问题
  • .vollhavhelp-V-XXXXXXXX勒索病毒的最新威胁:如何恢复您的数据?
  • /run/containerd/containerd.sock connect: connection refused
  • @media screen 针对不同移动设备
  • @德人合科技——天锐绿盾 | 图纸加密软件有哪些功能呢?
  • []FET-430SIM508 研究日志 11.3.31
  • []Telit UC864E 拨号上网
  • [AX]AX2012 SSRS报表Drill through action
  • [bzoj 3534][Sdoi2014] 重建
  • [BZOJ4566][HAOI2016]找相同字符(SAM)
  • [IE编程] 如何编程清除IE缓存
  • [IntelliJ IDEA插件]推荐一款简单方便的插件CodeChrono
  • [JavaWeb玩耍日记]Maven的安装与使用