背景情報

WannaCryと同様、NSAから流出したツールを利用する新しいサイバー脅威Petyaの大規模な攻撃が再び発生しました。特定の被害者をターゲットとし、データの破壊のみを目的としてい点が今回の攻撃の大きな特徴です。Petyaはランサムウェアのように見えますが、被害者が身代金を支払っても暗号化されたファイルの復号は無理なようです。

Petyaは2016年に初めて確認されましたが、攻撃手法は今回とはまったく異なるものでした。2017年バージョンは感染のスピードを優先し、ターゲットにするファイルの種類を絞り込んでいます。また、同じドメイン内での感染拡大を重視している点も、一般的なランサムウェアと大きく異なる最新バージョンの特徴です。この脅威は同じ企業ネットワークにあるコンピュータへの感染を狙っているため、世界中のセキュリティ・サービスが内部からの攻撃をブロックする方向へと方針転換を始めました。最初に使用される攻撃経路は現時点では明らかになっていません。

前回の投稿でも触れましたが、最近発生しているPetyaの一連の攻撃では、ランサムウェアのWannaCryで使われたものと同じツールが使用されています。新バージョンの作成者はWannaCryで利用されたDoublePulsarというバックドアにリバース・エンジニアリングを施し、巧妙に検出を回避しています。現在、Petyaはこのバックドアを独自に修正したDoublePulsarV2.0を使用しています。

新しいPetyaの脅威対策としては、2008年のConficker以降、最も効果的なパッチであるMS17-10のパッチが有効であり、今後も数年間は十分な効果を発揮すると考えられます。チェック・ポイントのIPSはDoublePulsar、SMBTouch、CVE-2017-0144(EternalBlue)などを対象に同様の保護機能を提供します。

本稿では、この新しいバックドアについて解説します。

DoublePulsarV2.0

カーネルの分析:

Petyaに埋め込まれているDoublePulsarは、WannaCryで見つかった(元々はハッキング・グループShadow Brokerが流出させた)前バージョンと同じように機能します。どちらも実行フローはほとんど同じですが、前者の実装はわずかに変更されています。DoublePulsarのインストール・プロセスは複数の段階に分かれており、各段階では次の段階で必要となる情報を取得します。バックドアが設定され、新たなコマンドを受けられるようになったら、インストールは終了です。このバックドアは32ビット版と64ビット版があり、システムのアーキテクチャに応じてどのバージョンを動かすべきか実行時に判断されます。

インストールの大まかなプロセスは次のとおりです。

第1段階 – カーネルのエクスポート関数を取得:まずはカーネルのメモリ内を移動するための基本的なツール・セットを取得しないと、DoublePulsarはいかなるアクションも実行できません。そうしたツールは、具体的にはntoskrnl.exe(Windows NTのカーネル・イメージ)によってエクスポートされる関数のことです。DoublePulsarでは次の関数を使用します。

  • ZwQuerySystemInformation – さまざまなシステム情報を種類別に取得します。
  • ExAllocatePool – メモリ・プール内でメモリ・ブロックの割り当てを行います。メモリ・プールはユーザ・モード・ヒープと同等のカーネル領域です。
  • ExFreePool – 前述のプールで割り当てられたメモリ・ブロックを開放します。

このような関数のポインタを取得するため、DoublePulsarのペイロードはまずはじめにKPCR(Kernel Processor Control Region)構造体のポインタを取得します。KPCR構造体はカーネルの仕様非公開のデータ構造体であり、各種の便利なフィールドが含まれています。例えば、この構造体の先頭からオフセット4の位置にあるフィールドは、IDT(割り込みディスパッチ・テーブル)を指し示します。そのテーブルはntoskrnl.exeのイメージのメモリ内にあり、その1点だけでこのフィールドは特に興味深い存在と言えるでしょう。さらに、このテーブルはメモリ・ページの先頭に位置揃えされるため、アクセスできたDoublePulsarのコードはページ単位で後方に移動しながら、各ページの先頭がMZ(PEマジック・ナンバー)であるかどうかをチェックできます。そうしたページが見つかったら、ntoskrnl.exeの先頭に達したと判断して間違いありません。

