▼2015年12月18日金曜日Joomla!の「ゼロデイコード実行脆弱性」はPHPの既知の脆弱性が原因Joomla!にコード実行脆弱性(CVE-2015-8562)があり、パッチ公開前から攻撃が観測されていたと話題になっています。「Joomla!」に再び深刻な脆弱性、3.4.6への速やかなアップデートを推奨パッチ公開の前に攻撃が始まる状態を「ゼロデイ脆弱性」と言いますが、それでは、この脆弱性のメカニズムはどんなものだろうかと思い、調べてみました。結論から言えば、この問題はJoomla!側に重大な脆弱性はなく、PHPの既知の脆弱性(CVE-2015-6835)が原因でしたので報告します。exploitを調べてみる既にこの問題のexploitは公開されていますが、悪い子が真似するといけないのでURL等は割愛します。以下のページでは攻撃の原理が説明されています。Executionざっくり言うと、以下の様な攻撃です。全体的には、典型的なオブジェクトインジェションによるコード実行です。デストラクタにより任意コードが実行できるかについては、以下の記事を参照下さい。文字列を切り詰めると、文字列型のデータがオブジェクトに化けるのでしょうか。前記の記事にはその辺の説明はなかったので、自分で調べてみました。シンプルな再現コード以下は、セッション変数にログインユーザ名とUser-Agentのみをセッション変数にセットして、その際のセッション形式の文字列を表示するだけの簡単なプログラムです。"\n";出力は以下となります。_default|a:2:{s:2:"id";s:8:"ockeghem";s:7:"browser";s:11:"Mozilla/5.0";}セッション変数のシリアライズ形式は、以下のような形です。外部からは操作できませんが、browserのところにオブジェクトをセットした場合の形式は下記のとおりです。ヌル文字を含むため、パーセントエンコードした形で表示しています(bloggerの制限により%記号は全角にしていますが実際は半角です)。_default|a:2:{s:2:"id";s:8:"ockeghem";s:7:"browser";O:6:"Class1":1:{s:15:"%00Class1%00private";s:3:"prv";}}これを念頭におきつつ、外部からUser-Agentとして以下を設定してみます(パーセントエンコード形式)。■は、実際には、UTF-8の4バイト形式の文字をセットします。_aa|O:6:"Class1":1:{s:15:"%00Class1%00private";s:3:"prv";}■セッション変数のシリアライズ結果は下記となります。_default|a:2:{s:2:"id";s:8:"ockeghem";s:7:"browser";s:57:"_aa|O:6:"Class1":1:{s:15:"%00Class1%00private";s:3:"prv";}■";}しかし、これはあくまで文字列です。それは、s:57という型指定がある以上、外部からは変更できないはずです。Joomla!のデフォルトのセッションストレージはMySQLであり、文字エンコーディングはutf8_general_ciとなっています。この場合、MySQLは、UTF-8の4バイト形式の文字があると、その文字を含めてそれ以降が切り詰められる、というすごい仕様があります。このため、セッションをいったんMySQLに保存して、次のページでそのセッションデータを読みだすと、以下のように■以降がカットされた状態となります。文字列だった部分がオブジェクトになっているではありませんか。オブジェクトが生成されているので、このデストラクタも実行されます。上記から、以下のことが言えます。全てPHP-5.4.0~PHP-5.4.44PHP-5.5.0~PHP-5.5.28PHP-5.6.0~PHP-5.6.12すなわち、以下のバージョンで修正されています。PHP-5.4.45PHP-5.5.29PHP-5.6.13PHP-7.0.0これらで修正されている脆弱性はなんだろうと思ってリリースノートを見ると、以下が該当するようですね。free脆弱性ということで、挙動から見てもビンゴでしょう。Hat社の脆弱性トリアージ(緊急度判断)は通常妥当だと思っているのですが、この件に関しては外れてしまったようです。シリアライズされたセッションデータが切り詰められるなんて状況はちょっと予想しがたいので、悪いのはMySQLの仕様だ!、と思わなくもありません。影響を受けるソフトウェアPHPのこの脆弱性の影響は、Joomla!に限られるものではありません。セッションストレージとしてMySQLを使うことは、一般的によく行われているからです。このため、影響の有無判定はともかく、PHPの最新版を使うことを推奨します。RHEL/CentOSについてはパッチが提供されていないので、個別の対策をとるしかないでしょう。以下の様な対応が考えられます。Firewall)の導入があります。まとめJoomla!のリモートコード実行の問題を分析しました。これまで説明したように、この問題の直接の原因は、Joomla!側にはなく、PHPの既知の脆弱性(CVE-2015-6835)が原因です。私も「Joomla!にゼロデイ脆弱性」とツイートしてしまいましたが、Joomla!の問題ではないと訂正いたします。4バイト形式以降を切り詰めるという仕様のため顕在化したことが問題と考えます。MySQLの上記挙動は、こちらでも書いたように、長いデータを黙って切り詰めると思わぬバグや脆弱性の原因になり得るという例だと言えるでしょう。Lite)は、このJoomla!のコード実行の問題に対応したシグネチャを提供済みです。お問い合わせはこちら。HASHコンサルティング株式会社は、セキュリティエンジニアを募集しています。興味のある方は、twitterやfacebookのメッセージ、あるいは問い合わせページからお問い合わせください。15:24ワークアラウンドをもうひとつ。データを格納すべきだったと思います。