参考:https://www.intigriti.com/researchers/blog/hacking-tools/hunting-for-reflected-xss-vulnerabilities
如果单独说一个东西非常差,你很难评估它到底差在哪里。现在有一个参考物进行对比,你就可以更好的感受到它们之间的差距所在。
你叔就奇怪了,为什么你的教程总是只能欺骗到小白,但是人家的教程为什么总是从基础到高级都覆盖,是你们的“十年工作经验”造成的吗?用四哥的话来说,你真的尽力了吗?
现在,你将不再会被面试官diao:你甚至还不如好好看看burp官网的教程 https://portswigger.net/web-security
Hunting for reflected XSS vulnerabilities: A complete guide
毫无疑问,跨站脚本漏洞是长期困扰应用程序的漏洞类型之一。这种无缝注入漏洞通常可以进一步升级,允许攻击者以受害者的名义执行恶意操作,甚至更糟的是,以易受攻击的服务器端组件的名义执行恶意操作,从读取和更改帐户信息(例如密码或电子邮件),到访问仅限内部使用的资源,甚至读取本地文件。
在本文中,我们将介绍一种经过验证的识别反射型 XSS 漏洞的方法,并深入探讨一些高级利用方法。
What is Cross-site scripting (XSS)
跨站脚本 (XSS) 是一种注入漏洞,攻击者可以利用该漏洞将恶意脚本注入其他用户访问的网页。该漏洞利用输入验证不充分以及对用户输入的任何编码缺失的漏洞,使攻击者能够插入 HTML 或 JavaScript 代码,并在受害者访问受感染页面时在受害者的浏览器中运行。
根据易受攻击的组件,XSS 可能发生在客户端和服务器端。客户端 XSS 仅发生在受害者的 Web 浏览器中,它允许攻击者接管受害者的会话。
服务器端 XSS(也称为盲 XSS)是指易受攻击的组件使用未经过滤的输入,并在服务器端的 DOM 中对其进行评估,例如通过无头 Web 浏览器。这使得攻击者能够使用任意 JavaScript 代码代表服务器发起外部请求,在严重的情况下,甚至可以读取本地文件(取决于无头 Web 浏览器的部署配置)。
现在,让我们来看看不同类型的 XSS 漏洞。
- Reflected XSS
反射型 XSS(有时也称为反射型 XSS)是指恶意用户输入通过请求属性(例如 URL 路径、片段、查询/正文参数或 HTTP 标头)注入,并在未经适当过滤的情况下立即反射回用户。
服务器处理用户输入并将其包含在 HTTP 响应中,而无需任何编码,导致受害者的浏览器在点击特制链接时执行攻击者的脚本。
- Stored XSS
存储型 XSS(有时也称为持久性 XSS)是指攻击者的恶意脚本被保存在目标数据库、文件系统或任何其他类型的存储服务(例如 AWS S3)中。当其他用户稍后检索这些存储的数据(例如,查看评论区、公开个人资料或论坛帖子)时,恶意脚本会在其浏览器中执行。
存储型 XSS 尤其危险,因为它可以影响多个受害者,而无需他们点击特定链接,这与反射型 XSS 不同。
- DOM-based XSS
基于 DOM 的 XSS 是指不安全的 JavaScript 代码处理用户可控制的数据(来自 DOM 源)并将其传递到 DOM 接收器。这使得攻击者能够编写 JavaScript 有效载荷,并由易受攻击的应用程序进行评估。
基于 DOM 的 XSS 更难发现,因为恶意用户输入不会立即反映到 HTTP 响应中,而是传递到 DOM 接收器。我们将在后续文章中讨论如何识别和利用基于 DOM 的 XSS 漏洞。
本文将仅讨论反射型 XSS 和存储型 XSS,因为这两种类型具有相同的特征。
- 什么是 Self-XSS?
Self-XSS 是指攻击者诱骗受害者在其浏览器中执行恶意 JavaScript 代码,通常是诱骗受害者将代码粘贴到浏览器的开发者控制台或只有受害者才能访问的合法网站的文本框中(例如,您个人资料中的地址栏)。
虽然从技术上讲,这会导致脚本执行,但大多数漏洞赏金计划和安全研究人员并不认为 Self-XSS 构成安全风险,因为它需要受害者主动对自己发起攻击,这违反了漏洞应该无需进行广泛的社会工程学攻击即可被利用的基本安全原则。
请注意,在某些情况下,Self-XSS 漏洞可以串联并进一步升级,但我们将在接下来的文章中更详细地讨论这个主题。
Methodology
如果您是初学者,这部分至关重要。它可以帮您节省大量时间,确定您发现的是 XSS 漏洞,还是正在处理简单的内容注入。让我们通过这三步方法,来识别反射型或存储型 XSS 漏洞。
Step 1: Reflection
第一步是确定您的输入在应用程序响应中反映的位置。在各种输入字段、URL 参数、标头或任何其他用户可控制的数据点中插入一个唯一字符串(例如 intigriti1337test)。
接下来,在 HTTP 响应中搜索此字符串。这有助于您找出所有反射点,并了解您的输入最终到达的位置,这对于确定是否存在漏洞利用以及您正在处理的注入类型至关重要。

