Yandex.Mail。 ハコストロフェ予防

昨年11月、Yandex社は、サービスでの脆弱性検索のトピックに関するコンテストを開催しました。 幸運なことに、そこにいくつかの穴を見つけて、2位になりました。 過去6か月間、詳細を公開していなかったため( デフコン-ロシア会議を除き、訪問者の狭いサークルのために口頭でした)、このギャップを埋めることにしました。 そのため、競争の一部として発見され、Yandexによってすぐに閉鎖された穴の1つについての物語があります。 競争は完全に正当化され、ひどい結果を防ぐことができたので、アイデアは明らかに成功していると思います。 実際には、ストーリーはスクリプトの1つでの承認チェックの平凡な欠如に関するものであり、1つのノードのみで10億文字を超える部分的な侵害につながる可能性があります...

開始する


競争が発表されたとき、デジタルセキュリティの監査部門の責任者として、私はそれに参加したくありませんでした(一般的には競争が怖く、上司には他に重要なことがあります:注文をするか、レポートを要求します... 8))、しかし、いつものように、好奇心と利益への渇望が彼らの条件を決定しました。 面白くて楽しいものを探すことにしたので、XSSやCSRFのような脆弱性を探す時間を無駄にしないことに決めました。 まず、スクリプトを調べると自動的に検出されます(実際には、いくつかのXSS'okがすぐに検出されました)。 第二に、それは面白くありません( kyprizelが同じ競争で示したように、それは危険ですが)。 さらに、コンテストエリアが広大だったので、私は自分にとって最も興味深いサービス、つまりメールのみに限定することにしました。 同時に、彼は仕事に気を取られないように、1営業日以上は費やさないことにしました。 これにより、何も見つからないという心配をする必要がなくなりました。時間がないので(自己正当化、ハァッ!)、本当に一酸化炭素を探します。 いずれにせよ、初心者にとっては、Webインターフェースの構造とロジックを調べるだけで済みました。 これは簡単でした-BurpSuiteとGoogle Chromeに組み込まれた開発者インターフェイスの助けを借りて。


Anton Karpov別名toxatokza )は、見つかったバグがどのように評価されるかを伝えます。

フロントエンド



メールコンテンツを配信するためのメインスクリプトは、特定のhandlers.jsxです。 開発者自身がメールアーキテクチャに関する情報を喜んで共有していることは注目に値するため、この場合はサーバー側のJavaScriptを扱っていることがわかります 。 ただし、最初の脆弱性は非常に古典的であることが判明したため、実装の詳細はそれほど重要ではないため、これらの微妙な点はすべて必要ではありませんでした。 しかし、最初に、一般的な詳細:



いくつかのモジュールとその意味:


より明確にするために、アレクセイ・アンドロソフによる同じプレゼンテーションのスクリーンショットを提供します。



つまり、すべてのコンテンツがAJAXリクエストを使用して共通のインターフェースにアセンブルされ、XSLテンプレートのおかげで「人間」の形になっていることは明らかです。
さて、同じ文言からのリクエストの例:

/handlers.jsx?_handlers.0=message&ids=1234567890&_handlers.1=message&ids=1234567891

XML応答:

<handlers> <handler name=”message” key=”_h=message&ids=1234567890”> <!--  --> </handler> <handler name="message" key="_h=message&ids=1234567891"> <!--  --> </handler> </handlers> 


すべてが単純なようです。 _handlersパラメーターは必要なデータ(ハンドラーモジュール)を決定し、idsは識別子です。 つまり、このリクエスト例では、識別子1234567890および1234567891の文字が読み込まれます。当然、最初に試したのはIDを置き換えて、たとえば123431337に置き換えることでした。私のものではありません。

成功しませんでした ちなみに、同じアクションは私の同僚と友人chipikによって取られました 。 昨年、彼と私はすでにGoogleを破りました(そして、 それがどのようであったかについても書きました )。 しかし、彼も失敗しました。 ただし、これは面白いことです。「コードカバレッジ」などがあります。 つまり、検証アクションを実行した後、コードの一部をチェックしました。 モジュール名を置き換えようとする場合、ID識別子によるアクセス許可のチェックは同じコードが担当すると想定するのは論理的です。 しかし、これはそうではないことを少し幸運が理解するのに役立ちました。

バガ