図1:メモリ内でntoskrnl.exeのイメージを特定するコード
図1メモリ内でntoskrnl.exeのイメージを特定するコード

ntoskrnlのイメージのポインタを取得した後、DoublePulsarのコードはPEの構造体を辿ってイメージのエクスポート・アドレス・テーブルにアクセスします。このテーブルはイメージ内にあるエクスポートされた関数のエントリ・ポイントを保持するもので、他のコードが関数を実行する際にも便利に利用できます。既存の関数名のスキャンでは、エクスポート・ディレクトリのAddressOfNames配列を辿りながら、ひとつひとつの名前のハッシュを特定のアルゴリズム(後述)で作成し、その結果を引数のハッシュと比較します。後者のハッシュはリクエストされた関数名を表します。目的の関数名が見つかったら、その名前のインデックスを持つ要素をエクスポート・ディレクトリのAddressOfFunctions配列から取り出すことで、エントリ・ポイントのアドレスを取得できます。

第2段階 – SMBドライバを取得:この時点で、取得した関数は、さらに便利な情報を得るためのプリミティブとして使用することが可能です。具体的にはExAllocatePoolを使用してメモリを確保すると、ZwQuerySystemInformationで取得した情報がそのメモリに書き込まれます。後者の関数はSystemQueryModuleInformationというInformationクラスの引数を使って呼び出され、システムに読み込まれているすべてのドライバのリストを返します。DoublePulsarのコードがこのリストをスキャンする際には、(前述した同じアルゴリズムを使って)各ドライバのフルパスのハッシュが作成され、SMBドライバ(srv.sys)に対応する定義済みのハッシュと比較されます。

第3段階 – ドライバの関数のフックをインストール:DoublePulsarのインストールの最終段階ではsrv.sysドライバのポインタを使用します。DoublePulsarのコードは、SrvTransaction2DispatchTableという名前のテーブルがあるドライバのイメージの.dataセクションを探します。このテーブルには特定の種類の着信SMBパケットを処理する関数のポインタと、SrvTransactionNotImplementedという名前の重要な関数が1つあります。この関数は予約されているフィールドまたは想定外のフィールド(TimeoutやReservedなど)が使用されている不正な形式のパケットを処理します。この関数を特定のハンドラに置き換えれば、そうしたフィールドを巧みに利用して、バックドアにコマンドを送信することや送信元に応答を返すことができます。

ただし、DoublePulsarのコードはSrvTransactionNotImplemented関数を完全に削除するのではなく、ディスパッチ・テーブルにおけるそのエントリを「記憶」した上で、前述のパケット・フィールドで渡されるコマンドを処理する独自の関数のポインタと置き換えます。このハンドラは割り当てられたメモリ領域に書き込まれ、不正な形式のパケットを受信するたびに呼び出されます。実行時には、コマンドの応答をカスタマイズして送信元に返せるように、渡された引数に必要な修正を加えてオリジナルの関数を呼び出します。

なお、現バージョンのPetyaにインストールされているハンドラは、WannaCryで確認されたものとは少し異なります。具体的にはハンドラがチェックするコマンドの値(Petyaの場合は0xf0、0xf1、0xf2)と、応答として渡される値(0x11と0x21)に違いがあります。コードで行われる各値のチェックの詳細については、下記をご覧ください。下の図でもチェックの内容を把握できます。

Petya版のDoublePulsarで見つかった新しいコマンド・コード
図2Petya版のDoublePulsarで見つかった新しいコマンド・コード

Petya版のDoublePulsarで見つかった新しい応答コード
図3Petya版のDoublePulsarで見つかった新しい応答コード

DoublePulsarの実行時に使用される文字列ハッシュ関数の概要は、次のPythonコードで確認できます。


