本サイトは、快適にご利用いただくためにクッキー(Cookie)を使用しております。
Cookieの使用に同意いただける場合は「同意する」ボタンを押してください。
なお本サイトのCookie使用については、「個人情報保護方針」をご覧ください。
WannaCry 2.0の騒動が発生してから一ヶ月半程が経過しました。騒動の発生時からWannaCry 2.0が利用する「EternalBlue」および「DoublePulsar」について繰り返し報道されてきたこともあり、これら2つのキーワードはかなり認知され耳に残る単語になったのではないかと思います。
他方で、この2つがどのように機能しWannaCry 2.0のワーム活動が構成されているか、すなわちEternalBlueとDoublePulsarの役割や境界線について、詳細な情報はありつつも断片的なものが多く、整理し終えないまま話題として収束しつつあるように感じています。
本記事では検証と解析を通じて事実を整理するとともに、ワーム活動におけるフローに焦点を当てつつ、WannaCryによって設置されるDoublePulsarが持つリスクについて言及します。
■NSAから流出した攻撃ツールのセット「Fuzzbunch」による攻撃の流れの理解
WannaCry 2.0が利用するEternalBlueおよびDoublePulsarは、元々NSAが作成したとされる攻撃のツールセット「Fuzzbunch」に含まれていたツールであり、端的に述べると以下となります。
- EternalBlue:MS17-010の脆弱性を攻撃するために使用するエクスプロイトコードおよび攻撃ツールの総称
- DoublePulsar:SMBまたはRDPプロトコルを用いて通信を行うバックドア
WannaCry 2.0では、これら双方が組み合わされることによりワーム活動が成功するため、どこまでがEternalBlueの動作で、どこからがDoublePulsarの動作であるか理解し難い部分がありました。
そこで、WannaCry 2.0に流用される元となったNSAの攻撃ツールであるFuzzbunchに備わっているオリジナルの機能、攻撃方法を確認することで、EternalBlueとDoublePulsar、それぞれの役割を確認してみます。
Fuzzbunchは起動するとコマンドプロンプト画面に入力を促す形式となっており、セキュリティ調査・攻撃ツールとして一般によく知られている「Metasploit」に非常に類似したインターフェイスおよび使用感を持っています。そのため、Fuzzbunchを攻撃ツールとして使用した場合、攻撃者が複雑な処理をしなくとも、また、エクスプロイトコードの詳細について理解していなくとも、容易に攻撃を実施できるようになっています。
図1 Fuzzbunchのインターフェイス(ヘルプを表示した画面)
以下ではまずFuzzbunchのインターフェイスを操作しながら、EternalBlueを実際に動作させて攻撃の流れを確認していきます。
Fuzzbunch を起動させuseコマンドを実行すると、Fuzzbunch で利用できるエクスプロイトの一覧が表示されます。以下の図2を見ると、多数のエクスプロイトコードがFuzzbunchに組み込まれていることがわかります。EternalBlueはそのうちの一つであり、表示された一覧からEternalBlueを選択します。
EternalBlueを選択すると、次は実際の攻撃に必要な攻撃先のIPアドレス、ポート番号、攻撃プロトコル、攻撃試行回数などを設定する項目が表示され、それらをすべて設定した後で攻撃を実行できるようになっています。
図2「Fuzzbunch」にて攻撃方法に「EternalBlue」を選択する画面
上記を見てわかるように、EternalBlueの機能自体に以下を確認するコードも含まれています。
1)ツールで設定したOSと実際のターゲットOSが正しいかどうか
2)DoublePulsarがインストールされているかどうか
ここでDoublePulsarがインストールされていないと判断された場合、自動的にDoublePulsarのインストールを試みます。
以下が、EternalBlueのエクスプロイトコードを実行した様子です。
図3 Fuzzbunch にて EternalBlue のエクスプロイトを行っている画面
実行されると、まず攻撃先にDoublePulsarのPingコマンドを送信することで攻撃先にDoublePulsarがインストールされているかどうかを確認します。攻撃先にDoublePulsarが未だインストールされていないと判断した場合、攻撃先のOSに適したシェルコードを生成し送りつけていることが処理の流れからわかります。
WannaCry攻撃キャンペーンのマルウェアであるドロッパー①(詳細は前回ブログ「WannaCryのキルスイッチに見えた2次攻撃者の影」参照)に含まれるEternalBlueも上記と同じくDoublePulsarが存在するかどうかで処理が分岐しますが、FuzzbunchのEternalBlueと実際の攻撃で使用されたドロッパー①はMS17-010の脆弱性が存在するかどうかの確認部分に少し差異があることがわかりました。
Fuzzbunchでは、更新プログラムを適用済みの端末に対してもエクスプロイトコードを送信し、その応答の有無で攻撃の成功有無を判断します。
以下は、MS17-010の更新プログラムを適用した端末にFuzzbunchを利用して攻撃を試みている様子ですが、FuzzbunchではDoublePulsarがインストールされているかどうかを確認するものの、MS17-010の脆弱性が存在するかどうかを確認する挙動はなく、直接エクスプロイトコードを送信し、その応答から攻撃の成功有無を判断する流れになっていることがわかります。
図4 MS17-010を適用した端末にFuzzbunchを利用した攻撃を行っている画面
しかし、WannaCry攻撃キャンペーンで使用されたドロッパー①、および、キルスイッチおよび暗号化挙動が無効化された亜種のドロッパー①においては、攻撃先の端末にMS17-010の脆弱性が存在するかどうかを明確に確認する挙動が存在します。
以下は、亜種のドロッパー①が、MS17-010の更新プログラムを未適用の端末、および、適用済みの端末にそれぞれ送信したPeekNamedPipeリクエストです。
ドロッパー①は、PeekNamedPipeリクエストの応答情報におけるSMB Headerのnt_statusの値が「0xC0000205」であるかどうかを確認することで、更新プログラムの適応有無を判断する挙動があります。
図5 MS17-010の更新プログラムの未適用端末におけるSMBサービスの応答
図6 MS17-010の更新プログラムの適用済み端末におけるSMBサービスの応答
以下は、ドロッパー①がPeekNamedPipeリクエストの応答情報であるSMBHeaderのnt_statusの値が0xC0000205であるかを確認し、MS17-010の脆弱性の有無をチェックする部分のコードです。
図7 ドロッパー①がSMBサービスの応答内容から脆弱性有無をチェックするコード
つまり、Fuzzbunchには含まれない脆弱性の有無を確認する挙動がドロッパー①には含まれていることがわかりました。
ドロッパー①における以上の挙動をまとめると次のような流れとなります。
1)MS17-010の脆弱性が存在する場合
- DoublePulsarが存在する
→ DoublePulsarを利用してドロッパー①をリソースに含むDLLを送付・実行させる - DoublePulsarが存在しない
→ DoublePulsarをインストールし、ドロッパー①をリソースに含むDLLを送付・実行させる
2)MS17-010の脆弱性が存在しない場合
- DoublePulsarが存在する
→ DoublePulsarを利用してドロッパー①をリソースに含むDLLを送付・実行させる
なお、Fuzzbunchには「VerifyTarget」という設定がありますが、これは脆弱性の有無を確認する設定ではなく、以下の説明の通り、SMBパケットの応答情報からOS情報を取得し、攻撃先OSとして設定されたものと一致するかどうかを確認する設定となります。
図8 Fuzzbunchの「VerifyTarget」の説明
次にFuzzbunchにおけるEternalBlueの攻撃対象OSの設定について見てみます。
以下は、FuzzbunchにおけるEternalBlueの攻撃対象設定の選択画面ですが、攻撃先OSとして選択できる項目が「WindowsXP 32bit」と「Windows7 and 2008 R2 32/64bit」の2つしか用意されていないことがわかります。
図9 選択できる攻撃対象は「Windows XP 32bit」と「Windows 7 and 2008 R2 32/64bit」
また、Fuzzbunchに含まれるFuzzbunchのインターフェイスを動作させるために実行する「fb.py」というPythonのプログラムは、python2.6の環境でないとうまく動作しないことが検証の結果わかりました(Python2.7では動作不可)。Python2.6のリリースは2008年のため(※2.7のリリースは2010年)、あくまで仮説となりますが、NSAはこれらの攻撃ツールを2008年から2010年頃に作成していた可能性があるともいえるかもしれません。以下の図は「fb.py」のソースコードの先頭部分ですが、明確にpython2.6を指定していることがわかります。
その頃はちょうどWindows 7が出始めた頃であり、当時のOSシェアを鑑みると、世間の端末の大半であったWindows XPとWindows 7を選択肢とすることで世間の大半の端末を攻撃対象に含めようとしていた背景が伺えます。
図10 「Fuzzbunch」の動作にはPython 2.6 が必要
続いて、DoublePulsar について確認していきます。
DoublePulsar は、EternalBlueと同じくNSAから流出したFuzzbunchに含まれているバックドアです。SMBまたはRDPプロトコルを用いて通信を行い、以下のコマンドを実行できます(シェルコードをファイルに書き出すだけのコマンドもありますが、ここでは割愛します)。
1)Ping(感染有無の確認用)
2)RunDLL(指定した任意DLLのインジェクション)
3)RunShellcode(任意のコード実行)
4)Uninstall (アンインストール)
図11 Fuzzbunchに含まれるDoublePulsarのバックドアコマンド
以下は、FuzzbunchのインターフェイスからDoublePulsarを選択し攻撃の設定を行う様子です。
下記の例では2)の「RunDLL」を攻撃のコマンドに指定しています。
図12「EternalBlue」による攻撃成功後、「DoublePulsar」に命令を送る画面
なお、上図からFuzzbunchにおけるDoublePulsarではDLLに加え、インジェクション対象のプロセス名も指定できるようになっていることがわかります。
なお、WannaCry攻撃キャンペーンで使用されたドロッパー①では、「lsass.exe」を指定してインジェクションを行います。
■WannaCry 2.0のワーム活動概要
ここまでの検証で、流出したFuzzbunchにおいてもWannaCryと同様にEternalBlueとDoublePulsarは基本的にペアで利用されるつくりとなっていることがわかりました。
また個々の操作を知ることで、大まかに以下のような順序でターゲットに侵入することも確認できました。
1. DoublePulsarの存在確認およびEternalBlueを利用した攻撃
2. 脆弱性を利用してDoublePulsarを設置(存在しない場合)
3. DoublePulsarに命令(WannaCryの配布・実行)を送信
4. 命令が実行されることでWannaCryに感染
・・・以降繰り返し
上記で得られたEternalBlueとDoublePulsarの役割、関係性を踏まえ、WannaCry2.0のワーム活動(感染の横展開の流れ)を整理すると以下のようになります。
図13 WannaCry 2.0 の感染の横展開の流れ
WannaCryの感染による脅迫画面のUIが表示されるのは、⑤のタイミングの直後になります。WannaCryのサービスが動作すると、暗号化が開始され、UIが表示されるとともに、別の端末へ拡散する動作となります。
■ EternalBlueのエクスプロイトからDoublePulsarを介したWannaCry感染までの詳細
ここでは、EternalBlueのエクスプロイトにより設置したDoublePulsarを介し、ユーザ空間のプロセスへ任意のDLLのインジェクションを行うまでの動作を踏み込んで見てましょう。
まず、EternalBlueによるSMBサービスの脆弱性攻撃ですが、カーネルスペースの非ページプール領域でバッファオーバーフローを発生させ、DoublePulsarのシェルコードを動作させます。具体的にはSMBサービスの内部処理で使用される構造体の変換時のキャスト処理において発生する整数オーバーフローが原因です。これによりメモリのコピーサイズにずれが生じ、本来の書き込み領域である「srv.sys」のバッファ領域を超え、「srvnet.sys」のバッファ領域に書き込みが可能となります。
図14 DoublePulsarのシェルコードに至る流れ
DoublePulsarのシェルコードは実行されるとSMBの関数テーブル(SrvTransaction2DispatchTable)の「SrvTransactionNotImplemented」関数のアドレスをDoublePulsarのバックドア機能を有するコードのアドレスに書き換え(フックし)ます。
書き換え前後のテーブルの状態は以下のようになります。
図15 書き換え前後のSMBの関数テーブルの内容
「SrvTransactionNotImplemented」関数をフックする理由は、Double Pulsarがバックドアコマンドの受信部を構築するためです。「SrvTransactionNotImplemented」は無効な要求を受けた場合に呼び出される関数です。
感染元(図13の「端末A」)が感染先(図13の「端末B」)の端末にバックドアコマンドやペイロードを含む 正しくない要求をSMBサービスに送信すると、端末Bではそれを無効な要求と認識するため、「SrvTransactionNotImplemented」関数を呼び出します。しかしながら、この関数は既に偽の内容でフックされており、無効な要求の内容からコマンドやペイロードを解釈しバックドアコマンドとして実行します。これは上記にて書き換えられた関数のジャンプ先のコードを見ることで確認できます。
ジャンプ後、まもなく命令の解釈の機構があることが確認できます。
図16 「SrvTransactionNotImplemented」が置き換えられた(フックされた)後のジャンプ先のコード
WannaCryはターゲット端末に対して、DoublePulsarのバックドア機構を使用して、自身のメモリ内から「launcher.dll」のバイナリデータとRunDLLの命令、対象プロセス名として「lsass.exe」の情報を送信します。ターゲット端末では受信した「launcher.dll」をファイル化することなく、メモリ上で処理し「lsass.exe」にインジェクション(注入)します。
このカーネルランドからユーザーランドへのDLLインジェクションについては、CIAからの流出情報にも類似情報(Kernel to User land: APC injection/Vault 7: CIA Hacking Tools Revealed/WikiLeaks)が含まれています。
「lsass.exe」に注入された「launcher.dll」は、ドロッパー①に位置する「mssecsvc.exe」を端末内にファイルとしてドロップし実行します。実行された「mssecsvc.exe」は自身をサービスとして登録し、開始します。
図17 lsass.exeに注入されたコードがサービスを作成、起動する様子
そしてサービスとして動作する「mssecsvc.exe」が、「taskse.exe」を介し「@WannaDecryptor@.exe」を起動します。
図18 登録されたWannaCry(ドロッパー①)のサービス
WannaCryは上述の通り、自身の起動にサービスを利用します。このとき、サービスの登録にシステム権限が必要となるため、システム権限を持ち、かつどの環境でも動作している「lsass.exe」をインジェクション対象のプロセスとして選択したものと考えられます。
なお、攻撃元から攻撃先への送信パケットに含まれるlauncher.dllは、XORで暗号化されています。そのXORの暗号化キーは、感染端末から攻撃元へのTrans2 Response Error:STATUS_NOT_IMPLEMENTEDのレスポンスにおけるSMB Header内のSignatureとして応答される値がXORの復号キーを生成するためのキーとなります。
図19 パケットデータを復号するために必要なXOR(復号)キーの生成キー
以下は、WannaCryの該当XORキーを復号するPythonスクリプトを用いて生成したパケットデータの復号キーです。ここでわかるようにXORの復号キーは常に可変値を取ります。
図20 XOR(復号)キーは可変値を取るため計算が必要
その後に攻撃側から送信されるTCP segment dataのパケットデータ内にシェルコードとともにlauncher.dllが含まれます。
図21 「launcher.dll」の本体(暗号化状態)が格納されたパケットデータ
以下は、得られたXORキーでパケットデータを復号した様子ですが、MZから始まるPEファイルが確認できます。
図22 生成したXOR(復号)キーを使用してパケットデータを復号した様子
そして以下は、その後攻撃された側の「lsass.exe」のプロセス空間の様子ですが、実行フラグが立てられたアドレス領域に「launcher.dll」がインジェクションされています。
図23 「lsass.exe」のプロセス空間に「launcher.dll」がインジェクションされている
改めてこれまでのワーム活動の流れの詳細を図示すると以下(図24)のようになります。
図24 WannaCry 2.0 の感染の横展開の流れ(詳細)
■ WannaCryに感染した端末にはDoublePulsarが存在するのか
ここまでの検証からEternalBlueとDoublePulsarそれぞれの役割を把握することができました。
また、流れを見る限り、MS17-010の脆弱性攻撃を介してWannaCryのドロッパー①(従来および亜種を含む)に感染した端末では、必ずDoublePulsarがインストールされることがわかります。
なお、弊社ではWannaCryの亜種に言及した前回のブログ記事の中で、暗号化挙動がない検体が拡散している考察の1つとして「DoublePulsarの拡散を狙っている背景も考えられなくもありません。」とし、この点について簡単に触れていました。
では実際に、WannaCryの亜種のドロッパー①に感染した端末には第三者がDoublePulsarに接続できる状況になっているのか、という点について今回実検証を通し確認していきます。
以下の図25の通り、WannaCry(亜種)に感染済みの端末Aからのワーム活動による横展開によってWannaCryに感染した端末Bに対し、Fuzzbunchからバックドア命令を送信する試みを行いました。
図25 WannaCryにより設置されたDoublePulsarに対し第三者から命令を送信する検証の構成
命令の内容は以下の通り、ターゲット端末のメモ帳のプロセス(notepad.exe)に対し、メッセージボックスを表示するだけの「launcher.dll」を注入し、DLLが提供する序数1番目のAPIを実行するように設定しました。
図26 設定したバックドア命令の内容(DoublePulsarの設定)
結果として、WannaCryに感染した端末B(のDoublePulsar)に対し、別の端末からFuzzbunchを使用してバックドア命令を送信、実行できることが確認できました。
つまり、WannaCry(亜種を含む)のドロッパー①に感染した端末にはDoublePulsarが存在し、第三者がそのDoublePulsarへ接続できる状況になっているという事実が実証できました。
図27 「notepad.exe」のプロセスに注入されたDLLが動作した様子
(セッション0のSMBサービスからセッション1の「notepad.exe」へインジェクションされた)
なお上記図27にあるように、DoublePulsarが行うDLLインジェクションの手法はLoadLibrary等の関数を介していないため、モジュール一覧には表示されません。そうした観点からも、より隠蔽度が高い感染手法であるといえるでしょう。
なお補足となりますが、EternalBlueおよびWannaCryによるMS17-010の脆弱性攻撃の検証の際、同一環境であってもエクスプロイトに失敗しBSOD(ブルースクリーン)が発生するケースが多々あることを確認しています。これはバッファオーバーフローが不安定な性質を持つ上に、システムに深く影響するカーネルランドのエクスプロイトであることに起因すると想定されます。
■まとめ
本記事の検証を通し、WannaCryのワーム活動の内部動作を全体から詳細に当たるまで整理するとともに、「暗号化機能を持たないWannaCryの亜種」においても、第三者からのバックドアを介した遠隔操作等の攻撃が行われる可能性を確認することができました。
これが意味することは、暗号化がされなくとも(目立った画面が表示されなくとも)、バックドアとしての動作は継続・成功しており、今後新たなマルウェアを送り込まれるリスクが残る、ということです。また、補足として述べた通り、エクスプロイトの不安定さからBSODを引き起こす状況が多々発生することから、連鎖するシステム障害を引き起こす要因になり得る脅威といえます。
DoublePulsarはメモリ上にのみ存在するため、感染PCを再起動することで消滅します。一度感染した環境においては更新プログラムをインストールした後もDoublePulsarが動作を継続している可能性が高いため、OSの再起動が必要です。
以下は、MS17-010の更新プログラムをインストールした直後のウインドウですが、「閉じる」ボタンを押したのみでそのまま再起動を忘れないように注意する必要があります。ウインドウに記載があるとおり、更新プログラムを有効にするためにも、コンピューターの再起動が必要です。
図28 更新プログラム適用後、再起動を促す画面
また、WannaCry(亜種を含む)のドロッパー①によるワーム感染において、DoublePulsarのインストールは自分自身に対しては行いません。そのため、更新プログラムを適用していなくても再起動することでDoublePulsarの除去は行えますが、同じネットワーク内にWannaCryに感染した端末が他に1台以上存在した場合、結果的にお互いがDoublePulsarを入れあうことになり、たとえ全台を再起動していても、最終的にはWannaCryに感染している端末全てがDoublePulsarにも感染しているという状況がその後も継続してしまう点に注意が必要です。このことからも、更新プログラムの適用+再起動は必須といえるでしょう。
■Appendix:DoublePulsarのバックドアコマンド
DoublePulsarに送信できる命令は、図11で確認したとおり以下の4つがありました。
1)Ping(感染有無の確認用)
2)RunDLL(指定した任意DLLのインジェクション)
3)RunShellcode(任意のコード実行)
4)Uninstall (アンインストール)
しかしながら、図16から確認できるWannaCryにより設置されたDoublePulsarのコードでは、命令の分岐は以下の3つとなっており、数が合いません。
図29 DoublePulsarの命令解釈部分のコード
そこで以下では、Fuzzbunchで確認できる4つの命令と、DoublePulsarのコードから確認した3つの命令コードの対応を確認してみます。
まずはFuzzbunchで「Ping」を選択し、命令を送信しました。
するとDoublePulsarが受信した命令は「0x23」であることが確認できました。
図30 Fuzzbunchから送信したPing命令と攻撃先のDoublePulsarで受信した命令コード
続いて「RunDLL」を試します。
図31 Fuzzbunchから送信したRunDLL命令と攻撃先のDoublePulsarで受信した命令コード
結果「0xC8」を送信することが確認できました。
また、事前に「0x23」のPing命令で疎通確認をする、という内部動作も新たにわかりました。
「RunShellCode」も命令としては同様で、初回「0x23」(Ping)命令で疎通確認をした後に「0xC8」を送信する流れであることを確認しました。
図32 Fuzzbunchから送信したRunShellcode命令と攻撃先のDoublePulsarで受信した命令コード
以上より、「RunDLL」と「RunShellCode」の命令は同一の命令コード「0xC8」で実現されていることを確認しています。
「Uninstall」命令も同様の流れで、「0x23」による疎通確認の後、「0x77」を受信することで、フック関数が元の状態に戻され、バックドアが存在しない状態になることを確認済みです。
図33 Fuzzbunchから送信したUninstall命令と攻撃先のDoublePulsarで受信した命令コード
図34 DoublePulsarのアンインストール後は命令を受け取れなくなった
これらの情報からFuzzbunchで選択可能な命令と、DoublePulsarに送信される命令コードの対応付けをまとめると以下のようになります。
Fuzzbunchで選択可能な命令 | DoublePulsarに送信される命令コード |
---|---|
Ping
|
0x23 |
RunDLL
RunShellcode |
0xC8 (事前に0x23で疎通確認) |
Uninstall
|
0x77 (事前に0x23で疎通確認) |
表:Fuzzbunchで選択可能な命令とDoublePulsarに送信される命令コード
これにより、Fuzzbunchで確認できる4つの命令と、DoublePulsarのコードから確認した3つの命令は、数は合わないものの、上記の通り対応付けられ構成されていることが確認できました。
関連ブログ記事
おすすめ記事