2000P's Blog

最初のページ

2545 wordはサンプルを用いて分析する。

著者 winterton 時間 2020-03-31
all

作者:xd 0 ol [email protected]創宇404実験室を知っています。

0ピン

前の記事では、Officeドキュメント型の脆弱性CVE-2015-641の利用を分析しました。このような脆弱性の中のもう一つの一般的な例CVE-2015-2545(MS 15-009)について分析を続けます。対照的に、これらのExpの脅威はより大きく、例えば「Word EPS+Windows EoP」という組み合わせが採用され、多くのところでブラウザ・ホールの利用構想を参考にしているので、我々が研究する価値があります。

1サンプル情報

分析に使用するサンプル情報は以下の通りです。

このファイルの拡張子をzipに変更しました。解凍後、下記のディレクトリ構造が得られます。

この中で、image 1.epsは、慎重に設計された脆弱性を利用したファイルであり、PostScript言語によって作成された特殊なグラフィックファイルであり、ここではWordとPostScriptの関係はある程度IEブラウザとJavaScriptの関係に類することができ、PostScript言語に関する説明はこのマニュアルを参照することができます。

image1.eps

さらに、本明細書の分析環境はWin 7 x 86+Office 2007 SP 3であり、EPSIM P 32モジュールのバージョン情報は以下の通りである。

2脆弱性の原理分析

まず原理を見て、簡単に言えば、EPS(Encapulated PostScript)グラフィックファイルを解析する際にUAF(Use-After-Free)の脆弱性があり、そのエラーコードはEPSIM P 32モジュールにあります。理解を容易にするために、サンプルの中でこの脆弱性を引き起こす部分のPostScriptコードを提供します。もちろん、ある程度の反混淆処理があります。

オペレータのcopyとforallの定義は以下の通りです。

上記のコードに関連して、dict 2オブジェクトをforallで操作する場合、dict 2の「key-value」を反復処理し、pNextポインタを次の処理の「key-value」に向けるという、より具体的な説明を与えます。しかし、procにはdict 1 dict 2 copyの操作があります。この過程でdict 2の元の「key-value」空間を解放してから、新しい空間を申請して次のコピーを行います。つまり、元のpNextが指す「key-value」空間が解放されました。その後、puttinterval操作では、元のpNextが指す空間を再利用し、特定の文字列を書き込みます。そのため、次の繰り返しの時、pNextが指すデータは私達が作った「key-value」になります。

dict1 dict2 copy

次に、このプロセスを完全に分析して、PostScriptオブジェクトとdictにおける「key-value」オブジェクトの定義を示します。

各PostScript操作子には、具体的な処理関数が対応しています。私たちはIDAで確認しやすいです。その後、相対オフセットの計算によってOllyDBGでキーポイントを特定できます。

下記のブレークポイントによって、EPSIM P 32モジュールのロード時に切断されます。

当然ながら、私たちはforallの対応関数を上下に切断し、dict操作の反復処理に関連するコードセグメントを得ることができます。ここで、EPSIM P 32のモジュールのアドレスは0 x 73790000です。

このプロセスは、次の処理を指す「key-value」とポインタpNextを取得するための4つのcall呼び出しを含み、2番目と3番目のcallはそれぞれkeyとvalueを操作スタックに格納するためのものであり、最後の4番目のcalはprocの動作を処理するためのものである。

私たちは、最初のcall呼び出し時に、ecxレジスタが指す内容はdict 2内部のhash-tableのポインタ、hash-tableの大きさと含まれるkey-valueの個数です。

この呼び出しが完了したら、keyZ 1とkeyZ 2へのポインタが得られます。

そして、2番目と3番目のコールが完了したら、keyZ 1のkeyとvalueは操作スタックに格納されていることが分かります。

第4のコールコールコールでは、プロcの各オペレータに対して、まず対応する処理関数のアドレスを取得し、その後、虚数関数で呼び出します。関連コードのセグメントは以下の通りです。

ここでは、copyの操作に注目しています。分析によると、dict 2内部のhash-tableに対応するすべての「key-value」空間が解放されます。つまり、上記のpNextが指すkeyZ 2空間が解放されました。以下のようにdelete操作を行うための函数の入り口を示します。

このとき、入力ecxレジスタが指す内容には、dict 2のhash-tableポインタが含まれています。次の操作は、keyZ 1~keyZ 8の空間を逐次解放します。最後にhash-tableもリリースされます。

放出されたkeyZ 2空間、すなわちpNextが指す空間は、その後のputtisterval操作で特定の偽造データを書き換えられる。

