WordPress にバックドア仕掛けられないように…

いくら気をつけていても、不幸にして WordPress にバックドアを仕掛けられることは往々にしてあるものです。
重要なのは日々のアップデートと監視なのですが、間に合わずにやられちゃってバックドア仕掛けられることもあるでしょう。
先日リリースされた WordPress 4.5.2 でも結構重めの XSS 脆弱性の報告と修正が行われましたね。
WordPress 4.5.2 セキュリティリリース

そんなわけで、ひさ~しぶりのブログはバックドア仕掛けられないようにする防衛策とソースが改変された時の対応策です。

バックドアを仕掛けられる前の防衛策

不要な php ファイルにアクセスさせない

WordPress のバックドア仕掛けてくるやつの手順として多いのが、メディアアップロード機能の脆弱性とかを利用して wp-conten/uploads/ 以下に php ファイルを置いていき、そのファイルに対してリクエストすることで色々悪さをする手口です。
また、そのファイルが発見されて駆除されたとしても良いように wp-includes/、wp-admin/includes/ とかにファイルを置いておくやつもいます。
なので、Nginx を使ってる場合は以下の様な設定でこれらのディレクトリに置かれたファイルに対して直接アクセスできないようにしてあげると良いです。

こうすることで、仮にバックドアを仕掛けられたとしてもある程度は防げるでしょう。

プラグイン・テーマの編集機能を殺す

あと、多いのはブルートフォースでパスワードをクラックして WordPress のダッシュボードからプラグインやテーマを編集・アップロードする機能を使用してバックドアを仕掛ける手口です。
これに関しては、define( 'DISALLOW_FILE_EDIT', true ); や、define( 'DISALLOW_FILE_MODS', true ); を wp-config.php に追加しておいてダッシュボードから作業できなくするようにすることです。
※一番の対策はクラックされないようにパスワードを単純なものにしないことなのは言うまでもありませんが.
Editing wp-config.php « WordPress Codex

ただ、これをやっちゃうと WordPress の利点であるダッシュボードからのプラグインアップデートとかもできなくなっちゃうので、運用形態にあわせて考える必要がありますね。

特定のPHP関数を無効にする

バックドアとして仕掛けられた php やマルウェアを含む php では、往々にしてソースを難読化するために eval() 関数を使っていることが多いです。
また、exec()、shell_exec()、system() などの PHP から外部コマンドを実行する関数を使用して悪さをすることもあります。
これらは、特に使用していないのなら php.ini の disable-functions 設定で無効にしておくと良いでしょう。
少なくとも、WordPress のコアソースではこれらの PHP 関数は使用していませんが、一部のプラグイン等で使用している可能性がありますので、これらを無効にする場合は自分が使っているプラグイン・テーマのソースを精査してから行ってください。
※追記: eval() は無効にできないそうです。
php.iniで関数を無効化できる。言語構造は無効化できない。ユーザー定義関数は無効化できない。

自分のサーバが SPAM 送信の配信元にされてないか確認しとく

mailq コマンドでメールキューに溜まったメッセージ数を確認できます。

# mailq | grep 'Total requests'

ただ、こんなん毎回手で叩いてもいられないので AWS 使ってる場合は、CloudWach のカスタムメトリクスを使って定期的にメールキューのメッセージ数を監視して、ある程度大きい数になったらアラート上げるようにしてあげると良いです。
カスタムメトリクスにメールキュー数をあげるためのシェルスクリプトはこんな感じ。

これを crontab で定期的(5分に一度程度)まわしてあげれば、ある程度の監視が可能ですね。
バックドア仕掛けられて SPAM の踏み台にされてる場合には、ありえない数の mailq が溜まるはずですので。

AWS 使ってない場合は、閾値以上のメールキューが溜まってたらメールするなり Slack 通知するなりするようにしてあげればいいと思うよ。

コアソースが改変されていないかを確認する方法

コアソースが改変されていないか確認するには、wp-cli を使用するのが便利です。
wp core verify-checksums を使用することでチェック可能です。
wp core verify-checksums

$ wp core verify-checksums
Success: WordPress install verifies against checksums.

なんか改変がある時は以下のように教えてくれます。

$ wp core verify-checksums
Warning: File doesn't verify against checksum: wp-load.php
Error: WordPress install doesn't verify against checksums.

マルウェアファイルが無いか確認する方法

一番良いのはアンチウィルスソフトを使って検索することですが、手っ取り早く行うには eval() を使ってるところが無いかをざっと確認することです。

$ cd /path/to/wordpress
$ find . -type f -name '*.php' | xargs grep 'eval(' | grep -v 'doubleval('
$ find . -type f -name '*.php' | xargs grep 'eval\/'

これで、あきらかにおかしいとことが無いかがざっと確認できます。
ただ、これだけだと特定のパターンにしか対応できないので、やはりアンチウィルスソフトなどを使用するようにした方がいいです。

不幸にも改変されていたことがわかった場合に復旧させるための作業

不幸にも改変が見つかった場合は、WordPress のコアソースに関しては wp-cli を使用すれば以下の手順で正規のモノに戻すことが可能です。

※ 1行目の /path/to/wordpress は WordPress がインストールされているディレクトリに読み替えてください。
※ 7行目の wp core download コマンドのパラメータ --version--locale は、適宜読み替えてください。

ただし、これだけだとコアソースに仕掛けられた改変しか戻すことはできません。
プラグインやテーマについては別途作業が必要になります。

※追記
もちろん、これだけやっときゃ大丈夫って話ではないです。
セキュリティ対策には銀の弾丸はありません。あくまでも一例ということで、ご理解ください。
記事中に間違ってる記述があるとか気づかれた方は、コメント欄等で指摘していただければ幸いです。

WordPress にバックドア仕掛けられないように…」への5件のフィードバック

  1. kimipooh

    shel_exec –> shell_exec

    あと、 exec, system, passthru は、 WP-DBManagerが使っているので、これ使うならOFFにできませんね。
    WP-DBManagerで これらの関数がdisableになっていると警告でます..

    あと .org はわりと利用するので
    location ~* .*\.(cache|sql|log|bak|org)$ { access_log off; log_not_found off; return 404; }
    のようにお示ししていただいたやつに org もつけておくと無難かなぁと思います。
    つい癖で .org 使っちゃう

    返信
    1. をかもと 投稿作成者

      shel_exec –> shell_exec

      指摘ありがとうございます、直しておきました。

      たしかに .org 拡張子はよく使いますね。これも 404 返すようにした方がいいかもです。

      返信
  2. hirorock

    いつも参考にさせていただいております!
    気になった点があったのでコメントさせていただきました。

    $ mv wp-config.php wp-config.php.org

    $ mv wp-config.php _wp-config.php

    平文になってしまう可能性があると思うので、こちらの方が良いかと思います。

    返信
    1. をかもと 投稿作成者

      平文になってしまう可能性があると思うので、こちらの方が良いかと思います。

      おー、そうっすね。指摘ありがとうございます。直しました。

      返信

コメントを残す

メールアドレスが公開されることはありません。