以前こんな記事をアップ。
www.aipacommander.com
「助けてー!レンタルサーバ会社から連絡がきたのー(><」って依頼があって、調べてみたら結構時間かかったので、メモしていました。
そのときの情報を今後のためにログ残しておきます。
気づいた理由
レンタルサーバの運営からメールがくる。
「あなたのサーバで、不審なプログラムが動いていたので、パーミッションを000に変更したお(^ω^;」
みたいなメールです。
その内容には、不審なプログラムのパスとファイル名も教えてくれます。
中身覗いたらゾッとした。
<?php
$xxxxx = Array();
eval(xxx_function($base64_data, $xxxxx));
?>
xxx_function()
はbase64でエンコードされている文字&難読化されている文字列$base64_data
を、$xxxxx
の配列を使って復元(?)しているっぽい。
で、動かしてみて、最後にeval()
する箇所をecho
に変更してみたところ。。。
class SMTP {}
class PHPMailer {}
class phpmailerException extends Exception {}
ひゃぁああああ! 第三者中継だね。。。orz
第三者中継 - Wikipedia
第三者中継(だいさんしゃちゅうけい)または“Third-Party Mail Relay”とは、インターネット関連の用語で、関係の無い第三者が自由に、電子メール送信に用いる事が可能なメールサーバの設定、もしくはそのような状態を指す。
orz
さて、、、どうすりゃいいかな。
調査方法
まず初めに、ソースコードとDBをバックアップ。
作業しているときに、地雷踏んで全部消えたら冗談にならいので。
その次に、おかしなファイルを探すことにした。
こういう場合はシェルコマンドを叩けばなんとくなくうまくいくはず。
しかし、レンタルサーバなので、sshを使ってログインができない。
ちょっと特殊な方法でシェルを叩く。
PHPでシェルを実行して結果を参照するコードを用意する。
<?php
$command = 'ls -lhR';
$output = array();
$ret = null;
exec($command, $output, $ret);
file_put_contents('ls.txt', print_r($output, true));
↑のコードはドキュメントルート以下に配置。じゃないとブラウザからアクセス(実行)できないので。
実行すると、↑のphpを配置した箇所にls.txt
ってファイルが作成される。
こいつを参照してみると。。。
Array
(
// ... 省略
[2393] => ./wp:
[2394] => total 224K
[2395] => drwxr-xr-x 5 user group 4.0K Jan 27 09:55 .
[2396] => drwxr-xr-x 6 user group 4.0K Jan 27 11:15 ..
[2397] => -rw----r-- 1 user group 101 Jan 26 14:55 .htaccess
[2398] => -rw-r--r-- 1 user group 418 Jan 25 2013 index.php
[2399] => -rw-r--r-- 1 user group 20K Jan 1 14:58 license.txt
[2400] => -rw-r--r-- 1 user group 10K Jan 1 14:58 readme.html
[2401] => -rw-r--r-- 1 user group 5.4K Jan 1 14:58 wp-activate.php
[2402] => drwx---r-x 9 user group 8.0K Jan 1 14:58 wp-admin
[2403] => -rw-r--r-- 1 user group 364 Jan 1 14:58 wp-blog-header.php
[2404] => -rw-r--r-- 1 user group 1.5K Jan 1 14:58 wp-comments-post.php
[2405] => -rw-r--r-- 1 user group 3.8K Jan 1 14:58 wp-config-sample.php
[2406] => -rw------- 1 user group 4.3K Jan 27 10:45 wp-config.php
[2407] => drwx---r-x 7 user group 4.0K Jan 27 10:47 wp-content
[2408] => -rw-r--r-- 1 user group 3.3K Jan 24 2015 wp-cron.php
[2409] => drwx---r-x 17 user group 16K Jan 1 14:58 wp-includes
[2410] => -rw-r--r-- 1 user group 2.4K Jan 1 14:58 wp-links-opml.php
[2411] => -rw-r--r-- 1 user group 3.3K Jan 1 14:58 wp-load.php
[2412] => -rw-r--r-- 1 user group 34K Jan 1 14:58 wp-login.php
[2413] => -rw-r--r-- 1 user group 7.7K Jan 1 14:58 wp-mail.php
[2414] => -rw-r--r-- 1 user group 14K Jan 1 14:58 wp-settings.php
[2415] => -rw-r--r-- 1 user group 30K Jan 1 14:58 wp-signup.php
[2416] => -rw-r--r-- 1 user group 4.0K Nov 30 2014 wp-trackback.php
[2417] => -rw-r--r-- 1 user group 3.0K Jan 1 14:58 xmlrpc.php
// ... 省略
)
よし。うまく実行できました。
そこでわかったことは。。。
- 運営から連絡のあったファイルの時間が
Jun 7
って書いてあった
- そいつで検索してみると、同じ時間で明らかにおかしいファイルが12個もあった。。。
- server.php、utf7.php、css.php、javascript.php、、、などなど
- 配置されるディレクトリはほんとにランダム
wp-content/plugins/
やらwp-admin/
箇所やら。。。レンタルサーバのルートディレクトリにも配置されていた。
- 中身を参照すると全部難読化されている
- 読み解く2つのコードがありました
- SMTP(第三者中継)
- 攻撃ファイル。cookieかpostを使い、攻撃コードを鍵で暗号化してセット => 送信 => サーバで復号 => eval()で実行っていう恐ろしいコード
((((;゚Д゚))))ガクガクブルブル
おそろしいわ。。。
ファイルの配置は、↑の「cookieやpostデータにコードを〜eval()で実行」ってやつで色々ランダム配置されたんだと思う。
postって確かアクセスのログに残らないと思うから。。。レンタルサーバキツイ
対応内容
そもそもなんでやられたんでしょうね? 原因は?
ざっと上げてこんな感じ。
- WordPressの管理者ユーザーが「admin」「password」
- ログイン画面にて、ボット対策がされていなかった(画像認証とか、Basic認証だとか)
- ftpログインパスワードが盗まれた・・・?
- sqlインジェクション・・・? xss?
- 今回のwebサイトはお問い合わせなどのフォームはないので、恐らくこれもないかな。
- しかし怖かったので「vaddy」っていう脆弱性診断サービスを使ってサイトをクロール => 何も見つからないε-(´∀`*)ホッ
クソがぁっ!!!!
とりあえず、ログインパスワードがヤバイと思ったので、速攻で新規管理ユーザー作成&パスワード最強 => adminユーザーを削除しました。
んで、次に
- WordPressを最新版にアップデート。
- pluginは全部削除して、最新版をインストール
- wp-config.phpの認証ユニークキー更新
- dbのログインパスワード変更
- siteguard pluginのインストール
- ログイン履歴が取れる
- ログイン画面で画像認証の機能を追加できる
これで良し。ってなりました。
とりあえず、これでいいんじゃないか? ということになりました。
だがしかし。。。
もうっかいやられる
対応したその翌日。。。朝ファイルを確認してみたらまたやられていた!!!!
なぜだぁ!!!!!! おかしなファイルは全部消して、WordPressも全部綺麗にしたじゃないかぁ!
どうして? (´;ω;`)ブワッ
ファイル改ざんされていたことに気づいた
うーむと悩んでいたところ。「まさか、、、ファイルが改ざんされているのでは?」と、ちょっと気になって、下記コードを書いてみて実行してみました。
<?php
$command = 'grep -E "(eval\(|base64_decode\(|error_reporting\(0\);|urldecode\(|chr\(|\$GLOBALS)" -r wp/';
$output = array();
$ret = null;
exec($command, $output, $ret);
file_put_contents('grep.txt', print_r($output, true));
最初のls.php
と違うのは、grep
でファイルの中身を検索している点です。
今回難読化されたコードを読んでいて気づいたのは、eval()
やらbase64_decode
をうまく利用している点でした。
なので、これで全ファイルを検索してみたらわかるかなと思い実行してみると。。。
Array
(
// ... 省略
[0] wp-admin/export.php => $GLOBALS['asf823ik'];global$sdadsf;$xiasd82=$GLOBALS;${"\x47\x4c\x53"} /* このあとコードがすげえいっぱい */
// ... 省略
)
きゃぁー!!!キモい!!グロい!!!
なんじゃこりゃ。改ざんされているじゃん。 アップデートは? どうしてうまくいかなかったの・・・?
さらにgrep
で引っかからないコードもありました。これはちょっと巧妙というか。。。そもそもそれ自体も難読化されているでキツイ
php -r "echo 'eva'.chr(108).PHP_EOL;"
eval
↑みたいな感じで、chr()
関数でASCIIを数値で保存しておいて、それを変換して攻撃するなんてコードもありました。大変や。。。
なんかもう、ここまでされると「ご苦労様です(`・ω・´)ゞ」って気持ちになってきた。
さて、話戻しますと、どうやらアップデートは変更がないphpファイルは上書きしないっぽいですね。。。
また、私も先ほどあげた対策のなかで、wp cliを使ってのdiff
を実行していませんでした。最新のWordPressと差分はないかチェックするのをしていなかったのです。
なので、
- アップデートしたけど、改ざんされているphpをほったらかし => そのままファイルは残っている
- 改ざんされたphpにcookieとpostにコードを仕込まし実行される => smtpやらファイルがランダム配置
- 我々が泣く
という流れに(´;ω;`)ブワッ
くっそと思いながらも、今度はちゃんと差分をとって、攻撃ファイルを排除しました。。。。(というかWordPress自体を入れ替えた)
また、注意する点が。実はthemeのファイルもやられていました。
しかし、仕事上、趣味でもそうですが、themeはオリジナルがほとんどだと思うので、やられていても気づきにくいし、検知も難しいかなと思います。
私の場合はすべて目で確認しました。幸いファイル数が少なかったので、そんなに時間はかからなかったです。
対応した内容その2
最初よりは対応が少ないですが、まぁ良いでしょう。。。
今のところ・・・大丈夫そう・・・?
それから毎日アクセスログとファイルを検索してみていますが、やられていないですね。。。いまのところ。
恐らく根本な原因はログインパスワードが「admin」「password」だったからでしょうね。。。(´Д`;
辞書攻撃一発でやられると思うので、次回からそうしないように周知しておきます。。。
ハァ疲れた。
今後の対策
- ソース管理
- gitで管理したらサーバで書き換わっていることを検知することができる
- 「本番が最新」って文化早く無くなれ
- パスワードを難しく
- 常にプログラムは最新に
- 「動かなくなるから怖い」とかいう人いるけど、ハッキングされるよりはまし
- 「パーミッションを強くしなよ」でもいいけど、メディアからファイルがアップロードができなくなるとかあるので、その辺は利便性とトレードな感じがする。
ぐらいかなぁ。。。