したがって、forallの次の反復の過程で、pNextポインタによって取得された「key-value」は私たちが偽造したデータになり、その後も同様に操作スタックに格納される。

3脆弱性の利用分析

ここでは、前のセクションの内容に続いて、脆弱性の利用を続けています。この時に偽造された「key-value」はすでに操作スタックに格納されています。以下に示すのは、今回の反復におけるforall操作で処理されたprocコードです。

つまり、操作スタック上のkeyとvalueをそれぞれxxu 19169およびxxu 26500に割り当て、操作が完了した後に得られるxu 19169は以下の通りである。

xx_19169 xx_26500 xx_19169

xxu 19169のtypeフィールドは0 x 0003であり、すなわち整数を表しているので、ここの分析環境にとって、次の処理は「old version」の分岐に従って行われることがわかる。

xx_19169

xxu 26500は、脆弱性の利用を実現するためのキーであり、図18により、そのtypeフィールドが0 x 0000 0500であることが分かり、これはstringタイプであり、value 2フィールドがリークされたポインタであることを示しており、これに基づいて一連の構造を経て、stringオブジェクトは以下の通りである。

xx_26500

PostScriptでは、各stringオブジェクトに対して、実際の文字列コンテンツを格納するための専用のブザーを割り当て、そのアドレスとサイズは、このstringオブジェクトに保存される。最終サンプルの偽造されたstringオブジェクトについては、そのバfferのアドレスは0 x 0000であり、サイズは0 x 7 fffffffffffであるため、このオブジェクトを介して任意のメモリの読み書きが可能である。その後コードは取得したRW prmitivesを通じてROP gadgetsを検索してROPチェーンを作成し、同時にputtisterval操作でshelcodeとpayloadをメモリに書き込みます。

その後、オペレータbytesavailableの処理関数を修正することにより、以下のようなcallポインタがROPチェーンにジャンプします。

ここで、ROPチェーンに含まれるコマンドは、まずStck pivot操作を行い、次にshellcodeのページ属性を実行可能にし、最後にshellcodeの入り口にジャンプすることが見られます。

ここでは、保護プログラムをバイパスしてZwProtectVirtual Memoryに対して呼び出された検出が、ntdlモジュールのNt/Zw関数については、eaxレジスタに付与されたid以外の部分は同じです。ROPチェーンは、eaxの割り当てを完了した後、つまりZwProtectVirtual Memory関数のIDをeaxに割り当てた後、ZwCreateEvent関数(この関数はhookには含まれていません)の最初の5バイトを直接スキップし、残りの部分の命令を実行します。このように任意のシステム呼び出しを実現して、検出されません。

次に簡単にshellcodeを見てみます。ほとんどの場合と同じで、主な役割は関連API関数を取得してから、payloadファイルを作成して実行することです。サンプルのshellcodeの一部のデータは暗号化されていますので、復号の操作があります。

その後、コードはLDRチェーンを検索することによってmsvcrtモジュールのアドレスを取得する。

その後、msvcrtモジュールの導入テーブルから関数Get ModuleHandleAとGetProcAddresのエントリアドレスを取得し、GetModuleHandleA関数によりケネル32モジュールのハンドルを取得し、最後にGetProcAddresの呼び出しにより、下記の導出関数アドレスを一つずつ取得することができます。

続いてpayloadの内容、つまり図19に示すコードの中で先頭文字列「55555555666666」の間のデータは、一時ディレクトリの下のplugin.dllファイルに書き込まれます。これは悪意あるプログラムであることが分かります。

このplugin.dllモジュールをLoadLibraryA関数でロードした後、別のGigfxe.exeというプログラムを一時ディレクトリでリリースします。その役割はリモートファイルを取得して実行することです。

4おわりに

本文はサンプル文書に基づいてCVE-2015-2545の利用を分析しましたが、PostScript言語についてはまだ知られていないので、ある程度の点も徹底的に説明できませんでした。このような脆弱性がもっと多い分析文章が出てくることを期待しています。また、間違ったところはご添削をお願いします。

5参考

[1]The EPS Awakens[2]Microsoft Office Empcapulated PostScript and Windows Prive Escalation Zero-Days[3]Microsoft Office EPSホールを利用した攻撃[4]CVE-2015-2545ホールに関する研究分析[5]文書型エクスプローラ攻撃研究報告[6]CVE-2015-2545 ITW EMET Eastion

本論文はSeebug Paperによって発表されます。転載するなら、ソースを明記してください。本論文の住所:https://paper.seebug.org/368/