この脆弱性は、Aleksandar Nikolic によって検出されました。
ブログ記事執筆者:Jaeson Schultz および Aleksandar Nikolic
多くのソフトウェア プログラムで実行される基本的なタスクの中には、ファイルの読み取り、ファイルへの書き込み、その他ファイルに対する一般的な処理が含まれています。ネットワーク化が進んだ現代の環境では、こうした処理を行うファイルやプログラムがあらゆる場面で使用されています。FTP 転送、HTTP フォームのアップロード、電子メールの添付ファイルなどがその例です。
コンピュータ ユーザがさまざまな種類のファイルを始終やりとりしているという状況の下、Oracle Corporation は、こうした日常のタスクをサポートするソフトウェアを開発するプログラマーを支援するために Outside In Technology(OIT)というツールを設計しました。OIT の Web サイトでは、このツールについて、「Outside In Technology は、600 種類の非構造化フォーマットのコンテンツの抽出、正規化、スクラビング、変換、および表示のための包括的なソリューションを開発者に提供するソフトウェア開発キット(SDK)スイートです」と説明しています。
今年の 4 月、Talos はブログで OIT に関連した任意のコードが実行されるバグを報告しました。このバグに対しては Oracle からパッチが提供されています。Oracle の OIT は、非常に多くのサードパーティ製品でファイルの解析や変換に使用されています。そのため、4 月に報告された脆弱性と、今回新たに報告される 18 件の OIT のバグの影響は深刻です。OIT に関連した、2016 年 1 月の CERT 勧告のレビューでは、セキュリティおよびメッセージング関連の製品を中心に、影響を受ける多数のサードパーティ製品のリストが公開されています。CERT によると、Oracle の Outside In SDK に依存している製品には以下のものがあります。
- Avira AntiVir for Exchange:Microsoft Exchange 用のウイルス対策
- IBM WebSphere Portal:企業用の Web ポータルを提供
- Google Search Appliance:1 つの検索ボックスで 1 つの企業のすべてのコンテンツを検索
- Guidance Encase:フォレンジック用ソフトウェア
- Microsoft Exchange:企業用の電子メールおよび生産性向上のためのソフトウェア
- Novell Groupwise:大規模な企業向けコラボレーション ツール
- Raytheon SureView:企業の可視性およびユーザ アクティビティのモニタリングのために設計されたソフトウェア
- Veritas(Symantec)Enterprise Vault:アーカイブを利用した情報ガバナンスのためのプログラム
Talos は、上記のサードパーティ製品に対する影響をすべて確認しているわけではありませんが、これらの製品の一部で OIT 関連の脆弱性のあるコードが実行されていることは確認しました。たとえば、Microsoft Exchange 2013(またはそれ以前)で WebReady Document Viewing が有効になっている場合、攻撃者が攻撃対象者に悪意のある電子メール添付ファイルを送り、対象者が Web プレビューを使用して電子メールを開くと、攻撃者はこれらの脆弱性を利用できる可能性があります。
さらに、Data Loss Prevention が有効になっている場合、悪意のあるファイルが添付された電子メールを影響を受けた Exchange サーバから送信するだけでこの脆弱性がトリガーされます。Avira AntiVir for Exchange(v12.0.2775.0 およびそれ以前)が導入されている場合は、悪意のある電子メールを送受信するだけで脆弱性がトリガーされます。これは、このプログラムが送受信されるすべての電子メールをスキャンするためです。加えて、さらに攻撃の効果をあげるために、OIT の複数の脆弱性が連鎖的に利用されることも考えられます。そのため Talos はユーザの皆さまに、これらのベンダーを直接フォローアップして、こうした脆弱性の影響が及ぶ範囲に関する詳細情報を入手することをお勧めします。
目次
- PDF での /Size の整数オーバーフロー
- TIFF での ExtraSamples コードの実行
- TIFF での Photometric Interpretation コードの実行
- GIF での ImageWidth コードの実行
- Gem_Text コードの実行
- PSI ファイルでの整数オーバーフロー コードの実行
- Word での DggInfo コードの実行
- Mac Works Database での VwStreamSection コードの実行
- Mac Word での ContentAccess libvs_word+63AC コードの実行
- BMP でのヒープ バッファ オーバーフローおよびコードの実行
- Mac Works での VwStreamReadRecord によるメモリ破損
- PDF での /Kids の情報の漏洩
- PDF での NULL ポインタの逆参照による Denial of Service(DoS)
- PDF での再帰呼び出しに起因するスタック オーバーフローによる Denial of Service(DoS)
- PDF での /FlateDecode および /Colors による Denial of Service(DoS)
- PDF での /Type および /Xref による Denial of Service(DoS)
- PDF での Xref のオフセットによる Denial of Service(DoS)
- Mac Word での ContentAccess libvs_word による Denial of Service(DoS)
- まとめ
1. PDF での /Size の整数オーバーフロー
Talos-2016-0097(CVE-2016-3575)
trailer オブジェクトは、「ファイル本文内の相互参照テーブルと、特定の特別なオブジェクトの場所」を示します。この中には、/ID、/Root、/Size、/Info のような、いくつかのフィールドがあります。/Size には、PDF 内のオブジェクトの数が格納されます。
/Size の値が大きいと、Oracle OIT PDF パーサーで問題が発生する原因となります。Oracle のパーサーは整数オーバーフローをチェックしますが、チェック後、結果に 4 を乗じて(左シフト)、先のオーバーフローのチェックで提供された保護をすべて無効にします。
.text:B74ECE59 mov edi, eax [1]
.text:B74ECE5B shl edi, 4 [2]
.text:B74ECE5E mov [esp+6BCh+s], edi
.text:B74ECE61 call _SYSNativeAlloc [3]
.text:B74ECE66 mov edx, [esp+6BCh+arg_10]
.text:B74ECE6D mov [edx+1D6Ch], eax [4]
.text:B74ECE73 test eax, eax.text:B74ECE75 jz loc_B7
[1] では、/Size 要素を丸めた 32 ビットの値が「eax」の値にそのまま渡されます。[2] でこの値に 4 が掛けられるため、先に行われた整数オーバーフローのチェックが無効化されます。[3] で「malloc」ラッパーが呼び出され、返されたポインタが [4] で保存されます。/Size の値が巧妙に設定されている場合、[2] の最初のブロックで整数オーバーフローが発生するため、[3] では小さな値が SYSNativeAlloc に渡されます。丸め処理が原因で、ヒープ アロケータが要求より大きなヒープ チャンクへのポインタを返すと問題が発生します。
たとえば /Size 値が 0x10000001 に指定されている場合、これは割り当ての前のチェックをパスしますが、この値は 4 つシフトされることで 0x10 となり、割り当ては小さくなります。基になるアロケータによっては、割り当てられたチャンクの実際のサイズはもっと大きくなります。Linux の場合、返されるチャンクの長さは 24 バイトになり、後続の「memset」は最初の 16 バイトのみを初期化します。このバッファの最初の 16 バイトのみが初期化された場合、このコードは、ゼロに初期化されていないメモリにアクセスします。初期化されていないメモリに残っているデータによってメモリが破損し、コードが実行される恐れがあります。
2. TIFF での ExtraSamples コードの実行
Talos-2016-0103(CVE-2016-3581)
TIFF ファイルも、リモート コードの実行を招く脆弱性の原因となる可能性があります。Oracle OIT SDK のこの脆弱性が原因で、イメージ ファイル ディレクトリ(IFD)内にある「ExtraSamples」タグの付いた TIFF ファイルを解析する際に、ヒープでのメモリの割り当てが不足します。この場合、ImageWidth、SamplesPerPixel、BitsPerSample、ExtraSamples の各値は TIFF ファイルに対する標準と見なされますが、ExtraSamples を含めることが、脆弱性がトリガーされる要因になります。割り当て時にビットは追加されないため、ExtraSamples タグを含めることで、ヒープ ベースのオーバーフローの発生を招く可能性があります。
3. TIFF での Photometric Interpretation コードの実行
Talos-2016-0104(CVE-2016-3582)
1992 年、TIFF ファイル形式の仕様が更新され、新しい画像タイプに対応するために、いくつかの拡張機能が追加されました。TIFF ファイルがサポートする画像タイプは、元々は白黒、グレースケール、RGB、およびパレット色の 4 つのみでした。更新された TIFF の仕様では、新たに CMYK(色分解)の画像タイプが含まれるようになりました。TIFF の画像タイプの指定には、「PhotometricInterpretation」というフィールドが使用されます。「PhotometricInterpretation」のレベルが 5(CMYK/色分解形式)に設定されている TIFF ファイルは、他の設定の場合と異なり、Oracle SDK が代替コード パスを選択する原因となります。この代替コード パスにより、チェック対象外の割り当てで ImageWidth 値が使用できるようになるため、最終的にはヒープのオーバーフローが発生する原因になります。
4. GIF での ImageWidth コードの実行
Talos-2016-0105(CVE-2016-3583)
PDF や TIFF ファイルに加えて、GIF ファイルも危険を招く可能性があります。ImageWidth 値は特定の GIF ファイルの絶対的な幅を示す値であり、同じファイル内にある Logical Screen Width 値より小さくなければなりません。Oracle Outside In SDK のこの脆弱性は、Image Descriptor ブロック内で ImageWidth が 0xFFFF に設定されている GIF を解析するとトリガーされます。0xFFFF に設定された ImageWidth は整数オーバーフローをトリガーし、libvs_gif.so 内の同じ関数にある 2 つのブランチで境界外のメモリへの書き込みが発生する原因となります。
5. Gem_Text コードの実行
Talos-2016-0162(CVE-2016-3595)
GEM メタファイルは、ベクター描画プログラムである Gem Draw に画像をレンダリングするための指示を含んだファイルです。Oracle Outside In Technology の libim_gem2 ライブラリのファイル解析コードには、整数オーバーフローの脆弱性が存在します。Gem メタファイルのデータが解析される際には、チェック対象外のメモリ割り当てが実行されます。その結果、巧妙に細工された Gem ファイルが整数オーバーフローをトリガーすることで、ヒープ ベースのバッファ オーバーフローが複数発生し、さらにリモート コードが実行される可能性があります。
6. PSI ファイルでの整数オーバーフロー コードの実行
Talos-2016-0161(CVE-2016-3594)
Oracle Outside In Technology の libim_psi2 ライブラリには、解析処理の脆弱性が存在します。具体的には、整数オーバーフローのことであり、これにより、大規模なメモリ割り当てが発生し、大きなサイズのメモリ コピーが行われます。PSI 画像ファイルの解析時、2 バイト サイズのフィールドの読み取りが行われ、符号が拡張されます。次に、この値はメモリの割り当てで使用され、さらに「memmove」の呼び出しで使用されます。読み取りサイズはメモリ領域が割り当てられる前に 8 バイト増やされますが、「memmove」の呼び出しでは元のサイズが使用されます。
7. Word での DggInfo コードの実行
Talos-2016-0160(CVE-2015-6014) *2016 年 1 月に修正済み
巧妙に細工された DggInfo 要素を持つ不正な形式の OLE ファイルを解析する際に、Escher の描画解析ライブラリである libvs_eshr に存在する脆弱性がトリガーされる可能性があります。DggContainer の最初の子要素の ID が 0xF006(Dgg)から 0xF007(BSE)に変更されるとパーサーが混乱し、最終的には、ファイルの 4 バイトの値が「cmp」命令でポインタとして使用されます。比較が失敗すると、同じポインタが間接的な「call」命令で使用されることから、任意のコードの実行を招きます。
8. Mac Works Database での VwStreamSection コードの実行
Talos-2016-0159(CVE-2016-3593)
Mac Works Database 文書の解析時に、ファイル内のバイトから読み取った値がカウンタの上限に設定されたループ内でメモリが書き込まれます。演算処理の後にサイズのチェックは行われないため、境界外のメモリへの書き込みが発生する可能性があります。
9. Mac Word での ContentAccess libvs_word+63AC コードの実行
Talos-2016-0158(CVE-2016-3592)
Mac Word 文書の解析時に、ファイルのシングルバイト値がカウンタの開始値として使用されます。この開始値は、メモリ アクセスのための演算処理で使用されます。この演算処理の後にサイズのチェックは行われないため、境界外のメモリに 4 バイトの書き込みが行われる可能性があります。
10. BMP でのヒープ バッファ オーバーフローおよびコードの実行
Talos-2016-0163(CVE-2016-3596)
巧妙に細工された ICO ファイルを解析する際に、ビットマップの幅を指定する、チェック対象外の値がメモリ書き込み処理のサイズの計算に使用されます。圧縮メソッドは 0x01 または BI_RLE8 に設定されている必要があります。このファイルの読み取りを行う際に、ヒープ上のメモリの一部が実質的にゼロで上書きされます。この上書きのサイズはチェック対象外であり、ビットマップの幅がそのまま使用されます。これにより、ヒープ データ構造が NULL バイトで上書きされる可能性があり、その場合、境界外への NULL バイトの書き込みにより関数ポインタが上書きされ、クラッシュが発生します。この上書きのサイズを巧妙に調整することで、ヒープ上の関数ポインタを操作して、任意のコードを実行することができます。
11. Mac Works での VwStreamReadRecord によるメモリ破損
Talos-2016-0157(CVE-2016-3591)
Mac Works Database 文書を解析する際に、宛先アドレスの計算で使用された値をカウンタに使用したループ内でメモリが書き込まれます。この演算処理の後にサイズ チェックは行われないため、部分的に制御された 2 バイトの上書きが行われる可能性があります。
脆弱性は、libvs_mwkd.so ライブラリ(イメージベース 0xB7F89000)の「VwStreamReadRecord」関数に存在します。具体的には、下記の基本ブロックで開始されます。
.text:B7F8ACF6 movzx eax, [esp+3Ch+var_12]
.text:B7F8ACFB mov edx, [edi+31Ch]
.text:B7F8AD01 mov ecx, ebp
.text:B7F8AD03 mov [edx+eax], cl
.text:B7F8AD06 movzx eax, word ptr [esp+3Ch+var_10] [1]
.text:B7F8AD0B movzx esi, [esp+3Ch+var_12] [2]
.text:B7F8AD10 mov [edi+eax*2+298h], si [3]
.text:B7F8AD18 add word ptr [esp+3Ch+var_10], 1
.text:B7F8AD1E add esi, 1
.text:B7F8AD21 mov [esp+3Ch+var_12], si
.text:B7F8AD26 cmp bp, 0F9h
.text:B7F8AD2B ja loc_B7F8AE1A
.text:B7F8AD31 test bp, bp
.text:B7F8AD34 jz loc_B7F8ADEB
.text:B7F8AD3A mov [esp+3Ch+var_1A], 0
.text:B7F8AD41 jmp short loc_B7F8AD71
[1] と [2] では、事前に計算された「eax」および「esi」の値がスタックから読み取られ、ゼロ拡張されます。[3] では、「eax」が宛先アドレスの計算に使用され、「si」の値がここに書き込まれます。「eax」および「esi」の初期値は関連付けられており、「eax」がカウンタとして機能します。範囲のチェックが実行されないことが原因で、境界外に2 バイトの書き込みが行われる可能性があります。
巧妙に細工されたファイルを使用することで、解放されるはずのポインタを攻撃者が制御する領域に移動でき、その領域を使用して「free()」を無効化して、コードを実行できる可能性があります。
12. PDF での /Kids の情報の漏洩
Talos-2016-0096(CVE-2016-3574)
PDF 文書のページに対するアクセスは、ページ ツリーから行われます。ページ ツリーには文書のすべてのページが定義されています。一般に、ページ ツリー内の各ノードには、/Type、/Parent、/Kids、/Count のエントリが含まれています。/Kids の参照は、現在のノードから直接アクセス可能なすべての子ノードを指定するためのものです。
ただし、Oracle OIT の PDF パーサーが /Kids の参照を処理する仕組みの中に脆弱性が存在します。不正な形式の /Kids 参照を含んだオブジェクトを持つ PDF ファイルを解析すると、参照の配列が配置されるべき、/Kids 要素の直後の値が文字列として解釈されます。これにより、パーサーがポインタを参照した際、ファイルからコピーされた文字列が配置されているため、任意の読み取りアクセス違反が発生します。正しい形式の PDF ファイルでは、少なくとも 1 つの参照の配列が、/Kids 要素の後に続く必要があります。libvs_pdf.so(ベース アドレス 0x0xB74BF000)にあるこのバグを以下に示します。
.text:B74E71DB mov eax, [eax] [1]
.text:B74E71DD mov edi, [esp+5Ch+var_24]
.text:B74E71E1 mov eax, [eax+edi*4] [2]
.text:B74E71E4 mov [esp+5Ch+var_4C], eax
.text:B74E71E8 mov ecx, [esp+5Ch+var_34]
.text:B74E71EC mov edx, [esp+5Ch+var_48]
[1] では、「eax」が、ファイルからヒープにコピーされた文字列をポイントしています。[2] で、この文字列の最初の 4 バイトがメモリ アクセスの計算で使用されることにより任意の読み取りアクセス違反が発生します。[2] で計算された値が、有効なメモリをポイントする場合、制御されたアドレスでの読み取りが成功します。ただし、/Kids 要素の後の値が純粋な整数の場合は、異なるコード パスがとられ、この整数値がポインタとして解釈されるため、以下のように完全に制御された任意の読み取りが行われます。
.text:B74E718A mov eax, [esp+5Ch+var_18]
.text:B74E718E mov eax, [eax]
.text:B74E7190 xor edx, edx
.text:B74E7192 mov edi, [eax+4] [1]
.text:B74E7195 test edi, edi
.text:B74E7197 jz loc_B74E72A2
13. PDF での NULL ポインタの逆参照による Denial of Service(DoS)
Talos-2016-0098(CVE-2016-3576)
巧妙に細工された PDF 文書を解析する際に NULL ポイントの逆参照が発生し、プロセスが終了します。パーサーは /FlateDecode でエンコードされたストリーム データのデコードに成功した後、データに含まれる演算子を実行します。ストリーム内に含まれたテキストで「Tj」演算子が実行されると、メモリ構造(通常、文字セットのマッピングを含む)が参照されます。NULL ポインタ チェックは行われず、さらにこの構造はゼロで初期化されているため、クラッシュが発生する可能性があります。
14. PDF での再帰呼び出しに起因するスタック オーバーフローによる Denial of Service(DoS)
Talos-2016-0099(CVE-2016-3577)
PDF 文書階層のルートはカタログ ディクショナリであり、PDF ファイルの Trailer オブジェクトで /Root エントリによって見つけることができます。カタログ ディクショナリには /Catalog タイプが必要です。不正な形式の PDF ファイル(不正な形式の xref テーブルがあるか、xref テーブルのない /Root 要素への参照を含む)が解析されると、ある関数への再帰呼び出しで毎回同じパラメータが使用されます。これにより、最終的にプロセス スタックが枯渇しクラッシュが発生します。
15 .PDF での /FlateDecode および /Colors による Denial of Service(DoS)
Talos-2016-0100(CVE-2016-3578)
/FlateDecode でエンコードされたストリームが含まれており、/Predictor が 1 以外の値に設定されている PDF ファイルを解析すると、/Colors の不正な形式の値によって libsc_ut.so ライブラリで NULL ポインタへの逆参照が行われ、デコーダの初期化が行われません。
16. PDF での /Type および /Xref による Denial of Service(DoS)
Talos-2016-0101(CVE-2016-3579)
ストリームが含まれたオブジェクトを持つ PDF ファイルを解析する場合、オブジェクト タイプが指定されていないと、任意のポインタへのアクセスが行われる可能性があります。/Type 要素の後の ASCII 整数値は 32 ビット整数に変換され、その値が比較演算でポインタとして使用されます。このポインタが無効な場合はプロセスがクラッシュします。
17. PDF での Xref のオフセットによる Denial of Service(DoS)
Talos-2016-0102(CVE-2016-3580)
OIT SDK の PDF パーサーに存在する脆弱性により、特定の状況下でチェック対象外のメモリ割り当て処理が行われた後に、ヒープ メモリ境界外へのアクセスが発生します。
PDF ファイル内には複数行の xref テーブルがあり、各行には 3 つの値が含まれています(ただし、1 行目は例外で、この行では最初に参照されるオブジェクトと、オブジェクトの数が指定されています)。最初の値は、オブジェクトが検出されるファイル内の 10 桁のオフセットを表しています。巧妙に細工された PDF ファイルでは、OIT PDF パーサーは指定された値を「realloc()」への呼び出しでパラメータとして使用し、この呼び出しが失敗します。エラーの戻り値はチェックされてもその後は使用されません。すると、元の数値がループの上限として使用され、プロセスのクリーンアップ中に境界外の読み取りが発生します。
18. Mac Word での ContentAccess libvs_word による Denial of Service(DoS)
Talos-2016-0156(CVE-2016-3590)
Mac Word 文書の解析時にファイルのシングルバイト値がカウンタの最大値として使用されます。この値は、メモリ アクセスのための演算処理で使用されます。演算処理の後にサイズのチェックは行われないため、境界外のメモリへのアクセスが発生する可能性があります。計算されたメモリ アドレスは「or byte」命令で宛先オペランドとして使用されます。
まとめ
信頼できないデータが、適切な検証や必要な検証を行わずにソフトウェアの入力データとして使用されることが原因の問題が繰り返し何度も確認されています。また、すべてのソフトウェア開発者が多数存在するファイル形式に精通しているとは限らないため、こうした開発者たちは Oracle OIT のような SDK に頼ることを余儀なくされています。しかし、残念なことに、サードパーティによって利用されている SDK で検出される脆弱性のために、修正に想定外の時間が費やされているのが実情です。最初に SDK を保守している組織が修正版を公開し、その後しばらくしてから、その SDK を利用しているサードパーティによってそれらの修正版を含む更新が顧客に提供されています。犯罪者はこのような状況を利用し、サードパーティ製品の脆弱性を不正利用できる時間を確保しているのです。
本稿は 2016年7月20日にTalos Group のブログに投稿された「Vulnerability Spotlight: Oracle’s Outside In Technology, Turned Inside-Out」の抄訳です。