2012年12月21日金曜日

Joomla2.5.2の権限昇格脆弱性

このエントリでは、Joomla!2.5.2まで(1.6.x、1.7.xも含む)に存在した権限昇格の脆弱性について説明します。 

今年5月16日に、情報通信研究機構(NICT)から以下のプレスリリースがありました。
1. 事案の概要
発生時間:
2012年5月1日14時18分~17時17分
発生場所:
研究者の情報交換のためNICT が外部公開用に設置しているWebサーバ
http://mastarpj.nict.go.jp/
サービス概要:
本Webサーバには、主に過去に開催した音声翻訳関連の研究に関する会議の情報が保存され、Webで公開するために稼働させていました。(現在は運用を停止)
2. 被害の状況
  • 上記Webサーバのトップページ(index.html)が改ざんされました。
  • 会議参加者等に係る個人情報は当該Webサーバ上にはなく、個人情報の流出はありません。
  • 詳細なアクセス解析等の結果、当該Webサーバ以外のNICTのサーバへの侵入は認められませんでした。
  • 改ざんされたトップページには、マルウェア(不正プログラム)や他の不正サイトへ誘導するリダイレクトコードの挿入等は認められませんでしたので、当該ページにアクセスされた一般ユーザの方への二次被害はありません。
http://www.nict.go.jp/info/topics/2012/05/announce120516.html
あのNICTが侵入されたということで一部で衝撃が走った(大げさ?)ようですが、NICTのオフィシャルホームページではなく、研究者が独自に設置したサイトが攻撃を受けてしまったようですね。
原因については下記のように説明されました。
3. 直接的な原因
当該Webサーバにおいて使用していたコンテンツマネジメントシステム(CMS)Joomla!2.5.1では、研究者の情報交換が円滑に行われるよう、一般ユーザ権限のアカウントを管理者のチェックなしに取得できる設定※1としていましたが、その取得の際に不正な情報を入力すること等によって一般ユーザ権限のアカウントが管理者権限のアカウントに昇格されるという脆弱性をもっていました。
このため、CMSの管理者権限のアカウントが不正に取得され、そのアカウントを用いてトップページが改ざんされました。
なお、最新※2バージョンのJoomla! 2.5.4では、今回の不正なアクセスに係る脆弱性は解消されておりますが、当該Webサーバにおいてはバージョンアップを怠っていたものです。
※1 アカウント登録方法を "Self " に設定
※2 平成24年5月15日現在
NICT は、この度の事案を重く受け止め、事実関係の調査で得られた結果を踏まえ、再発防止のための対策を講じ、更なるセキュリティ強化に取り組んでまいります。
http://www.nict.go.jp/info/topics/2012/05/announce120516.html
Joomla!2.5.1には存在し、Joomla!2.5.4では改修されている脆弱性を探したところ、以下が該当するようです。
[20120303] - Core - Privilege Escalation
中味を見ても、たいしたことは書いておらず、ネットをさらに調べたところ、以下に詳細が書いてありました。
Jeff Channell | Joomla! 1.6/1.7/2.5 Privilege Escalation Vulnerability | Joomla! | jeffchannell.com
この権限昇格の攻撃方法はまことに興味深いものです。以下、上記のエントリの内容に従い、Joomla! 2.5.2の攻撃方法とその原因、対策について説明します。

攻撃方法

まず、試験環境について説明します。Joomla!2.5.1(侵入されたNICTと同じバージョン)の管理コンソールです。左下に「Joomla! 2.5.7を今すぐアップデート」と見えていますが、アップデートすると脆弱性を試せないので、このままログアウト(退出ボタン)します。


これから先は、攻撃者の視線です。Joomla!の画面左下に、「アカウントの作成」と言うリンクが見えます。これは、一般ユーザとしてコミュニティに参加するための機能でしょうね。設定により禁止することもできますが、侵入されたサイトでは、研究者が自らユーザ登録するようにしていたようです。


 「アカウントの作成」リンクをクリックして、下記のように入力します。

 ここで、画面上では見えませんが、「パスワードの再入力」をわざと間違っておきます。ここでは、パスワードをそれぞれevil1、evil2としています。
ここから、登録ボタンを押すのですが、その際にパラメータを1つ追加する必要があります。方法はなんでもよいのですが、ここではBurp Suiteを使って追加します。

 画面の下に見えるように、「&jform[groups][]=7」は後から追加したものです。後はそのまま流します。

 パスワードが一致していないというエラーメッセージが表示されるので、今度は同じパスワードを入力して登録ボタンをクリックします。
ここから、管理画面に遷移して、今登録したevil(一般ユーザのはず)でログインしてみましょう。

攻撃者は、先ほど登録したユーザ名とパスワードを入力して、ログインボタンをクリックします。すると、管理者権限がないはずなのに、管理者としてログインできてしまいます。

