「Pawn Storm作戦」で利用されたFlash Playerの脆弱性、Adobeの緩和策を回避

トレンドマイクロは、2015年10月、標的型サイバー攻撃キャンペーン「Pawn Storm 作戦」が Adobe Flash Player に存在するゼロデイ脆弱性を攻撃に利用したことを確認しました。その後、弊社が解析したところ、Flash Player の脆弱性を利用する攻撃を軽減するために Adobe が以前に導入した緩和策が、この脆弱性を利用した攻撃から PC を保護するのに十分でないことが判明しました。

世界各国の外務省を標的にした「Pawn Storm 作戦」で利用された脆弱性「CVE-2015-7645」は、脆弱性を利用したこれまでの攻撃手法と大きく異なっていました。なお、Adobe は、この問題の脆弱性に対応したセキュリティ情報「APSB15-27」を公開しており、Flash の最新バージョン「19.0.0.226」はもはやこの脆弱性の影響を受けることはありません。

■Adobe が導入した緩和策
Adobe は、2015年、Google の「Project Zero」と協働し、Flash Player の脆弱性を利用する攻撃に対して、いくつかの緩和策を導入しました。この緩和策は、Vector.<*>の脆弱性を利用する攻撃の軽減に重点が置かれました。破損した Vector.<*>は、メモリの任意の箇所の読み込みや書き込みを実行するために利用されることが頻繁にあります。この脆弱性が利用されると、「Data Execution Prevention(DEP)」や「Address Space Layout Randomization、ASLR)」、「Control Flow Guard(CFG)」、「Enhanced Mitigation Experience Toolkit(EMET)」といったさまざまなセキュリティ対策が回避され、ブラウザのプロセス内で遠隔からコード実行される恐れがありました。

この緩和策が実施されると、脆弱性を利用した攻撃は減少しました。しかし、完全になくなったわけではありません。今回の事例は、緩和策導入後、最初に確認されたゼロデイ攻撃です。

■「CVE-2015-7645」は「Pawn Storm 作戦」でどのように利用されたか
上述のように、「Pawn Storm 作戦」はゼロデイ脆弱性を利用して世界各国の外務省を攻撃の標的にしました。攻撃標的者は、エクスプロイトコードに誘導する URL が含まれた標的型メールを受信しました。標的型メールは、メールの件名や記載された URL の文字列などから、最近の出来事に関連したニュース記事に見えるように巧妙に作成されていました。

攻撃標的者が標的型メールに記載された URL をクリックすると、エクスプロイトコードがダウンロードされます。このエクスプロイトコードは、弊社の製品では「SWF_OLOLO.A」として検出されます。この不正プログラムは、「TROJ_SEDNIT.D」として検出される DLLファイル “marlou.fel” を作成します。不正プログラム「SEDNIT」の亜種は、「Pawn Storm作戦」のすべての攻撃キャンペーンで利用された不正プログラムです。

■脆弱性「CVE-2015-7645」の根本原因を解析
今回の脆弱性は新しい種類の脆弱性であり、「Method Confusion(メソッドの取り違え)」とでも呼べるものです。これは、弊社がこれまでに解析した Flash Player の脆弱性の中でも、最も目を引くものでした。

脆弱性を利用する、不正な SWFファイルは難読化されていました。難読化を復号し、分析すると、弊社は、ByteArrayオブジェクトのメソッド「writeObject」に脆弱性が存在することを確認しました。ba.writeObject(some_obj)を処理する際、some_obj がインターフェイス「flash.utils.IExternalizable」を実装するクラスのオブジェクトだった場合、IExternalizable のメソッド「writeExternal」を呼び出します。

メソッド「writeExternal」はクラス「some_obj」の定義で実装されていなければなりません。しかし、「writeExternal」と名付けられたプロパティのフィールドがあり、通常と異なる方法で定義されていた場合、プロパティ「writeExternal」はメソッド「writeExternal」を隠ぺいします。

図1 は、この巧妙な定義です。

図1:特殊なクラス定義
図1:特殊なクラス定義

メソッド「writeExternal」がプロパティ「writeExternal」によって隠ぺいされると、メソッドの関数「binding_id」は誤った値を持ちます。ba.writeObject(some_obj) では、「writeExternal」の関数「binding_id」を最初に取得する必要があります。その後、この関数を利用して、methods[binding_id] のようなセンテンスを使ってメソッドの環境構造を取得します。

取得したメソッドの環境構造はネイティブコードに「Just-In-Time(JIT)」でコンパイルされ、その後呼び出されます。

以下は、ba.writeObject(some_obj) でメソッド「writeExternal」を呼び出した時の簡単な手順です。

  1. パブリックの名前空間で「writeExternal」を名前検索して、関数「binding_id」を検索する
  2. methods[binding_id] でメソッドの環境構造を取得
  3. メソッドの環境構造をネイティブコードに JIT でコンパイルし、その後呼び出す

関連するコードは、AVMPlus オープンソースプロジェクトで確認できます。また、コンストラクタ「ClassInfo」では、m_functionBinding がパブリックの名前空間と文字列「kWriteExternal」を利用するのを確認できます。

図2:「Get kWriteExternal function binding」のコード
図2:「Get kWriteExternal function binding」のコード

図3:「Find MethodEnv pointer」のコード
図3:「Find MethodEnv pointer」のコード

上記で重要なセンテンスは、MethodEnv* method = obj->vtable->methods[id] です。