次の表は、DoublePulsarのコードで確認されたハッシュ値に対応する文字列を示しています。


次の図は、これまでの分析で説明した実行フローを視覚的に表しています。

図5:バックドア「DoublePulsar」のインストール・プロセスの概要
図5バックドア「DoublePulsar」のインストール・プロセスの概要

SMBの分析:

インストールされたDoublePulsarV2.0は、サブコマンドのTRANS2_SESSION_SETUP(0x000E)を使用したSMB_COM_TRANSACTION2(0x32)コマンドによる基本的な通信インタフェースを用意します。

Shadow Brokersが流出させ、WannaCryで使われていた前バージョンとは異なり、DoublePulsarV2.0は「Timeout」フィールドと「Reserved」フィールドを使ってメッセージを送信します。

この方法を採用したバックドアの通信は、人気のオープンソース・ツールであるMetasploitDoublePulsar検出スクリプトによるルールベースの検出やスキャンを回避できます。

「Timeout」フィールドを使うと、(エンコーディングやXORメソッドを使用せず)コマンド自体をハードコード化して送信できます。「Reserved」フィールドは、リクエストしたコマンドについて、バックドアから肯定的または否定的な回答を得るために使用します。

「CIFS(Common Internet File System)プロトコル」には次のような記述があります。

「Reservedフィールドは予約済みであり、0x0000に設定されていなければなりません。」

これは実際に悪用が行われてきたことを物語っています。

ここで、図2で説明されている3つの基本的なコマンドを確認しておきます。

「Timeout」フィールド:

  1. 0xf0(0.240秒) – バックドアがインストールされているかどうかを確認する。
  2. 0xf1(0.241秒) – バックドアをアンインストールする。
  3. 0xf2(0.242秒) – DLLを読み込むか、シェル・コードを実行する。

図3にある3つの応答オプションも確認しましょう。

「Reserved」フィールド:

  1. 0x0000 – 否定的な応答。
  2. 0x1100 – 肯定的な応答。
  3. 0x2100 – エラー・メッセージ(不正なコマンド)。

ここからは、Petyaに見られるバックドアの通信フローを示します。

まずは0xf0コマンドを使って、バックドアがインストールされているかどうかを確認します。


バックドアがインストールされていないことを示す否定的な応答を受信します。


MS17-10(EternalBlue)を悪用してバックドアがインストールされると、同じ0xf0コマンドを使用した次のチェックが、インストールの確認応答を受けて終了します。


この時点で、同じネットワークの次の標的マシンに、0xf2コマンドを使ってペイロードを送信できます。


次のように不正な0xf7コマンドをバックドアに送信すると、応答コードには不正なコマンドのエラー・メッセージも含まれます。

エラー・メッセージが生じる不正なリクエスト:


チェック・ポイントのIPSの対応範囲

次に示すのは、チェック・ポイントのIPSの保護機能で対応できるPetyaの攻撃経路のリストです。

チェック・ポイントのIPSのSoftware Bladeは、Petyaのすべてのエクスプロイトをブロックする万全な保護機能を提供します。

IPSの対応範囲:

  • Microsoft Windows SMBTouch Scanner(Microsoft Windows SMBTouchスキャナ)
  • Microsoft Windows SMB Remote Code Execution(Microsoft WindowsにおけるSMB経由でのリモート・コード実行)(MS17-010:CVE-2017-0144)
  • Microsoft Windows SMB Information Disclosure(Microsoft WindowsにおけるSMB経由での情報漏洩)(MS17-010:CVE-2017-0147)
  • Microsoft Windows EternalBlue SMB Remote Code Execution(Microsoft Windowsにおける、EternalBlueによるSMB経由でのリモート・コード実行)
  • Petya Ransomware Lateral Movement Remote Code Execution(ランサムウェアPetyaの水平展開によるリモート・コード実行)
  • Microsoft Windows DoublePulsar SMB Remote Code Execution(Microsoft Windowsにおける、DoublePulsarによるSMB経由でのリモート・コード実行)