簡単なハック:クロスサイトスクリプティングインクルージョンを介してデータを取得する方法。 XSSの脆弱性を最大限に活用するXssnoscript警告

XSSの脆弱性とは何ですか? 私は彼女を恐れるべきですか?

クロスサイトスクリプティング(略してXSS)は、多くのWebアプリケーションに影響を与える広範な脆弱性です。 これにより、攻撃者は、サイトにアクセスするユーザーのブラウザーがコードを実行するように、悪意のあるコードをWebサイトに挿入できます。

通常、このような脆弱性を悪用するには、ユーザーとの対話が必要です。ユーザーはソーシャルエンジニアリングを使用して感染したサイトに誘導されるか、ユーザーが自分でサイトにアクセスするのを待つだけです。 したがって、開発者はXSSの脆弱性を真剣に受け止めないことがよくあります。 しかし、それらに対処しないと、深刻なセキュリティ上の脅威をもたらす可能性があります。

WordPress管理パネルにいて、新しいコンテンツを追加していると想像してください。 これにXSSに対して脆弱なプラグインを使用すると、ブラウザに新しい管理者の作成、コンテンツの変更、およびその他の悪意のあるアクションの実行を強制する可能性があります。

クロスサイトスクリプティングにより、攻撃者は最近の最も重要なソフトウェアであるブラウザをほぼ完全に制御できます。

XSS:注入の脆弱性

すべてのWebサイトまたはアプリケーションには、複数のデータ入力場所(URL自体までのフォームフィールド)があります。 データ入力の最も簡単な例は、フォームにユーザー名とパスワードを入力する場合です。

図1.データ入力フォーム

私たちの名前は、将来私たちと連絡を取るためにサイトのデータベースに保存されます。 確かに、どのサイトにもログインすると、「ようこそ、イリヤ」というスタイルの個人的な挨拶が表示されました。 ユーザー名がデータベースに保存されるのはこの目的のためです。

インジェクションは、名前やパスワードの代わりに特別な文字のシーケンスが入力された場合の手順であり、攻撃者が必要とする特定の方法でサーバーまたはブラウザーに反応させます。

クロスサイトスクリプティングは、Webサイトに代わってブラウザーでアクションを実行するコードを挿入するインジェクションです。 これは、ユーザーの知らないうちに、ユーザーへの通知とバックグラウンドの両方で発生する可能性があります。

図2.クロスサイトスクリプトの視覚的な図

最も単純な例は、通知ウィンドウを表示する基本的なスクリプトです。 次のようになります。

表1.ポップアップウィンドウを呼び出すスクリプト

このスクリプトは、「これはXSSの脆弱性です!!!」という碑文のあるウィンドウを呼び出します。 ユーザーのブラウザは、このスクリプトを正当なサイトコードの一部として認識して実行します。

XSSの脆弱性の種類

すべてのXSSの脆弱性が同じというわけではなく、多くの種類があります。 タイプとそれらがどのように相互作用するかを次に示します。

図3.XSSの脆弱性の種類


サーバー側のコード(Java、PHP、.NETなど)によって引き起こされる脆弱性:

従来のXSS攻撃:

  1. 反映(非永続的)。 反映されたXSS攻撃は、ユーザーが特別に準備されたリンクをクリックするとトリガーされます。 これらの脆弱性は、Webクライアントによって提供されるデータ(ほとんどの場合、HTTP要求パラメーターまたはHTML形式)がサーバー側のスクリプトによって直接実行され、適切な処理なしでそのクライアントの結果ページを解析および表示する場合に発生します。
  2. 保存済み(永続的)。 格納されたXSSは、攻撃者が元のページにアクセスするたびにブラウザーで実行されるサーバーに悪意のあるコードを挿入できる場合に可能です。 この脆弱性の典型的な例は、HTMLコメントを許可するフォーラムです。

クライアント側のコード(JavaScript、Visual Basic、Flashなど)によって引き起こされる脆弱性:

DOMモデルとも呼ばれます。

  1. 反映(非永続的)。 サーバー側の場合と同じですが、この場合のみ、コードがブラウザーによって処理されるため、攻撃が可能になります。
  2. 保存済み(永続的)。 サーバー側に保存されたXSSと同様に、この場合のみ、悪意のあるコンポーネントがブラウザーストレージを使用してクライアント側に保存されます。

インフラストラクチャの脆弱性(ブラウザ、プラグイン、サーバーなど):