查找隐藏的输入参数
枚举(隐藏)参数可以帮助您发现所有类型的注入漏洞,包括 XSS!在我们的详细指南中,我们概述了 5 种发现隐藏参数的方法。立即阅读本文。
https://www.intigriti.com/researchers/blog/hacking-tools/finding-hidden-input-parameters
Step 2: Injection
找到反射点后,通过注入一个简单的 HTML 标签(例如 <s>intigriti1337test)来测试是否可以脱离当前上下文,并观察应用程序如何处理它。
对于 JavaScript 上下文中的反射(位于 <script> 标签内的任何位置),注入字符串会略有不同。我们稍后会更深入地讨论这种情况。
- 无注入的输入反射
您的输入可能经过了 HTML 编码。在这种情况下,由于您的任意输入已被过滤,因此通常无法进行 XSS 攻击。但是,请注意,应用程序可能会根据您的用户代理(移动端和桌面端)或您注入特殊字符(例如空字节、CR/LF 字符等)而表现出不同的行为。
到了这一步,你发现存在过滤器或waf,但是测试这个地方的过滤器或waf只是基础,现在你可以好好对比一下你司的教程了。

关于waf或过滤器,它们在检查什么以及如何测试请参考:https://www.bugbountyhunter.com/vulnerability/?type=xss 此文简单的一把梭即:语义的不同形式(比如非正确语义,<h1;网站自带的可解析编码(比如URL编码);最后记住一句话,WAF 通常只是在寻找某些字符串,它甚至可能在黑名单上运行(包括全球所有的waf产品)。
一个好问题是,如果 demo.com/home/?id=1 的地方存在waf或者过滤器,那么 demo.com/home/?name=1 的地方也存在waf或者过滤器吗?我需要单独进行测试吗?
换一个问题就是waf或过滤器的代码作用域(与HTTP头测试同理,与编码测试同理),有的是基于CDN的NIDS的全局的流量拦截,而有的是基于代码作用域的局部流量拦截,所以答案是需要单独测试不同的参数或功能点(与HTTP头测试同理,与编码测试同理)。
- Input reflected with injection
当你的输入被反射并注入时,意味着没有特殊字符被编码,这很有可能存在 XSS 漏洞。我们现在要做的就是注入一个特殊的 HTML 标签或事件处理程序,将简单的 HTML 注入转化为 XSS 漏洞。

Step 3: Payload (proof of concept)
现在是时候编写一个可以在受害者浏览器中执行 JavaScript 的有效概念验证了。为此,您的有效载荷取决于两个因素:1) 您的输入被反映的上下文,以及 2) 任何阻止您注入恶意 XSS 有效载荷的现有过滤器。
让我们来看看您的未经过滤的输入可能出现的几种上下文,并了解一些可以帮助我们突破这些上下文并实现代码执行的有效载荷。
- Generic (HTML context)
当你的输入直接反映在 HTML 主体中,而无需任何特定的标签或属性时,你将拥有最大的利用灵活性。从简单的 Payload 开始,例如:
<script>alert(1)</script>
Or:
<img src=x onerror=alert(1)>
上述两种有效载荷都无需跳出任何标签即可工作。对于初学者来说,这是最简单的方案,因为您几乎可以使用任何支持 JavaScript 执行的 HTML 标签,包括 <svg>、<iframe>、<object> 或自闭合标签上的事件处理程序属性。

