
この投稿では、このリストの別の脆弱性について詳しく説明します。 この脆弱性には識別子CVE-2014-4113が割り当てられており、サポートされているすべてのバージョンのWindows(2k3 +)のwin32k.sysドライバーに存在します。 この脆弱性により、許可されていない(OSの制限を回避する)カーネルモードコードを実行し、エクスプロイトによって起動されたアプリケーションの権限を最高レベル(SYSTEM)に高めることができます。 CVE-2014-4113は、10月のパッチ火曜日の一部としてMS14-058更新プログラムによって閉じられ、64ビットバージョンのエクスプロイトがWin64 / Dianti.Aとしてデータベースに追加されました。
過去数年にわたるWin32k.sys自体は、特権の昇格(またはLocal Privelege Escalation、LPE)などの脆弱性を探すための真の宝石でした。 2013年のレポートでは、OSのこのコンポーネントは、年間を通じて修正された脆弱性の数で2番目にランクされていることがわかりました。 これは、多数の実行可能ファイルで構成されるInternet Explorer製品の先にありますが、win32k.sysの場合、ファイルは1つしかありません。
Win32k.sys自体は既に2回以上記述されています。これは、カーネルモードで動作するWindowsサブシステムの一部であり、Windows GUIインターフェイスの実装と、入力デバイスを介したユーザーとの対話に関連するロジックとメカニズムを担います。 遠い過去に、Windows NTがWindows 2000(NT 5.0)、Windows XP(NT 5.1)など、そして今ではWindows 10(NT 6.4)として記憶されている歴史になったとき、GUIサブシステム全体ユーザーモードで動作し、画面への表示、キーボードメッセージの処理などに関連する操作中にプロセスコンテキストを切り替えるために多くのオーバーヘッドが必要でした。
次に、NT 4.0では、win32k.sysカーネルモードドライバーがパフォーマンスを改善し、コンテキスト切り替えのオーバーヘッドを削減するように見えました。 GUIサブシステムのロジックは、ユーザーモードで動作する部分(既知のライブラリuser32.dllおよびgdi32.dll)と、win32k.sysドライバーの形式のカーネルモードの部分に分けられました。 おそらくそれがwin32k.sysに非常に多くのバグがある理由であり、ドライバーコードはいくつかの場所でユーザーモードライブラリからコピーされる可能性があります。 さらに、ポインターを返すはずのドライバー関数は、定数、つまりポインターとして解釈できない値も返すことができるように実装されました。
Windowsでは、カーネルモードコードは特別なメカニズム(API)を介してのみ実行できます。これは、このようなコードがすべてのOSソフトウェアおよびハードウェアリソースへのフルアクセスを許可されているためです。 脆弱性win32k.sysにより、攻撃者は何らかの方法でこれらの制限を回避し、エクスプロイトを介してカーネルモードコードを実行できます。
CVE-2014-4113の場合、win32kの特別なシステム構造( win32k!Tagwnd )を作成し、それをカーネルモードに投影し、ドライバー関数の1つにこの生成された構造からコールバックを呼び出すことができるという事実について話します。 脆弱性自体は、ドライバー関数の1つ( xxxHandleMenuMessages )が、他の関数( xxxMNFindWindowFromPoint )(想定されるポインター)によって返される値をチェックせず、間違った値で動作している別の関数( xxxSendMessage )に渡すことです。 blog.trendmicro.com/trendlabs-security-intelligence/an-analysis-of-a-windows-kernel-mode-vulnerability-cve-2014-4113を参照してください。
32ビット版
このエクスプロイトの32ビットバージョンの場合、整数引数オーバーフローが使用され、これはxxxHandleMenuMessagesからxxxSendMessage関数に渡されます。 この渡された引数自体は、 xxxHandleMenuMessages関数によって、ポインターとして、またはxxxMNFindWindowFromPoint関数によってエラーが返された場合の負の値として解釈されます。 xxxHandleMenuMessagesで負の値(エラー)をチェックしないため、この関数はxxxSendMessageへのポインターの代わりにこの値を渡します。
一般的に、エクスプロイトはエクスプロイトのために次の手順を適用します。
- ntdll!ZwAllocateVirtualMemory関数を使用して、メモリページをゼロアドレスに割り当てます。
- このページは、エクスプロイトコールバック関数(シェルコード)へのポインターを初期化することにより、偽のwin32k!Tagwnd構造を作成します。
- これは、脆弱性の操作、つまり、誤った引数(0xfffffffb、-5)をxxxSendMessage関数に転送するための条件を作成します。これにより、ポインターが逆参照され、ゼロページでメモリがアクセスされたときに整数オーバーフローが発生します。 つまり、 xxxSendMessage関数がコールバック関数のポインターフィールドにアクセスすると、予期されるアドレスのオーバーフロー(0xfffffffb + 0x60)が発生し、その結果、関数はシェルコードへのポインターを受け取ります。
- 操作の結果として、コントロールは、システムプロセスのアクセストークンを指すように、現在のプロセスのEPROCESSカーネルオブジェクトの構造内のアクセストークンへのポインターを書き換えるシェルコードを受け取ります。 後で、これにより、エクスプロイトによって作成されたプロセスがシステムプロセスのアクセストークンを継承し、システムで最大の権限を取得します。
したがって、操作の準備は、次の機能を実行するために削減されます。