しばらくして、再びidを交換することにしましたが、別のモジュール-「 nearest-messages 」、 loおよびbehold ...最初はこれがどのように起こったのか理解できませんでしたが、後でこれがチェックしない唯一のモジュールであると確信しました。 IDメッセージが現在のユーザーに属しているかどうか。 これは、このモジュールを使用して、他のサーバーユーザーの「隣接する文字」をロードできることを意味します。 正当なリクエストを分析しましょう:

http:// mail.yandex.ru/neo2/handlers/handlers.jsx?_handlers=message-nearest&ids=2020000002590081157

2020000002590081157は私の手紙のIDで、かなり具体的で明確です。 Yandexサーバーは次の要求を返します。

(...-音量を下げるためにカット)

 <handlers> <handler name="message-nearest" gid="0" key="_handler=message-nearest&ids=2020000002590081157"> <message-nearest> <list> <message id="2020000002590182740"> <thread id="2020000001499988536"/> <folder id="2020000650059912118"/> <date> <timestamp>1320143331000</timestamp> <iso>2011-11-01T14:28:51</iso> <short>01.11.11</short> <full>1 . 2011  14:28</full> </date> <size>2 </size> <last_status/> <subject fwd="Fwd:">TEST</subject> <firstline>,     2</firstline> <to> <name>ne_eik01110d111@yandex.ru</name> . . . </to> <from> <name>SSS AAA</name> . . . </from></message> <message id="2020000002590081157"> <thread id="2020000001499929723"/> <folder id="2020000650059912118"/> . . . <size>1,8 </size> <last_status/> <subject re="Re[2]:">TEST</subject> <firstline> ,  … </firstline></message> <message id="2020000002590076913"> <thread id="2020000001499929723"/> <folder id="2020000650059912118"/> . . . <full>1 . 2011  14:01</full> . . . <subject>TEST</subject> <firstline> 1</firstline> <from> <name>Alexey Sintsov</name> <email ref="3cab8cda1a132a2d17803cc47cd55d91">ddookie1@inbox.ru</email> </from> <reply-to> <name>ddookie1@inbox.ru</name> <email ref="3cab8cda1a132a2d17803cc47cd55d91">ddookie1@inbox.ru</email> </reply-to> . . . </message> </list> <timer_db>266</timer_db> <timer_logic>175197</timer_logic> </message-nearest> </handler> <login>ne_eik01110d111</login> <actual-version>5.11.55</actual-version> <timestamp>1335882564270</timestamp> </handlers> 


サーバーは、3つのオブジェクトを含むXMLを返します。 各オブジェクトは、レターに関する情報です。



さらに、リクエストでIDが示されているメッセージは2番目のオブジェクトに送られます。 最初と3番目のオブジェクトは、要求されたオブジェクトと同じフォルダー内の隣接するメッセージです。 たとえば、IDを1つずつ変更すると、他の3人のメッセージが届きます。 むしろ、受領日、ヘッダー、住所、ID識別子、および手紙の最初の行。 しかし実際には、最初の行は最初の行だけではありません! 経験から、そこに複数の行を入力できることが示されており、ここでの主なことは、改行の量と数です。 私の実験では、結果とそれぞれ5行がありました! つまり、ボリュームは実際の脅威について話すのに十分な大きさです。

メッセージ本文で送信:

– 1

, – 3
----- – 4
– 5
– 6

– 8
! – 9



handlers.jsxを使用して傍受:

 <firstline> –  1 ,   –  3 ----- –  4  –  5  –  6  </firstline> 


ご覧のとおり、この量のデータは、機密性を侵害したり、登録データを電子メールに送信するサービス(Facebookなど)からアカウントを盗んだりするのに十分です。

少し



一般に、すべてが明確です-バグは最も簡単ですが、いくつかの質問があります:



これらの質問は、より標的を絞った標的型攻撃に関心のある適切なクラッカーによって尋ねられます。 結局、私たちはIDを扱っており、敵の手紙のIDを知ることは常に私たちに与えられるわけではありません(ほとんど決して)。 したがって、攻撃はテクノロジーの観点からもう少し危険で興味深いものになります(ほとんどの人が置き換えることができますが、それを計算します...)

また、経験的に明らかにされた詳細もいくつかあります。 idは、レターまたはフォルダーの単なる識別子ではなく、実際にはオブジェクトであることがわかります。

最初の4桁は、ボックスがホストされているノードの番号です(どのように正しく呼び出されるのかわかりません。したがって、それを呼び出します)。 注意を払うと、すべてのレターとフォルダーに一定の番号が付いていることに気付くでしょう。 したがって、特定された脆弱性を使用すると、メールボックスが配置されている同じノードからのみ文字を読むことができます。 数十億の手紙に注意してください! 多くのノードがあり、同時に登録された2人のユーザーが異なるノードにアクセスできます。

