先月あたりに話題になっていたJavaの脆弱性について解説した記事を眺めてみたのでメモ。 POCへのリンクもあるので文章で書かれたことがどういうコードになるのかがなんとなくわかりました。
CERT/CC Blog: Anatomy of Java Exploits
自分が理解できた(つもり)のは以下のとおり。
- 背景
- Javaには信用できない(untrusted)コードの実行を制限する機能が存在する
- 一番重要なのは SecurityManager クラス。 System.{set,get}SecurityManagerで操作できる
- SecurityManagerはデスクトップ環境などでは通常nullに設定されていて、特に実行を制限しない
- アプレットなどではセキュリティポリシーにしたがってファイルアクセスなどを制限するよう設定されている
- 許可されていないコードを実行しようとするとSecurityExceptionが発生して終了する
- Javaには信用できない(untrusted)コードの実行を制限する機能が存在する
クラスローダやリフレクションAPIなどを信用できないコードから実行することは制限されていますが、 脆弱性を利用するとこれらの制限を回避できてしまうようです。
以下の2つを達成することで、任意のコードを実行できるようになるようです。
- sun.org.mozilla.javascript.internal.{Context, GeneratedClassLoader} クラスへのハンドルを取得する
- 上記クラスを使いdefineClassで動的にセキュリティ機能を無効化する処理を行うクラスを定義する
- System.securityManagerをnullにする
- sun.org.mozilla.javascript.internal.{Context, GeneratedClassLoader} クラス
- セキュリティ機能によるアクセス制御が行われているがprivate宣言されていない
- アクセス制御が行われていない com.sun.jmx.mbeanserver.MBeanInstantiator クラスの findClass を経由して取得できる
- java.lang.invoke.MethodHandles.Lookup クラス
- 直接クラスローダーを作成しようとするとSecurityManagerに阻止されるので、このクラスを経由する
- コンストラクタやメソッドのハンドルを取得できる
- 通常、リフレクションAPIはセキュリティ機能により呼び出し元(caller)が信用できるかどうかを確認している
- java.lang.invoke.MethodHandles.Lookupは脆弱性により信用できる呼び出し元だと判断されてしまう
0 件のコメント:
コメントを投稿