非常にまれですが、より危険です:

  1. クライアント側のインフラストラクチャ。 これは、悪意のあるコンポーネントが、XSSフィルターなどのブラウザー機能の操作を実行したときに発生します。
  2. サーバー側のインフラストラクチャ。 Webサーバーが要求を正しく処理せず、要求を変更できる場合に発生します。
  3. 通信網。 クライアントとサーバー間の通信に侵入できる場合に発生します。

ユーザーが誘発する脆弱性:

  1. Self-XSS。 多くの場合、ソーシャルエンジニアリングの結果として、ユーザーが誤ってブラウザで悪意のあるコードを実行したときに発生します。

XSSの危険性は何ですか?

XSSからサイトをどのように保護できますか? コードの脆弱性を確認するにはどうすればよいですか? このような攻撃を回避するために特別に設計されたSucuriFirewallのようなテクノロジーがあります。 ただし、開発者の場合は、XSSの脆弱性を特定して修正する方法について詳しく知りたいと思うでしょう。 これについては、XSSに関する記事の次のパートで説明します。

誰もが長い間、XSSを使用して、攻撃者が被害者にCookieを送信し、CSRFトークンを読み取り、フィッシング攻撃を実行し(偽のログインフォームを作成することにより)、ユーザーに代わって何らかのアクションを実行し、その他の同様の攻撃を試みることを長い間知っていました(おそらくこれはそうではありません) すべての可能性がありますが、これらはすべて、現時点で私が知っている最も人気のあるものです)。

この方法の目的は、攻撃されたサイトにアクセスするユーザーに代わってページを監視し、キーストロークを監視することです(移動してマウスをクリックすることもできますが、私にとってこれは不要であり、ほとんどの場合、非常に有用な情報ではありません) ..。
今、最大の利益のために-私はアルゴリズムが次のようになると信じています:

  • クッキーを読んで送信する。
  • 残りの情報(IPアドレス、インストールされているプラ\u200b\u200bグイン、ブラウザーのバージョンとタイプ、フラッシュのサポート、シルバーライトのサポートなど)を読んで送信します[オプション]
  • 内部ネットワークに関する情報を取得し、ルーターを突破します[オプション]
  • さまざまなトークンの読み取りと送信[オプション];
  • フィッシングを実装します[オプション]。
  • ユーザーが「手で」「何かをする」[オプション];
  • 彼がタブを閉じるかサイトを離れるまで、私たちは彼をスパイし、情報を抽出し続けます。

リスト内のすべてのオプション項目は、XSSを使用して達成する目的のために、状況と特定の優先順位に応じて実行する必要があります。これらは互いに干渉し(より正確には、次々に実行しようとすると)、XSSの悪用が失敗する可能性を高める可能性があります。
ただし、いずれの場合も、常に最初と最後のポイントに従う必要があります。実際、記事の主要部分は、このリストの最後のポイントについてです。

目標に到達します。

遠くから始めましょう。JavaScriptを使用すると、ページをリロードせずにアドレスバーのパスを変更できます。 たとえば、ユーザーがでページを読み込んだ場合

http://site.com/some/path/to/page/


次に、アドレスバーのコンテンツは次のようになります(ページをリロードしない場合)。

http://site.com/new-url/

http://site.com/new-url/


ちなみに、この機能は、Reflected XSSを含むリンクをクリックした後、ユーザー(またはより注意深いカテゴリのユーザー-管理者)からURLを非表示にする必要がある場合に非常に役立つことがあります。これにより、後でページを読み込んだ後、 アドレスバーに、何も見つかりませんでした。

http: //site.com/search.php?q\u003d123

http://site.com/search.php?q\u003d123

http: //site.com/search.php?q\u003d123


私たちは彼からこの機会を奪います。

しかし、この手法にはさらに興味深く強力な用途があります。 リンクをクリックした後のユーザーのサイト滞在をシミュレートします。実際、ユーザーは常に同じページに留まります。この時点で、サードパーティのスクリプトが機能し、情報を抽出して攻撃者に送信します。 この方法では、 XSSは、ユーザーがこのドメインのリンクをたどる限り機能します .

アイデアを定義します。

一般的な操作の原則は次のとおりです。ユーザーがXSSでページにアクセスすると、スクリプトはこのページと同じアドレスでiframeを作成し、それをフォアグラウンドに「貼り付け」ます。iframeはコードでのみ表示されるため、ユーザーはページが正常に読み込まれたという印象を持ちます。 ページ。