ユーザメニューから、自らの権限を確認しましょう。

 evilユーザは、「システム管理者」の権限があります。これは2番目に強い権限です。最高の権限は「最高管理者」ですが、システムに一人しかいないので、新たに追加はできません。
攻撃者は、管理者権限を得ることができましたので、Joomla!のCMSとしての機能を悪用して、サイト改ざんができることになります。

脆弱性の原因

ここまで見た攻撃方法は、入力パラメータに権限の指定を追加するところは、「ありがち」なものですが、単にそうしただけでは駄目で、最初にパスワードの入力を不整合にしないと攻撃が成立しないところが面白いですね。

Joomla!2.5.2と2.5.3の該当箇所の差分を見ると、以下のようになっています。


components/com_users/models/registration.php getData() 関数内

2.5.2: $this->data->groups = isset($this->data->groups) ? array_unique($this->data->groups) : array();
2.5.3: $this->data->groups = array();

2.5.3では、groupsプロパティを強制的に空にしたようですね。これは対症療法ですので、根本原因はここではありません。
この少し上を見ると、以下の処理があります。


 $temp = (array)$app->getUserState('com_users.registration.data', array());
 foreach ($temp as $k => $v) {
   $this->data->$k = $v;
 }

これは、セッションに保存した内容をすべて$this->dataに追加しています。匂いますね。このセッション変数をセットしている箇所はどこでしょうか。幸い、com_users.registration.dataというラベルがついているので、探索は容易です。以下の箇所でセットしていました。registrationのコントローラですね。


components/com_users/controllers/registration.php register()関数

 $data = $model->validate($form, $requestData);
 // Check for validation errors.
 if ($data === false) {
   // Save the data in the session.
   $app->setUserState('com_users.registration.data', $requestData);
   // Redirect back to the registration screen.
   $this->setRedirect(JRoute::_('index.php?option=com_users&view=registration', false));
   return false;
 // 中略
 // バリデーションが正常の場合
 // Flush the data from the session.
 $app->setUserState('com_users.registration.data', null);

ご覧のように、バリデーションのエラーになった場合、リクエストのデータをすべてセッションに放り込んでいます。バリデーションが正常の場合は、セッションにはnullをセットしているので、これはおそらくデータの再入力画面を表示するための処理でしょうね。
すなわち、以下の経路で、不正に指定した権限がセットされてしまったようです。
  1. パスワードをわざと不整合にしておく
  2. ユーザ登録時に jforms[groups][]=7 をPOSTパラメータに追加
  3. パリデーションでエラー発生
  4. 再入力に備えてリクエストのパラメータをすべてセッションに保存(コントローラ)
  5. モデル側で、セッションの中味をすべて取り込み
  6. 2.で追加したgroupsが取り込まれる
これに対して、Joomla! 2.5.3では、強制的に権限パラメータ(groups)を空にするという対処がなされましたが、いかにも対症療法ですね。
本来は、コントローラーからセッションに取り込む際に、「来たものをすべて取り込む」のではなく、「セッションに保存するパラメータのみを明示的に指定して取り込む」ようにすべきです。

対策

Joomla!ユーザがとるべき対処は、Joomla!の最新版へのバージョンアップです。冒頭の管理画面で、「Joomla! 2.5.7を今すぐアップデート」というボタンが見えていました。思い切って、このボタンをクリックしてみましょう。


上記の画面が表示されるので、Joomlaの行をチェックして、「更新」ボタンをクリックします。数分すると、以下の画面が表示されます。



あれあれ、Joomla!の2.5.7を導入するはずが、2.5.8が導入されています。このあたり、ちょっとゆるい感じですが、最新版は2.5.8ですのでよいことにしましょう。

最新版で攻撃を試す

念のため、この最新版で先ほどと同じ攻撃をしてみましょう。途中の過程は省略しますが、登録したユーザ(evil2)で管理者ログインしようとすると、以下のようにエラーになります。


大丈夫のようですね。念のため、正規の管理者でログインして、ユーザ一覧を確認します。

evil2は「登録ユーザ」のみで、管理者権限はありません。確かに、攻撃は成立していないようですね。

まとめ

Joomla! 2.5.2までに存在した権限昇格の脆弱性([20120303] - Core - Privilege Escalation)について説明しました。
この脆弱性を確認するために初めてJoomla!を導入しましたが、とても簡単に導入できることに驚きました。Joomla!が簡単に使えて、高機能なために人気があるというのはよく分かります。しかし、一方で脆弱性が多く発見されており、攻撃対象として狙われているため、Joomla!を導入する場合は、常に最新版にアップデートしないと危険です。

もしも、継続的なアップデート作業が難しいと言う場合は、自らJoomla!を導入するのではなく、適当なサービスをユーザとして使うことも検討すべきだと考えます。

0 件のコメント:

コメントを投稿

フォロワー