- HTML attribute (inline HTML)
当您的反射出现在 HTML 属性中(如 <input value="REFLECTION"> 或 <form action="/path/to/submit?param1=REFLECTION">)时,您需要先脱离属性上下文,然后才能注入有效负载。
您可以使用引号关闭属性,使用 > 关闭整个标签,然后注入新的恶意标签(如“"><script>alert(1)</script>”),或者通过添加事件处理程序(如“" onload=alert(1) x="”)保留在同一个标签内。
关键是要了解使用哪种引号类型(单引号或双引号)来包装属性,以及应用程序是否过滤了任何其他可能阻止我们转义上下文的字符。

- JavaScript block
当您的输入反映在 <script> 标签内时,通常作为 JavaScript 变量赋值的一部分,如 var data = "REFLECTION"; 或 var config = {"key": "REFLECTION"};,您需要跳出 JavaScript 语法来执行您的代码。
对于常规字符串,使用"; alert(document.domain); // 退出以关闭字符串,执行代码,并注释掉其余部分。
对于模板文字(反引号),您可以使用 ${alert(document.domain)} 直接在模板内执行代码,而不会破坏语法。
这里棘手的部分是确保 JavaScript 在注入后仍然保持语法有效,因此请注意可能导致错误并阻止执行的未闭合括号、引号或圆括号。

XSS exploitation
我们已经介绍了什么是 XSS 漏洞,以及如何系统地探测和识别可能的注入点。现在是时候测试一下我们新学到的技能了。让我们看几个真实案例,以便更好地帮助我们构建 Payload。
- XSS with no filtering
在极少数情况下,您会遇到没有进行任何过滤或验证来预防 XSS 漏洞的情况。这些情况通常是由于开发人员疏忽,忘记过滤用户输入而导致的。
在这种情况下,我们可以使用任何我们喜欢的有效载荷来证明 XSS 的存在:

- XSS in inline-HTML (attributes)
另一个常见的情况是,您的输入会反映在 HTML 属性的值中。在这种情况下,您可以:
突破 HTML 属性的限制,并注入事件处理程序来执行任意 JS 代码
或者,突破 HTML 属性的限制,关闭标签,然后打开一个新标签来执行任意 JS 代码
根据具体情况,注入新的事件处理程序通常更容易。而在其他情况下,这可能是唯一可行的解决方案,因为用于打开和关闭 HTML 标签的字符会被明确过滤。

- XSS in JavaScript context
随着应用程序变得越来越复杂,开发人员往往会引入更多安全漏洞,包括 XSS 漏洞。虽然这种情况很少发生,但有时开发人员会将未经过滤的用户输入直接反射到 JavaScript 上下文中。我们通常不会意识到后果,而是会利用这个机会逃离上下文,并在不使用任何 HTML 的情况下注入任意 JavaScript 代码。
根据反射点的不同,您通常需要:
脱离当前上下文(通常是变量值或函数参数)
注入有效载荷
关闭有效载荷以使语法匹配

- XSS inside the textarea field
对于某些 HTML 标签(例如 <textarea> HTML 标签),浏览器会拒绝渲染其值以保留其内容。如果您是初学者,一开始可能会认为这种情况不可利用。但是,如果您的输入反映在这些标签中,我们将被迫在注入有效载荷之前关闭该标签。


- XSS with limited HTML & attributes allowed
您可能会遇到一种常见的情况,即当特定模式匹配时,输入会被限制、过滤或完全阻止。这是迄今为止开发人员最常用的过滤方法之一。
幸运的是,在大多数情况下,我们可以简单地模糊测试任何允许的 HTML 标签、事件处理程序和字符,以帮助我们规避过滤器或 Web 应用程序防火墙 (WAF) 的阻止。
具有有限黑名单的 HTML 标签和属性的基本跨站点脚本 (XSS):

- XSS 模糊测试
您是否尝试过所有防御措施,试图让目标执行您的 XSS 有效载荷,但却无法绕过过滤器?不用担心,这恰恰是进行 XSS 模糊测试的强烈信号!
PortSwigger 研究学院提供了一份包含所有可用 HTML 标签和属性的速查表。我们可以使用此列表,通过探测注入点,几乎枚举所有可接受的标签和事件处理程序。之后,我们只需通过注入允许的 HTML 标签和属性来匹配拼图碎片,以帮助我们构建有效载荷!
https://portswigger.net/web-security/cross-site-scripting/cheat-sheet
Conclusion
本文的关键在于识别注入点的上下文,并了解目标对恶意字符的行为方式。每当测试部署了严格过滤规则的目标时,建议花时间手动测试反射点。有些工具很容易识别不到这些,因此并非总是可靠。
所以,您刚刚学到了一些关于寻找反射型 XSS 漏洞的新知识……现在,是时候测试您的技能了!您可以先在漏洞实验室和 CTF 上练习,或者……浏览我们在 Intigriti 上提供的 70 多个公共漏洞赏金计划,说不定下次提交漏洞就能获得赏金呢!