また、補助スクリプトはスパイボットのロジックを制御します。つまり、アドレスバーでアドレスを変更するために、フレーム内のアドレスがいつ変更されるかを監視しますが、フレームの新しく変更されたアドレスに別のドメインがある場合は、新しいvlkadkaで開くことができます。そうでない場合は、ページを再読み込みする必要があります。 やけどしないように。
したがって、XSSの実行を現時点で停止するには、ユーザーはページを手動で更新する必要があります(XSSが反映され、POSTメソッドを使用して送信された場合、更新は保存されません。ちなみに、一部のブラウザーは、ページの更新時にPOST要求を再度送信できます)。 タブを閉じるか、別のドメインに切り替えます(ただし、この場合でも、制御を失うことはありません)。

攻撃されたドメインのサブドメインに移動した場合、攻撃者の選択、つまりXSSは機能しますが、ユーザーがアドレス間に不一致を確認する可能性はわずかです。 たとえば、google.ruドメインが攻撃された場合、ユーザーは通常drive.google.ruサブドメインにあるGoogleのクラウドファイルサービスに切り替えた場合、アドレスバーを見たときにキャッチに気付く可能性が非常に高いと思います。 、 彼がこのサービスを頻繁に使用した場合..。 そうでなければ、あなたはそれを危険にさらす可能性があります。 ただし、クロスオリジンポリシーでは許可されていないため、サブドメインを持つフレームからデータを読み取ることができないことを考慮に入れる必要があります。 ただし、非表示モードでは、メインドメインに代わって静かに登ることができます(これについては、以下で詳しく説明します)。

この方法にのみ制限があります。つまり、サイトのWebサーバーの応答にヘッダーがある場合は機能しません。 Xフレーム-オプション意味のある 拒否..。 しかし、個人的には、そのようなサイトに数回会ったことがありますが、今では半分になっています SAMEORIGIN公開されていない、ましてや完全な制限 拒否.

アイデアを分析します。

今では、BeEFのような素晴らしいものを覚えている人も多いでしょう。BeEFにも興味深いものがたくさんあります。 ちなみに、フレーム内でユーザーを強制的にリダイレクトするオプションもありますが、アドレスバーのアドレスは変更されないため、すぐにデスクを焼く可能性があり、このオプションは他の目的には少し役立ちます。
一般に、BeEF'eには必要なものがほぼすべて揃っており、追加機能もたくさんありますが、個人的には次のような追加機能が必要でした。

  • 攻撃されたユーザーが利用できるページのコードをリアルタイムで監視する機能。
  • 彼がそのサイトで入力したすべてのもの(ログインとパスワードからホットキーとメッセージまで)、つまりJSのキーロガーを監視する機能。
  • 受信したページのコードを表示した後、リアルタイムでボットにJSコマンドを与える機能。
  • コマンドをローカルでボットに任せて、直接参加せずにコマンドを「ピックアップ」して実行する機能。
  • ボットが火傷する可能性が低い、またはボットが詮索好きな目から「隠す」能力。

上記のように、私はコマンド実行キューのBeEFのクールなアイデアから借りることにしました。 たとえば、特権ユーザーがXSSを保存してコントロールパネルに登ったときにボットがスローしたページを分析し、コマンドをボットに任せます-次にユーザーが入力するときのように、JSコード、このボタンを押す、この値をここに書き込むなど。 このユーザーが次にページにアクセスすると、ボットはコマンドを読み取って実行します。私たちは彼の指揮を執る必要はまったくありません。非常に便利です。

基本的に、このようなボットは、もちろん、コンテンツ管理の追加の「レバー」を持つ一部のサイトのステータスユーザー、他のユーザーなどのために設計されています。 機能の要求から、サーバー側なしでは実行できないことは明らかです。

アイデアを実装しましょう。

原則として、記事のこの部分はスキップできます。これは、誰かがボットを作り直したり、自分で完成させたい場合に備えて、目的のボットを実装するプロセスとその詳細の一部を説明しているだけだからです。 コードの最初のボットには、いくつかの設定を行うことができる変数がありますが。
まず、ロードの瞬間からのボットアクションのアルゴリズム:

1)ヘッダーの確認 Xフレーム-オプション:拒否(ある場合は、釣り棒を巻き上げます);
2)フレームを埋め込み、ボットのすべてのコンポーネントを設定します。
3)スクリプトとHTMLコード内のすべてのトレースを削除します。
4)サーバー側との接続を確立し、データの送信を開始し、応答に反応します(サーバーからコマンドを受信します)。

