はじめに
11月、Foxglove Securityの研究者が、Apache Software Foundationが提供するJavaライブラリCommons Collectionsを使用して、同ライブラリを同梱しているアプリケーションサーバを攻撃する手法をインターネットで公開した。
Commons Collectionsライブラリは、WebSphere、WebLogic、JBossなどのアプリケーションサーバの他、Javaアプリケーションで広く利用されており、本脆弱性は大きな話題となった。Java開発者の方であれば、すでに耳にしていらっしゃることだろう。
本件は、本質的にはライブラリの利用者側がデシリアライズ処理をセキュアに実装していないことに起因し、単にライブラリの修正プログラムを適用するだけでは、根本的な対処とならない。
本記事では、開発者の皆さまが本問題を正しく理解して、本質的な対策をとっていただけるよう、問題や攻撃の仕組みについて技術解説する。
問題の概要
概要については、さまざまな記事になっているためご存じかと思うが、オブジェクトのデシリアライズ時に任意のコードを実行できてしまうという問題である。詳細についてはJVNVUなどを参照いただきたいが、影響を受ける条件は、以下2点である。
- Commons Collectionsライブラリ v3系またはv4系がクラスパス上に存在すること
- シリアライズされたオブジェクトを外部から受けとっていること
注意すべきは、明示的にCommons CollectionsライブラリのAPIを使っていなくても、ライブラリがクラスパス上に存在するだけで影響を受ける点だ。理由については後述する。
攻撃者は、細工したオブジェクトをシリアライズして前記条件を満たすアプリケーションなどに送信することで、受信側のサーバ上で任意のコードを実行することができる。シリアライズされたオブジェクトを受け取るサービスがインターネットからアクセス可能な場合は、遠隔から攻撃が可能である。
攻撃の仕組みを解説する前に、まずは本問題を説明する上でキーとなるシリアライズ、デシリアライズについて簡単に説明しよう。
シリアライズ・デシリアライズとは
シリアライズとは、プログラムで扱うオブジェクトの状態を保持したまま送受信したり、ファイルへ読み書きを行ったりするために、オブジェクトをバイト列などに変換することである。デシリアライズはその逆だ。シリアライズ時には、対象オブジェクトから参照されているオブジェクトもまたシリアライズ対象となる。ポイントは、デシリアライズ時にデシリアライズ対象クラスが実装しているreadObjectメソッドが実行されるところにある。対象オブジェクトから別のオブジェクトを参照している場合は、各オブジェクトのreadObjectメソッドが順次実行され、オブジェクトが復元される。
攻撃者はこれを悪用し、readObjectメソッドが実行された際にRuntime.exec()などを使ってOSコマンドなどを実行するように細工する。
それでは、攻撃の仕組みについて詳しく見ていこう。