図 32ビットシステムの脆弱性を悪用する準備をしています。 ゼロページのアドレスを選択するには、すでに一般的な呼び出しZwAllocateVirtualMemoryを使用します。これには、アドレスとして1が渡されます。これにより、予約アドレスのページアライメントがゼロになります。 この「機能」は、Windows 7ではMS13-031の更新プログラムによって閉じられ、Windows 8以降ではこの更新プログラムはデフォルトで有効になっています。 関数の開始時に、エクスポートされていないuser32! PtiCurrent関数が呼び出され、Win32ThreadInfo構造体へのポインターが返されます。 このポインターは、win32k!_THRDESKHEAD.pti構造体フィールドを初期化するために使用されます。
64ビットバージョン
64ビットの仮想アドレス空間では、整数のオーバーフローの代わりに、メモリ内の指定されたアドレスでメモリ割り当てを使用します。 つまり、返される定数自体は、 fnFillmalicioustagWnd関数で満たされるメモリページを予約するときにアドレスとして使用されます(下のスクリーンショットを参照)。

図 これは、Windows 7 x64でtagWNDがどのように見えるかです。 シェルコードを指すコールバック関数へのポインターは赤でマークされています。

図 現在のプロセスのEPROCESSのアクセストークンへのポインターの置換を実行するシェルコード関数。

図 偽のtagWND構造を作成する関数。 構造体の最初のフィールドを埋めるために、 Win32ThreadInfoへの取得されたポインター( user32!PtiCurrent )が使用されます。

図 fnPrepareExploitation関数の一部。 x64では、返された定数、つまり0xFFFFFFFBのポインターによってメモリページがバックアップされます。
準備措置が完了した後、エクスプロイトは運用フェーズに進みます。つまり、脆弱性が機能するための条件を作成します。 これを行うために、メニューコントロールを使用したさまざまな操作とウィンドウトラップの設定が使用され、最終的にwin32kの脆弱な関数がポインターではなく定数を返すようにします。 次に、 CreateProcessA関数を使用してプロセスが作成されます。

図 悪用の結果、子コマンドラインプロセスはシステムアクセストークンを継承しました。
Windows 8以降のx32およびx64では、この脆弱性の悪用は不可能であることに注意してください。 32ビットバージョンでは、NULLポインターによるメモリ割り当てに対する保護がデフォルトで存在し、64ビットバージョンでは、ユーザーモードのページからのカーネルモードでのコードの実行はSMEPメカニズムによってブロックされます。