4連休の前半が間もなく終わろうとした22:30、晩ご飯を食べまったりと本を読んでくつろいでいたらスマホがブルブル震えるんですね。ソシャゲの体力でも回復したのかと思いしばらく放置していたのですが、そろそろ横になろうかと23:00ごろ手に取ると……Mackerel先生からCPU負荷94%突破のお知らせが(^q^)
連休中に君の名前は見たくなかったw
とはいえ見てしまったからにはしょうがないと諦め内容を確認すると、どうやら個人で利用しているWordpress用サーバが炎上なうの模様。何らかの記事がバズった?と思いダッシュボードにログインするけどアクセス数はいつもと変わらず。特定のプロセスが激重の可能性も考えたけど、突然そんなことになるとも思えず、何となしにApacheのアクセスログをtail -f
で確認すると…。
「xmlrpc.php」への大量のアクセスΣ(゚Д゚)
$ tail -f /var/log/httpd/access_log 70.132.61.91 - - [20/Sep/2020:22:41:09 +0900] "POST //xmlrpc.php HTTP/1.1" 200 497 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36" 70.132.61.143 - - [20/Sep/2020:22:41:09 +0900] "POST //xmlrpc.php HTTP/1.1" 200 497 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36" 70.132.61.95 - - [20/Sep/2020:22:41:10 +0900] "POST //xmlrpc.php HTTP/1.1" 200 497 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36" 70.132.61.147 - - [20/Sep/2020:22:41:10 +0900] "POST //xmlrpc.php HTTP/1.1" 200 497 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36" 70.132.61.143 - - [20/Sep/2020:22:41:10 +0900] "POST //xmlrpc.php HTTP/1.1" 200 497 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36" 70.132.61.81 - - [20/Sep/2020:22:41:10 +0900] "POST //xmlrpc.php HTTP/1.1" 200 497 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36" 70.132.61.144 - - [20/Sep/2020:22:41:10 +0900] "POST //xmlrpc.php HTTP/1.1" 200 497 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36" 70.132.61.91 - - [20/Sep/2020:22:41:10 +0900] "POST //xmlrpc.php HTTP/1.1" 200 497 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36" 70.132.61.97 - - [20/Sep/2020:22:41:10 +0900] "POST //xmlrpc.php HTTP/1.1" 200 497 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36" 70.132.61.95 - - [20/Sep/2020:22:41:10 +0900] "POST //xmlrpc.php HTTP/1.1" 200 497 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36"
これ以外のリクエストがほぼ見えない状態でログがガンガン流れてくのを呆然と眺めること数分。明らかにアタックを受けている。それも目の前で、リアルタイムに。はっと我に返りすぐさま対応せねばと思い至りTerminalに意識を戻します。……正直寝たいw
緊急対応から根本治療まで
応急処置
DDoS/DoSにしてはリクエスト数が中途半端だし、そもそも個人サイト潰して何が楽しいのかってお話なので、おそらく情報を抜こうとしているのだろうと思いxmlrpc.phpをリネーム。
$ sudo mv /wordpress/xmlrpc.php /wordpress/_xmlrpc.php
これにより404が返り出したとたん予想通りリクエストも止まり、負荷もいつもの状態に戻りました。気がついてから10分程度で復旧できたので個人サイトとしてはまぁ御の字でしょう。
よくある話しらしい
「wordpress xmlrpc」などで検索すると、このファイルへのアタックは古来からあるようで、現代においては特別な理由が無ければ事前に塞いで置くのがお約束みたいですね。
2014年前後の記事が多く見つかるので、一大ムーブメントがあったのでしょう…。全然記憶にないw
目的はアカウント情報を取得し、ほどほどにアクセスのあるブログを踏み台サーバなどにすることのようですね。
Apacheの設定で根本対応する
リネームしっぱなしだとWordpressの自動アップデートがコケる予感がしたので、ファイル名は元の状態に戻し「httpd.conf」へxmlrpc.phpへのリクエストをすべて拒否する設定を追記し再起動しました。他にもWordpressの設定ファイルを追記する方法もあるようですが、あまり本体はいじりたくないのです。
<Location /xmlrpc.php> Deny from all </Location>
またWordpressへログインするための情報を以下のURLからも収集しているようなのでこちらも同時に閉じた方が良さそうです。前者はWordpressのユーザー名の一覧を返してくれる機能。後者はWindowsの「Windows Live Writer」用の情報を返すもの。どちらも使わないのであれば閉じた方が安心です。
<Location /wp-json/wp/v2/users/> Deny from all </Location> <Location /wp-includes/wlwmanifest.xml> Deny from all </Location>
wp-json
は丸ごと拒否しても良いかもしれませんね。これでひとまずは大丈夫でしょうか。
調査開始
前置きが長くなってすみません。ここからが本題です。
誰が仕掛けてきたのか知りたい
このブログはフロントにAWSのCDN(CloudFront)がいるのですが、POSTや拡張子が.php
へのリクエストは素通りさせる設定になっています。この設定のおかげで負荷が高まり気がつくことができたというわけですが、オリジンのログだけではアタック元の情報がわからないのです。
本当にたまたまなのですが、CDNへのアクセスログをS3に保管するよう設定していたのを思い出し早速ダッシュボードへログイン。本日のログを適当に作ったバケットへコピー。
CLIでダウンロード、解凍します。
$ aws s3 cp s3://log2.katsubemakito.net log --recursive $ cd log $ gunzip *.gz
このファイル群にgrepすると、アタック元のIPアドレスが判明しました。
$ grep '//xmlrpc.php' * | cut -f5 | sort | uniq -c 62738 168.62.29.77 1 168.62.41.113
マイクロソフト…だと!?
結論から言うと、タイトルにもある通り、カリフォルニアにあるマイクロソフトのオフィスのIPアドレス説が濃厚になります。
ひとまずwhois
で調べると、MICROSOFTの名前が表示され、思わず変な声が出ましたw
IPアドレスから大まかな地理情報を調べることのできるGeoIPで有名なMAXMINDのデモサービスの結果もご覧の通り。
いやいや待て待て、「ああ、そうか、Azureで誰かが悪さしているのだろう」と思いAzureのIPアドレス範囲を調べることに。
AzureのIPアドレス範囲
AzureのIPアドレス一覧は以下のページでダウンロードできるようです。 https://www.microsoft.com/en-us/download/details.aspx?id=41653
で、ダウンロードしたファイルを開いて検索しましたが、今回の犯人である「168.62.29.77」の姿は無さそうです。
ということは、やはりマイクロソフトのオフィスから……? AzureのこのIPアドレス一覧の更新に時間差があることも考えられますが……。もう少し後を追いかけたいところですが残念ながらパパっと調査できるのはここまでですね。
CDNのアクセスログを公開しました
今回調査に使用したCloudFrontのログの中で「xmlrpc.php」へのアタックに利用された部分だけ抜き出したものをGitHubで公開しました。 github.com
まとめ
お願い
最後になりましたが、もしマイクロソフト関係者の方がこの記事をご覧になられていらっしゃいましたら、こういった用件の窓口を教えていただけると大変助かります。さすがに社内の端末からすぐに足のつくようなことはしないでしょうから、社内の端末…もしくはVPNなどが何らかの方法で乗っ取られている可能性があるためです。
もし何か調査で協力できることがあればさせていただきたいと思います。
今回の教訓
個人的な教訓は以下です。
- ブルートフォースアタックはある日突然くる
- パスワードはできる限り長い物にする(施行時間を稼ぐ)
- 個人サイトでも監視は大切
- 有事の際に調査ができるようログは必ず保存する。
Twitterでの実況
ブログ用のサーバからCPUのアラートが飛んできたと思ったら、`xmlrpc.php`へブルートフォースアタックを受けていたでござる(^q^)
— 勝部麻季人 💦👏 (@katsube) September 20, 2020
22:30〜23:10の40分間で88058回なので36req/sか。格安サーバにしては思ったより耐えてくれた印象。負荷テストありがとうございますw pic.twitter.com/qAlxyu6Tba
で、アクセスログからIPアドレス引っこ抜いて調べてるとどうもマイクロソフト(カリフォルニア)らしい。最初Azureで誰か悪さしてるのかと思ったけど、AzureのIPアドレスでもなさそう。https://t.co/6R0BljUW5y pic.twitter.com/niaB5tTcZ9
— 勝部麻季人 💦👏 (@katsube) September 20, 2020