最初のポイントは完全ではありませんでした。つまり、ボットは最初のページとルートヘッダーのみをチェックします。 実際、これらのヘッダーは通常、すべてのページに対してWebサーバーによって一度に埋め込まれ、すべてが別のページに対して「手動で」行われることは非常にまれです。 そして、このタイトル自体は非常にまれです。 さて、2番目と3番目について言うことは特別なことは何もありません、すべてが低くなります。

コードにボットスクリプトコードを追加する前に、アドレスバーのXSS記号を(JSコードから)すぐに削除する必要があるという比較的重要な点があります。これにより、検出の可能性が減り、最も重要なこととして、アドレスがフレームに追加されたときに発生する再帰が防止されます。 同じXSSコードを使用して、それ自体で別のフレームを作成します。

ただし、念のため、ボットコードは、そのようなフレームの再帰を検出し、作成済みのフレームにフレームを追加する最初の試みでそれを防ぐ可能性を実装しますが、それだけに依存するのではなく、ボットコードをロードする前にコードを追加で削除することをお勧めします。 まだ問題はありませんが。

フレームアップデートチェック機能。 イベントハンドラーをオンにすることで、この問題を経済的に解決するいくつかの方法を試しました contentWindowまたは contentDocument、しかし何も成功しなかったので、フレームのアドレスをチェックして以前に保存したものと比較し、これに基づいてフレームが更新されているかどうか(アドレスが変更されているかどうか)を判断し、それ自体を再帰的に呼び出す関数を作成する必要がありました。

1秒あたりのこのようなチェックの頻度は、変数によって制御されます。 ディレイ、ボットコードファイルの先頭で指定されます。 しかし後で、すでにそれを書いたので、私はより効率的な解決策を見つけました-単純な解決策を使用してハングアップします オンロードフレームごとに、その機能を残しましたが、後でもっと需要があることが判明した場合に備えて、コメントアウトしました。

ページのHTMLコードを送信します。

ここでは、スキームは非常に単純です。フレームをリロードするたびに(最初のロードを含む)、ボットはページのHTMLコード全体と現在のアドレスをサーバーに送信するため、後でコードが必要なページに属しているかどうかを区別できます。

ページを保存するロジックはサーバーに実装されています。各ドメインのサーバーは、このドメインの名前でフォルダーを作成し、そこにすべてのデータを保存します。 ページコードは保存され、常に最新バージョンに更新されますが、必要に応じてバージョン履歴を制御できるように、毎日新しいページのコピーが作成されます。 つまり、 /news.php9月1日にステータスが更新され、9月2日にそのコピーが作成されます。これは、その日にのみ関連するため、毎日新しくなります(ユーザーが毎日このページにアクセスした場合)。 ページ名は、日付と、サイトルートを基準にした(つまり、ドメインを含まない)このページへのパスで構成されます。

JavaScriptのキーロガー。

このアイデアはすでに一部の愛好家によって実装されていますが、私にとっては、それらのほとんどが非常に単純である、つまり、押されたキーのコードを検出し、 String.fromCharCodeシンボルに変換されます。 ただし、この方法にはいくつかの欠点があります。Shift、Control、Spaceなどの制御キーは、どの形式にも変換されず(多くの場合、空の文字のみ)、プログラムで実装する必要があるため、英数字キーとShiftキーの相互作用が誤ってログに記録されます。 また、押されたすべてのキーは大文字で表示され、プログラムで修正することもできます。

その結果、数字、文字、基本文字のすべてのキーを正しく検出し、両方のレイアウトで作業し、シフトに応答し、すべての主要な特殊キーをログに記録するキーロガーが作成されました。 確かに、一部のマシンでは、一部の企業が変更する基本標準に従って実装されているため、一部の文字(シフトと番号を押すと印刷されるデジタル行の上部)が異なる場合があります。
押された文字の各部分は、テキスト要素がフォーカスを失うまでクライアントによって保持されます。 次に、この部分はサーバーに送信され、テキストファイルに保存されます。テキストファイルは毎日新しいコピーで作成されるため、大きなサイズに拡大することはなく、そのときにユーザーが入力していた内容をすばやく見つけることができます。
キー自体に加えて、テキストが入力された要素に関する情報が各部分とともにサーバーに送信されます(つまり、 ,