今天,我们将解释最具挑战性的 XSS 漏洞类型,即基于 DOM 的 XSS。但是,今天的解释将使您更容易理解这种类型,只需仔细阅读即可。我们将解释如何使用 Portswigger Lab 简化信息传递。我们将要研究的实验室的标题是“使用源 location.search 在 document.write 接收器中解决 DOM XSS”。
第一步:
我们将进行 DOM 分析
进入 LAB 后,我们将输入网站上不存在的任何值,例如“gentil”。当我们在搜索框中输入“gentil”时,我们会注意到它在 DOM 中打印了两次,一次在 <h1> 标签之间,另一次在 <img> 标签内,具体来说是在 src 内。
DOM 源代码
DOM 源代码
我们会注意到 <img> 标签正在通过 JavaScript 传递值,这里我们暂停一下来了解发生了什么。
传递给 <img> 标签的值是什么?
搜索框中搜索的单词会传递给 <img> 标签。在我们的例子中,我们在搜索框中搜索的单词是“gentil”。它是如何传递给 <img> 标签的?通过 JavaScript 代码。
为什么要将其传递给 JavaScript 代码?
要理解设计师为何将搜索框中输入的值传递给 JavaScript,我们需要分析 JavaScript 代码来了解其用途。我们看到的这段 JavaScript 代码负责获取页面中搜索框中搜索的单词,并将它们发送到服务器,以便将它们全部存储在一个地方。
网站所有者通过收集其网站内搜索的词汇能获得什么好处?
简而言之:增强他们提供的内容。当他们知道在他们的网站中经常搜索的内容时,他们可以专注于此并优先考虑它。
例如:如果他们的网站专门从事网络安全,并且网站内搜索最多的查询与渗透测试工具有关,那么他们就会重点提供有关渗透测试工具的内容。
这意味着,如果没有这段 JavaScript 代码,搜索过程还能顺利进行吗?
是的,确实如此。此代码不会影响网站内的搜索过程,因此可以轻松完全取消它,而搜索过程将继续有效运行。
第二步:
在基于 DOM 的 XSS 漏洞中,您必须阅读和分析代码以确定是否存在任何可被渗透测试人员利用的错误。
因此,我们现在将分析上述 JavaScript 代码,以了解开发人员如何检索搜索框中输入的值,以及导致 DOM XSS 漏洞的错误是什么。
function trackSearch(query) {
document.write('<img src="/resources/images/tracker.gif?searchTerms='+query+'">');
}
var query = (new URLSearchParams(window.location.search)).get('search');
if(query) {
trackSearch(query);
}
首先,目标:
开发人员希望将搜索到的单词发送到服务器。为了实现这一点,他们选择使用 img 标签(具体来说是在 src 属性中)来执行此任务。要理解这一点,当 img 标签从服务器请求特定图像时,它会将所需图像的路径写入 src 属性中。
像这样:
< img src = “/resources/images/tracker.gif” />
在这种情况下,这是从服务器请求的图像的路径:/resources/images/tracker.gif
明白了img标签与服务端通信之后,开发者将如何将搜索框中输入的值随img请求一起发送呢?
开发人员将搜索框中输入的值写入 img 标签的 src 属性中,并将其发送到服务器。
/resources/images/tracker.gif 之后的?searchTerms='gentil'
使其看起来像这样
/resources/images/tracker.gif?searchTerms='gentil'
现在我们来理解一下:问号“?”的意思是“和”,就好像它在对服务器说,
嘿服务器,我希望你从这个路径 /resources/images/tracker.gif 获取图像,并且服务器获取这个值“gentil”并将其存储在 searchTerms 中并将其保存在服务器上,因为我稍后会需要它。
服务器在响应中回应说:“这是您向我请求的图像,不用担心,我已经在服务器上的 searchTerms 中保存了您发送给我的值,如果您需要它,可以随时检索它。”
现在我们知道,程序员利用服务器对图像的请求来发送在搜索框中输入的值并将其保存在其中。
图片在哪里?为什么他们选择这种特定方法将搜索值发送到服务器?
该图像的尺寸为 1x1 像素,因此您看不到它,因为它非常小,不显眼。事实上,从服务器调用此图像的目的并不是为了在网站内显示它。设计者使用这种方法只是因为它简单、不复杂,并且不会影响页面处理速度来在网站内发送搜索值。不幸的是,他们以不安全的方式编写了它,导致基于 DOM 的 XSS 漏洞。这也解释了为什么设计者专门选择这种方法将值发送到服务器并将它们存储在其中。
第二:
了解程序员如何在 JavaScript 中检索我们输入的值并将其传递。
var query = (new URLSearchParams(window.location.search)).get('search');
在这一行中,设计器使用 window.location.search 检索所有参数,包括与搜索框相关的参数。然后,它们将所有参数发送到 URLSearchParams 对象以提取“search”参数的值(也就是我们搜索的内容),并将其存储在名为“query”的变量中。稍后,此变量被发送到一个函数,该函数获取此查询的值并将其添加到我们之前讨论过的 img 请求中。该函数的工作原理如下。
function trackSearch(query) {
document.write('<img src="/resources/images/tracker.gif?searchTerms='+query+'">');
}
document.write 是 DOM 的一部分,它的作用是使用 JavaScript 代码将 HTML 代码写入页面内部。它里面有 ('<img src=”/resources/images/tracker.gif?searchTerms=' + query + '“>')。这里它告诉服务器 searchTerms 的值将是查询,而查询是用户搜索的单词。
这样,它就将我们在搜索框中搜索的值发送到服务器并将其存储在其中以供以后使用,而无需用户点击页面,也无需编写复杂的 JavaScript 代码。
第三步:
了解开发人员在编写导致 DOM XSS 漏洞的 JavaScript 代码时所犯的错误。
function trackSearch(query) {
document.write('<img src="/resources/images/tracker.gif?searchTerms='+query+'">');
}
在这段代码中,开发人员获取用户搜索的值并将其传递给 JavaScript,而不对其进行编码,也不对其进行加密。
为了保证此代码的安全性,应将其写成如下形式:
function trackSearch(query) {
var img = document.createElement('img');
img.src = '/resources/images/tracker.gif?searchTerms=' + encodeURIComponent(query);
document.body.appendChild(img);
}
所以在这里,encodeURIComponent(query) 用于对用户在搜索框中输入的值进行编码。然后,使用 DOM 将其添加到页面中,如下所示:document.body.appendChild(img)。
这样,我们就对输入进行了编码,并以安全的方式获得了所需的结果。
第四步:
如何在搜索框中注入警报功能?
首先,让我们再看一下 img 标签,因为我们要将代码注入其中。这是写在DOM内部的最终结果。
<img src="/resources/images/tracker.gif?searchTerms=gentil">
您可以通过在 Google 上搜索轻松找到如何在 img 标签中注入 JavaScript 代码,您会发现数千个结果。注射将如下所示:
gentil" onload="alert('XSS')
最后,它将看起来像这样。
<img src="/resources/images/tracker.gif?searchTerms=gentil" onload="alert('XSS')">
在这里,我关闭了双引号,然后添加了一个名为“onload”的属性,这意味着当页面加载时,执行我给你的值。在本例中,值为 alert('XSS')。
因此,当获取此有效负载“gentil” onload=“alert('XSS')” 并将其添加到搜索框中,然后按 Search 时,警报函数代码将像这样执行。
警报功能
现在让我们解决最常见的问题:
反射 XSS 和基于 DOM 的 XSS 有什么区别?
上图突出显示了反射 XSS 和基于 DOM 的 XSS 之间的根本区别。
反射的 XSS:
反射的 XSS 无法直接与浏览器交互;您和浏览器之间必须有一个中介来执行 JavaScript 代码。
例如:
您告诉具有反射 XSS 漏洞的受感染服务器在请求中将“123”返回给您(“请将 123 返回给我”),并按响应中的原样返回。它确实接受您的请求,并按照您的要求将其反映给您,而无需对其进行任何更改(再次将其反映给您)。这就是 Reflected XSS 的作用;它迫使您与服务器打交道以执行您在浏览器上请求的内容。浏览器信任服务器,而不是您,因此它充当您和浏览器之间的中介。
基于 DOM 的 XSS:
在 DOM XSS 中,您可以直接与浏览器通信,而无需中介(服务器)。您在易受攻击位置输入的代码将直接在浏览器上执行,浏览器无需寻求服务器的许可。您在易受攻击的位置提供的代码将立即执行。
Are you still confused about the difference between Reflected XSS and DOM XSS?
https://gentilsecurity.medium.com/are-you-still-confused-about-the-difference-between-reflected-xss-and-dom-xss-45715d0fe37b
原文始发于微信公众号(Ots安全):你还不清楚反射型XSS和DOM XSS之间的区别吗?
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论