巷でここ数日間話題になっているように、WP4.7, 4.7.1 のWP-REST−APIには深刻な脆弱性が含まれていました。
ざっくりとした問題点は「誰でもコンテンツを書き換えられる」。もしexecPHPのようなコンテンツ内のコードを実行できる状態になっているサイトであればサーバーまるごとの乗っ取りが可能な場合すらもありえます。
このことについては日本語情報も多数あるのでそちらをご覧ください。
WordPress の脆弱性対策について:IPA 独立行政法人 情報処理推進機構
WordPress 4.7.1 の権限昇格脆弱性について検証した | 徳丸浩の日記
ちなみに自分はCapital Pの記事で知りました。(広く話題になるのはそれから1,2日くらい遅れていた気がします。)
そもそもWPの差分を追っていたのでREST API周りに変更が加えられていることには気づいていたのですが、この問題には当時気づいていませんでした。
幸いにもリリースから開示までラグを取られたお陰でその間の問題はほぼ観測されていないはずですが、開示以降大量に攻撃が観測されています。
私の管理しているWPサイトでもこれを標的としているアクセスを観測していますが、自動アップデートによりリリース後12時間以内にはすべてアップデートが完了していたため攻撃が成功したサイトは存在しませんでした。
くれぐれも自動アップデートは無効化しないようにしましょう。
アクセスログから攻撃を探す
サーバーのアクセスログをgrepすることで攻撃を検出することが可能です。
目安としてはwp-json/wp/v2/(投稿タイプ)/{post-id}?id={post-id}{hoge}
のようなURLへのリクエスト。post-idには任意の投稿id(整数)、{hoge}には任意の数字以外の文字列が入ります。
Amimotoを使用している場合、以下のようなコマンドでだいたい抽出できるはずです。
1 2 3 |
$ sudo su - # grep -E '/wp-json/.*id=' /var/log/nginx/*.log # zgrep -E '/wp-json/.*id=' /var/log/nginx/*.gz |
管理しているサイトでみてみたところ、UAがpython-requests/2.11.1
のPythonで作られたbotと思われるログが幾つか見つかりました。
試しに grep -r wp-json /var/log/nginx/ してみたらWP4.7の例の脆弱性狙ったアタック観測できた。CloudFrontでUA隠れてて確認できてないけどアクセス元はカナダとかだった
— ガヴリールドロップアウトをみて (@hnle0) February 6, 2017
再現環境を作る
試しに、ローカルに再現できる環境を作ってみます。
くれぐれも外部に公開している環境でやらないでください。
自動アップデートを無効化
何度も言うけど本番環境の自動アップデートを無効化するのはよしましょう。今回みたいな時に対応が間に合いません。
プラグインでもテーマでもいいのでどこか必ず読み込まれる場所に
1 |
define( 'WP_AUTO_UPDATE_CORE', false ); |
を追加。wp-config.phpでおk.バックグラウンドで自動アップデートされなくなります。
4.7.1 に戻す
手動でやってもいいけど面倒なのでWP-CLIを使えばコマンド1つ。
1 |
wp core update --version=4.7.1 --force |
これで環境は整ったはずです。
試しにリクエストしてみる。
存在する投稿IDに対して /wp-json/wp/v2/posts/{id}?id={id}hoge
のようなURLでPOSTするだけ。認証ヘッダーとかはもちろんつけない。
これだけ。簡単すぎる。
ちなみにexec-PHPを有効にしていたら……なんていうのは言うまでもない。(と思って試してみたけれど権限不足で<script>
やPHPのコードは除去されているのでそのあたりの問題は大丈夫かも)
最後に
くれぐれもWPの自動アップデートを無効化したりするのはやめましょう。常に最新版を保ちましょうね。
追記:自動更新が無効化されていた原因を考える記事を書きました。