「writeExternal」の関数「binding_id」は、プロパティ「writeExternal」によって隠ぺいされた後、誤った値を持ちます。それは、パブリックのプロパティ「writeExternal」を検索するからです。

つまり、エクスプロイトコードは特殊なクラス定義を構築し、関数「binding_id」の必要な値を取得することができます。

AVMPlus のソースコードから、obj->vtable->methods[id] からメソッドを読み込むことがわかります。この id の値は制御可能なため、エクスプロイトコードも MethodEnv* の読み出しを制御できます。これ以降、この脆弱性は「メモリ領域外の読み込み」の脆弱性となります。つまり、エクスプロイトコードがメモリ配置を制御し、任意の MethodEnv* を偽の関数「binding_id」に割り当てることができます。

このエクスプロイトコードは、別の特殊な AS3 で定義されたメソッドを利用し、ksome_externalizable_obj をこのポインタとして用い、呼び出されます。ここでは「Type Confusion(型の取り違え)」の脆弱性のように見えます。

要約すると、この脆弱性は以下の手順で利用されます。

  1. utils.IExternalizable を実装するクラスA を定義する。クラスA はメソッド「writeExternal」およびプロパティ「writeExternal」をパブリックの名前空間内で定義する。プロパティ「writeExternal」の命令を制御し、偽の関数「binding_id」を制御する
  2. クラスB を定義し、メソッドB を不正なコードで定義する。このコードは後で呼び出される。このクラスからの新しいオブジェクトはメモリ配置を制御するために利用され、メソッドB の環境構造が偽の「binding_id」に割り当てられることを確認する
  3. クラスA で新しい externalizable オブジェクトを生成し、その後、writeObject(externalizable_object)を利用して脆弱性を利用する
  4. メソッドB が呼び出され、攻撃者はメソッドの externalizable オブジェクトのこのポインタを制御できる

■Vector.<*>以外を利用した攻撃も可能に
攻撃者は上述の方法で脆弱性を利用しました。この事例では、ByteArray 基盤のオブジェクトの length フィールドを 0Xfffffff6 に上書きしました。攻撃者はこれを利用して、任意のメモリ位置で読み込みおよび書き込みを実行しました。ByteArray の長さは保護されていないため、Vector.<*>の緩和策はここでは役に立ちません。

今後、攻撃者は脆弱性を利用するために Vector.<*>を対象にする必要はありません。この攻撃で示されたように、他にも利用できるオブジェクトがあるためです。Adobe は ByteArray の長さだけでなく、プロパティ「length」を持つ他のオブジェクトも保護する必要があります。

■デバッグの詳細
弊社では、簡単な「Proof-of-concept(PoC、概念実証型エクスプロイト。実際に有効な攻撃ができることを実証している攻撃コード)」を作成して脆弱性を説明し、またデバッグを行いました。最初に、プロパティオブジェクト「writeExternal」を 28番目のプロパティに設定しました。この PoC は、関数「binding_id」のメモリ配置を制御しません。そのため、不要なメソッドの環境ポインタを読み出し、クラッシュを引き起こします。

弊社では拡張子「windbg」を使用して、この PoC をデバッグしました。この拡張子は AS3メソッドのブレークポイントを追跡し、設定することができます。この方法を用いると、MethodEnv* method = obj->vtable->methods[id] で簡単に一時中断できます。

図4:デバッガからの出力結果
図4:デバッガからの出力結果

■トレンドマイクロの対策
緩和策は脆弱性を利用した攻撃を減少できますが、完全になくなるわけではありません。隙のない完璧なエクスプロイトコードがセキュリティ対策を回避することはこれまでも起きており、ゼロデイ脆弱性を利用した攻撃に対して多重層の防御を用いることがユーザにとって最重要となります。弊社の製品はネットワーク基盤のすべての層を保護し、ゼロデイ脆弱性を利用した攻撃からユーザを守ります。

トレンドマイクロ製品をご利用のユーザは、この脅威から守られています。弊社のネットワーク挙動監視ソリューション「Trend Micro Deep Discovery(トレンドマイクロ ディープディスカバリー)」のサンドボックスや「Script Analyzer」エンジンにより、他のエンジンやパターンの更新がなくても、この脅威をその挙動で検出することができます。

また、トレンドマイクロのサーバ向け総合セキュリティ製品「Trend Micro Deep Security(トレンドマイクロ ディープセキュリティ)」および「Trend Micro 脆弱性対策オプション(ウイルスバスター コーポレートエディション プラグイン製品)」をご利用のお客様は、以下のフィルタを適用することにより、この Adobe Flash Player のゼロデイ脆弱性を利用した攻撃から保護されます。

  • 1007119 – Identified Malicious Adobe Flash SWF File

また、今回の脅威に関連した不正プログラムの SHA1ハッシュ値は以下のとおりです。

  • 2DF498F32D8BAD89D0D6D30275C19127763D5568 -「SWF_OLOLO.A」として検出
  • 20F5A9C0E1D2AEF36D15CA149FE71AC6B2A9AF1E -「TROJ_SEDNIT.D」として検出
  • A5FCA59A2FAE0A12512336CA1B78F857AFC06445 -「TSPY_SEDNIT.D」として検出

協力執筆者:Stanley Liu

参考記事:

 翻訳:品川 暁子(Core Technology Marketing, TrendLabs)