Webサーバーへのサイト攻撃にあったのでログを調べたところ、痕跡が残っていました。今流行りなのかひとつのパターンがあります。
犯人の狙いはphpの関数eval()を実行して、いろんな悪さをすることです。失敗したのに何度もチャレンジするところがウザい。
Webサーバーのログ内容
まずは、サイト攻撃にあったログの内容を見てもらいましょう。
0.000 - - *.*.*.* - - [07/Dec/2021:20:24:36 +0900] "GET /.env HTTP/1.1" 444 0 "-" "python-requests/2.6.0 CPython/2.7.5 Linux/3.10.0-1160.45.1.el7.x86_64" "-"
0.000 - - *.*.*.* - - [07/Dec/2021:20:24:37 +0900] "GET /.env HTTP/1.1" 444 0 "-" "python-requests/2.6.0 CPython/2.7.5 Linux/3.10.0-1160.45.1.el7.x86_64" "-"
0.000 - - *.*.*.* - - [07/Dec/2021:20:24:37 +0900] "GET /vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php HTTP/1.1" 444 0 "-" "python-requests/2.6.0 CPython/2.7.5 Linux/3.10.0-1160.45.1.el7.x86_64" "-"
0.000 - - *.*.*.* - - [07/Dec/2021:23:05:45 +0900] "POST /vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php HTTP/1.1" 444 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36" "-"
0.000 - - *.*.*.* - - [07/Dec/2021:23:25:11 +0900] "GET /vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php HTTP/1.1" 444 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36" "-"
IPアドレスはがっつり記録されていたのですが * でマスキングしました。IPアドレスは変わるので確定できませんが、イギリス・ロンドンとロシア・サンクトペテルブルグ発信です。
偽装できるので確定ではありませんが、pythonプログラムやブラウザからリクエストされたよう。
ステータスコードは444を返しているので、被害はありません。
コード444はNginx固有のもので、リクエストを受け付けたあと何もしないというもの。
レスポンスコードすら返さないのでサーバー負荷も小さく、上記のように信頼できないリクエストを受け付けたときに使われる。
悪意のある大量なリクエストに対して有効。
ついでに .env ファイルへのアクセスも試みられたようですね?
このファイルはフレームワークなどの環境設定ファイルでよく使われるファイル名です。
Laravelとか想定してるんじゃないかな?
狙いはPHPUnit内の eval() でプログラムのリモート実行
さて、今回の本題ですが、HTTPリクエストでは "/vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php" のPHPファイルを実行しようとしています。
PHPUnitはPHPプログラムのユニット(単体)テストのツールとして最も有名なもの。
ファイル名(eval-stdin)からして、プログラムコードの文字列を渡したら eval() を実行するみたい。
ご丁寧にGETとPOSTの2つの方法でアクセスしてる。
このPHPUnitの脆弱性は有名だそうで、2017年には報告されていたようです。
2019年によく使われた手法で、一旦収まりまた2020年には活発になったそう。
もう2021年も終わりそうだが、それでも使われるということは今だに効果があるんだろう。
(か、やってる人が周回遅れか。)
これはすでに修正されてます。古いPHPUnitを使って無ければ問題ありません。v8.5.21で確認しましたが、ファイル自体ありませんでした。
(v4.8.28, v5.x以前、もしくは5.6.3以前でなければ大丈夫。)
CVE - 共通脆弱性識別子
(Common Vulnerabilities and Exposures)
コンピュータセキュリティの欠陥のリストのこと。
アメリカの国土安全保障省の一機間から資金援助を受けたMITRE社が作成・管理している。
PHPドキュメントを見ても eval() の使用は要注意扱い。
PHP関数の eval() は、PHPドキュメントでもかなり危険だということを注意喚起しています。
それなら非推奨にすればいいのにと思わくもないですが、最新のPHP8でもそうなってはいません。
もう一つ外部プログラムを実行するのに exec() もあるんですが、このようにプログラムからプログラムを実行するものは注意が必要です。
安易に使うものではありません。
eval() はとくに、外部からプログラムコードそのものを期待しているので危険度Maxです。
個人的には使おうとは思いません。もし使おうとする人がいたら『本当にそれしかないの? それでいいの?』としつこく聞くでしょう。
ログを見て気をつけること。
ログ自体は数行で少ないですが、いろいろなことを教えてくれます。当たり前のことをしていれば何てこと無いんですが、一応ご参考までに。
運用上必要のないプログラムはサーバーに置かない。
今回狙われたのは、テスト環境でしか使わないPHPUnitです。運用上必要ありません。
このように、テストや開発でしか使わないようなプログラムは本番環境に置いてはいけません。
ファイル転送時に面倒くさがってそのままアップする人がいますが絶対にやめましょう。
こういうサボりのところは狙われてます。
古いバージョンのパッケージは要注意
今のプログラミングは一から自分で作ることはほぼありません。いろいろなパッケージを組み合わせて作り、固有の処理だけをプログラミングするのが主流です。
ここで気をつけるのは、使用しているパッケージのバージョンは最新にしておくこと。
古いプログラムはセキュリティホールが多いです。普通のパッケージ作成者ならば、指摘された脆弱性は修正しています。
たしかに、パッケージをアップデートしたらテストのやり直しなどが発生して面倒です。
でも、この面倒をサボると狙われます。(やっぱりサボるのは良くない。)
会社員時代によく見ました。恐ろしく古いパッケージを使ってるシステムを。大規模システムほどアップデートを嫌う傾向がありますね?
仕事上では、意見が通らないことが多々あるのでしょうがない部分はありますが、できるだけアップデートするようにしましょう。
アップデートするしないに関わらず、自分の使ってるものの脆弱性の情報にはアンテナを張ってないといけません。
プログラムを実行するプログラムはアクセス不可にする
PHPのeval()もそうですが、プログラミング言語には任意のプログラムを実行する関数があります。
そういうソースコードは、外からアクセスできるところに置いてはいけません。
どうしても必要なら、実行できるプログラムを限定するチェック処理を入れましょう。いくら任意と言っても何でも実行できるのは危険です。
結論。面倒なことを言い訳してやらない人ほど狙われる!
プログラミングをする人の特長として面倒くさがりがあります。かくいうボクの口癖も『面倒くせー』。
ただ、それだけで終わらせてはいけません。
面倒くさい作業が出てきたら、それに有効な方法を提示して実行すべきです。
けっして面倒だからやらないは止めてください。こういうのが悪さをする人のカモになります。
ただ、仕事というものは面倒で意味のないことをやれと言われてしまうのが常。そういうときはこう言って切り抜けましょう。
『〇〇したほうが同じ効果で早く終わります。その分だけ予算が浮きます。』
お金を絡めるとパワーワードになります。理不尽な上司も納得するでしょう。立場が上がれば上がるほどお金のことは気になりますから。
またいい上司は、あなたの意見に触発されてもっと良い意見を出したりします。
もしダメだったら、その場から離れる方向で動くかな。自分なら。
面倒なことを解決する方策が見つからないときは、それは本当にやらなければいけない面倒なことです。
その面倒は引き受けましょう。
考え続けて経験値が上がると、面倒なことをいかに簡単にするかの術をもてます。
『面倒くさい』⇒『やらない』は最悪。一生、最強の武器を持てません。
面倒なことを簡単にやってのける人は最強。
(ただし、便利屋として利用されるだけの場合もあるので注意。)