中央では、タイプ識別子はフォルダまたはメッセージ(メッセージ00には65のようなフォルダがあります)であり、最後の桁はノード上のメッセージ識別子です。 これが最後の変更であり、可能です。 つまり、私の例では、現在のメッセージの番号は259008115 7でした。 これで、1つのノード上のメッセージの量を大まかに表します。

2番目の面白い事実:メッセージ識別子は、絶対的な増分値です。 つまり、現在のノードで処理(受信)される次の文字は259008115 8になります。 この手紙が私に送られなくても。 これで、両方の問題を解決できます。 つまり、標的型攻撃を実行し、愚かにも10億文字をダンプしない8)

攻撃



被害者と同じノードにメールボックスを作成する必要があります。 被害者のボックスがずっと前に登録されている場合、タスクを解決することは困難です。 異なるノードからボックスを取得または盗み出し、可能な場合はそれらのノードでボックスを登録できます。 しかし、被害者のボックスが最近作成された場合、攻撃は100%成功する可能性があります。 したがって、たとえば、 target-mail1 @ yandex.ruメールボックスを攻撃します。 最近作成しました。 したがって、攻撃の成功は高いです。 そのため、 check-mail1check-mail2check-mail3などの一連のメールボックスを作成します。 主なことは、作成されたすべてのボックスが異なるノードにあることです。 その後、メールをtarget-mail1に送信し、作成したすべてのメールボックスのコピーを作成します。



ユーモアとは? 「check-mail」アカウントにidsの文字が表示されたら、この値を5単位ずつ増減します。 そして、check-mailNがtarget-mail1と一致したノードで、レターが表示されます。 例を参照してください。



そのため、ターゲットボックスにアクセスできます。 そして、標的の手紙はどうですか? しかし、思い出すと、この脆弱性を悪用するモジュールは、同じメールボックスの同じフォルダー内の隣接する文字を示しています(スクリプトは、idsで指定されたものと、同じメールボックスからの2つの隣接するメッセージを表示することに注意してください)。 選択した文字が最後の場合、現在と前のIDを含む2文字のみが表示されます。 これは、次のクエリでこのIDを選択できることを意味します。XML応答の2番目のオブジェクトとして表示され、3番目はさらに古い文字になります。 次に、idを取得し、フォルダに保存されているすべての文字を読み取り、探しているものを見つけるまで「スライド」します。

結論



侵入テストとファジングのコードカバレッジは、重要なパラメーターである場合があります。 ここでは、誰もがメッセージ本文モジュールのIDを変更しようとし、リクエストがロールしないため、他のあまり明らかでないモジュールで同様のテストを行わなかったという素晴らしい例を見てきました。

脆弱性は単純ですが、攻撃自体は非常に複雑であり、ID生成とノードアーキテクチャの分析が必要です。 脆弱性を悪用することは、単に「穴」を探すことよりも興味深いものです。 特定のメールボックスから特定の手紙をハイジャックすることは興味深い挑戦でした。 これは古いボックスでは困難ですが、それでも可能です。新しく作成されたボックスでは、成功率は100%です。 古い場合は、同じノードにメールボックスを作成する機能に依存します。 新しいregsの統計:作成された3番目または4番目のボックスはすべて同じノードになります。 ノードが起動されてからノードに登録される可能性のある期間は約6か月です(つまり、「新規」/「新しく作成された」ボックス、これは半年前に作成されたボックスです)。 理論的には、6か月後、このノードに登録することは不可能です。

謝辞:

アントン・カルポフ( tokza )とヤンデックス-興味深い挑戦と競争、そして2位。 確かに、脆弱性はどこにでもあり、そのようなコンテストはそれらの多くを閉じるのに役立ちました!
Dmitry Chastukhin( chipik )-すでに「テスト済み」のバグを見つけたとき、彼はあまり怒っていなかったので...
d0znppkyprizelptsecurity-コンテストに参加して、ひどい穴を見つけるために、私は1か月中リラックスできませんでした(コンテストは嫌いです)。

最後にプルーフビデオ...



みなさんさようなら!

PS:私はYandexの従業員ではないため、アーキテクチャ、アルゴリズム、および名前の詳細は信頼できない場合があります。 Yandex.Mailデバイスに関するすべての結論は、著者の内なる感情と直感的なビジョンに基づいています。

Source: https://habr.com/ru/post/J143921/


All Articles