SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

Javaのデシリアライズに潜むセキュリティ問題

Apache Commons Collectionsの脆弱性解説

Javaのデシリアライズに潜むセキュリティ問題(前編)

問題の詳細と攻撃の仕組み

 シリアライズ対象のクラスは、受信側のアプリケーションのクラスパス上にも存在する必要があるので、前述のような攻撃は簡単にはできないと考えるかもしれないが、Javaで内部的に利用されているクラスやCommons Collectionsライブラリに含まれる特定のクラスを使うことで実現が可能である。

図2 Commons Collectionsライブラリを使った攻撃の概要
図2 Commons Collectionsライブラリを使った攻撃の概要

 以下、報告者によって公開されている攻撃の仕組みについて、詳細に説明する。

 Commons Collectionsライブラリにはリフレクションの機能を持つInvokerTransformerクラスがあるが、本クラスを用いて、複数のGadget(メモリに読み込み済みのコード)を連鎖させて、任意のコードを実行するGadget Chainを生成することが可能となる。このような手法はProperty-Oriented-Programingと呼ばれている。

Gadget Chainの例

Runtime.getRuntime().exec(new String[]{ "calc.exe" }); を実行するGadget Chain
final String[] execArgs = new String[] { "calc.exe" };
final Transformer[] transformers = new Transformer[] {
        new ConstantTransformer(Runtime.class),
        new InvokerTransformer("getMethod", new Class[] {
            String.class, Class[].class }, new Object[] {
            "getRuntime", new Class[0] }),
        new InvokerTransformer("invoke", new Class[] {
            Object.class, Object[].class }, new Object[] {
            null, new Object[0] }),
        new InvokerTransformer("exec",
            new Class[] { String.class }, execArgs),
        new ConstantTransformer(1) };
final ChainedTransformer transformerChain = new ChainedTransformer(transformers);
// 上記transformerChainに対してtransform() を実行すると、Gadget Chain が実行される

 Commons Collectionsライブラリは、Java標準のMapを継承したLazyMapというコレクションを提供しているが、LazyMapはInvokerTransformerのインスタンスを保持し、getメソッド内の処理でGadget Chainを実行している。readObjectメソッド内の処理でMapを使っているAnnotationInvocationHandlerクラス(注1)に対し、MapのインスタンスにLazyMapを設定し、getメソッドを呼び出すように細工することで、AnnotationInvocationHandlerのデシリアライズ時にInvokerTransformerを呼び出すことができる。

 攻撃者は、前述の仕組みを使用して任意のコマンドを実行するGadget Chainを実行するように細工したうえで、AnnotationInvocationHandlerクラスをシリアライズして送信する。受け取り側でデシリアライズすると、Commons Collectionsライブラリがクラスパス上に存在する環境であれば、攻撃者がGadget Chainで定義した処理が実行され、任意のコード実行が成立してしまう。

 なお、公開されている攻撃手法では、InvokerTransformerやLazyMap、AnnotationInvocationHandlerクラスなどが使われているが、他にも任意のコードを実行するGadget Chainが生成可能なクラスが存在し、何らかの方法でデシリアライズ時に呼び出すことが可能な場合は、新しい攻撃手法が公開される可能性も考えられる。

 また、本攻撃手法が用いられた場合、デシリアライズの過程で任意のコードが実行されるので、デシリアライズ後にオブジェクトのチェックを行っても、防ぐことができない。攻撃を防ぐためには、デシリアライズ前に意図したクラスであるかを検証する必要があり、これについては連載の次回で説明する。

図3 Commons Collectionsライブラリを使った攻撃の詳細
図3 Commons Collectionsライブラリを使った攻撃の詳細

 また、前述した手法で、攻撃用のシリアライズされたデータを簡単に作成できるツールがインターネットに公開されている。攻撃者は、本問題の影響を受けるアプリケーションとの通信をキャプチャリングすることにより、シリアライズされたデータをやりとりしているペイロードを見つけ出し、攻撃用のデータにすり替えることで比較的簡単に攻撃を行える可能性がある。

注1

 Java標準のクラスだが、APIとして公開されていない内部的に利用されているクラス。

次のページ
Apacheの対処と見解

この記事は参考になりましたか?

Javaのデシリアライズに潜むセキュリティ問題連載記事一覧

もっと読む

この記事の著者

藤本 万里子(JPCERT コーディネーションセンター)(フジモト マリコ)

一般社団法人JPCERTコーディネーションセンター 早期警戒グループ 情報セキュリティアナリスト。前職では、国内企業においてソフトウエアの開発や内部統制のためのシステム開発等を担当。 2015年4月、JPCERTコーディネーションセンター早期警戒グループに情報セキュリティアナリストとして着任。主に国...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/9150 2015/12/11 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー