本文の内容は、2021年8月26日にStefano Chiericiが投稿したブログ(https://sysdig.com/blog/crypto-sysrv-hello-wordpress/)を元に日本語に翻訳・再構成した内容となっております。
Sysdigセキュリティリサーチチームは、最近のボットネットSysrv-Helloに関連して、WordPressを実行しているKubernetesポッドを襲うクリプトマイナー攻撃を確認しました。この攻撃の目的は、ポッドを制御し、暗号通貨を採掘し、侵害されたシステムから自分自身を複製することでした。
特に、攻撃者は初期アクセスを実行するために、誤って設定されたWordPressを標的にしていました。その後、他の潜在的なマルウェアを阻止しようとし、クリプトマイナーをインストールして実行し、最後に自分自身を複製しようとしました(当社のハニーポットインフラおよびインターネット上で)。
この攻撃で注目すべき点は、攻撃スクリプトとクリプトマイナーのバイナリハッシュが非常に最近のものであり、マルウェアデータベースの登録状況を見ると、ほとんどの人が検出していないことです。そのため、ほとんどのセキュリティソフトウェアではこの攻撃を検出することができず、警告を受けるためにはその動作を検出することに頼らなければなりませんでした。Sysrv-HelloボットネットがWordPressポッドを操る様子を表現したもの。ファンタスティック4に登場する操り人形を参考にしているのは明らかです。
この攻撃は、私たちが長い間見てきたことを裏付けるものです。ボットネットやクリプトマイナーによる攻撃は増加しており、その形態もさまざまです。年初に暗号通貨の価格が暴落したからといって、事態が好転するわけではありません。結局のところ、攻撃者にとっては、あなたのインフラはまだ無料のお金なのです。
この記事では、特定の攻撃レコーダーの特徴、この特定の攻撃の詳細、そしてそれに対してあなたのインフラを保護する方法を説明します。
Sysrv-Helloボットネットとは?
Sysrv-helloボットネットは、2020年12月下旬に初めて確認されたWindowsおよびLinuxに感染し、複数の脆弱性を悪用し、シェルスクリプトを介してデプロイされます。Sysrv-helloの運営者は、ニーズに合わせて常にボットネットを更新し、変更しています。最初の確認以降、攻撃者は、Sysrv-helloのインプラントをインストールするシェルスクリプトの変更を何度か実行し、実行可能なマルウェアがホストシステムにデプロイされるようにしました。
今回の変更では、ボットネットに新機能と複製のためのエクスプロイトが追加されています。最も重要な新機能は、Moneroのようなマイナーをダウンロードして、暗号通貨の採掘を開始する機能です。
攻撃の解剖図
まず、攻撃の概要と、暗号通貨の採掘活動から侵害されたポッドからの複製まで、実行された主な手順を説明します。
Sysrv-HelloボットネットがWordPressを標的にして行った攻撃の模式図
攻撃の概要は以下の通りです:
- エントリーポイントは、デフォルトの認証情報で管理者ログインが設定されたWordPressのセットアップでした。このインストールは、ハニーポットのアカウントにあります。侵入後、攻撃者はマシン上でスクリプトをダウンロードして実行することができました。
- このスクリプトは以下のことを試みました:
- インターネットに完全にアクセスするために、ファイアウォールをオフにし、その他のネットワーク変更を行う。
- 検出されないようにトラブルシューティング用のバイナリを変更する(topバイナリ)。
- マルウェアの実行に必要なすべてのコンポーネントをダウンロードする(curl、crontabなど)。
- 他のマイニングファミリーがよく使用するポートを監視して、競合するマイニングプログラムを削除する。
- アンインストールスクリプトをダウンロードして実行し、ホスト内の監視ツールを排除する。
- すべての準備が整ったところで、実行されたスクリプトは、攻撃者のマシンからsys.x84_64バイナリをダウンロードして実行しました。このバイナリの主な目的は、暗号通貨を採掘することと、公開されているさまざまなサービスのさまざまな脆弱性を利用して自分自身を複製することです。
- このスクリプトは、侵害されたポッドから情報や秘密を収集しながら進みます。
- すべての情報が収集されると、攻撃者はその情報を使って他の内部マシンを攻撃し、クラスターネットワークを介して自分自身を内部に複製します。
最後に、オープンソースのFalcoを使ってこの攻撃を検出する方法を説明します。
どのようにしてこの攻撃を発見し、Sysrv-Helloボットネットにつなげたのか?
#1 ハッキングされたWordPressとスクリプトの実行
攻撃者は、デフォルトの認証情報を使ってハニーポットのWordPressに初期アクセスし、ウェブサイトのハッキングに成功しました。侵入後、攻撃者の最初の行動は、インターネットから以下のスクリプトをダウンロードして実行することでした:

このスクリプトを分析すると、インターネット接続の確認や、暗号化に関連するドメインを/etc/hostsに追加するといった通常の操作から始まり、さまざまな活動を行っていることがわかります。

もっと不思議なステップは、カスタムスクリプトによるtopバイナリの置換です。目的は、検出されないように、生成されたcryptominerプロセスをコマンド出力から削除することです。

このスクリプトは、持続性についても考慮しており、crontab バイナリがシステムで利用可能かどうかをチェックします。この場合、crontabが利用できなかったため、スクリプトはそれをインストールしました:

実際の永続化は、これから説明するバイナリによって第2段階で実行されます。
実際に「本物」のマルウェアバイナリを起動する前に、スクリプトは検出を回避する目的で監視ツールのアンインストールも試みました。下の画面では、スクリプトがアンインストールスクリプトをダウンロードして実行し、alyun.serviceやBMC-agentなどのツールを削除しようとしているのがわかります。

#2 Cryptominerの実行ファイルのダウンロードと実行
スクリプトは、nohupを使用してcryptominerバイナリのダウンロードと実行を進めます。
ダウンロードされたバイナリを確認すると、実は最近のバージョンであり、検出できるセキュリティツールが少ないことがわかります。

ダウンロードしたバイナリはGolangで書かれており、LinuxとWindowsで以下の名前で提供されています。
- sys.x86_64 – Linuxバージョン
- Sys.exe – Windowsバージョン
Sys.x86_64のバイナリ
スクリプトがバイナリを実行すると、3つの主要な目標に向かってポッド上でさまざまなアクションを実行し始めました。- コンテナのパーシスタンスを取得すること。
- cryptominerを実行する。
- インターネット上の他の公共サービスを利用して自分自身を複製する。
このバイナリは、同じマルウェアがすでにポッド上で稼働しているかどうかを確認するために、ポート53055への接続を試みました。
connect res=-115(EINPROGRESS) tuple=127.0.0.1:36988->0.0.0.0:53055
接続に失敗したので、バイナリでポートを開放し、アクティビティを開始しました。
listen fd=3(<4t>:::53055) backlog=128
新しい環境で永続化するために、ポッドにcronjobを作成して永続化を進めます。
* * * * * /home/ec2-user/.ssh/0k8gxs
次に、バイナリはポッド内に 2 つの主要なプロセスを生成しました。
- Kthreaddkプロセス – マイナープロセス
- Random nameプロセス – インターネット経由でエクスプロイトを送信して、自分自身を複製します
kthreaddkプロセス(crypto miner)のシSyscallの調査
kthreaddkプロセスは、主にマイニング活動に焦点を当てています。生成されたSyscallを分析すると、採掘活動を開始するために読み込まれた設定ファイルがわかります。
data={. "api": {. "id": null,. "worker-id": null. },. "autosave": false,. "use_nicehash": true,. "background": true,. "randomx": {. "init": -1,. "mode": "auto",. "1gb-pages": false,. "rdmsr": true,. "wrmsr": true,. "cache_qos": false,. "numa": true,. "scratchpad_prefetch_mode": 1. },. "cpu": {. "enabled": true,. "huge-pages": true,. "huge-pages-jit": false,. "hw-aes": null,. "priority": null,. "memory-pool": false,. "yield": true,. "max-threads-hint": 100,. "asm": true,. "argon2-impl": null,. "astrobwt-max-size": 550,. "cn/0": false,. "cn-lite/0": false,. "kawpow": false. },. "donate-level": 0,. "donate-over-proxy": 0,. "log-file": null,. "pools": [ { "url": "194.145.227.21:5443" } ],. "retries": 5,. "retry-pause": 5,. "syslog": false,. "user-agent": null,. "verbose": 0,. "watch": false,."pause-on-battery": false.}
プロセスはプールとの通信を開始し、作業するジョブを取得しました。このケースでは、ポッドは先ほどと同じIP、194.145.227.21との接続を、5443ポートを使って開きました。プールとの接続は、ドメインやポートに基づく検出を避けるために、攻撃者のマシン(C2)によってプロキシされているようです。
マイナーサーバープールにログインするためのペイロード、およびマイニングメカニズムをネゴシエートするためのペイロードは次のとおりでした:
data={"id":1,"jsonrpc":"2.0","method":"login","params":{"login":"x","pass":"x","agent":"XMRig/6.4.0 (Linux x86_64) libuv/1.38.1 gcc/9.3.0","algo":["cn/1","cn/2","cn/r","cn/fast","cn/half","cn/xao","cn/rto","cn/rwz","cn/zls","cn/double","cn-lite/1","cn-heavy/0","cn-heavy/tube","cn-heavy/xhv","cn-pico","cn-pico/tlo","cn/ccx","rx/0","rx/wow","rx/arq","rx/sfx","rx/keva","argon2/chukwa","argon2/chukwav2","argon2/wrkz","astrobwt"]}}
ネゴシエートされた情報を持つプールからの成功したレスポンスは次のとおりです:
data={"jsonrpc":"2.0","id":1,"error":null,"result":{"id":"5ccc9a1e092bd09e","job":{"blob":"0e0eeda6ce8806d9152b51d43091e17f30a12f09814b5d732d1d6a077db35a6a49ca1e619ee56700000092b0c254968b591363e6bad84a31d4360ac166929841dc424b538cea75b291e1c233","job_id":"9s1","target":"b2df0000","algo":"rx/0","height":2424652,"seed_hash":"ecd3a12c863b63d19b9558d0554ce42e9b5eeceba9c08c7da75f409f1f2980a1"},"extensions":["algo","nicehash","connect","tls","keepalive"],"status":"OK"}}.
マイナーも念のためkeepaliveアクションを実行していますが、まだ稼働していることを確認しています。
data={"id":3,"jsonrpc":"2.0","method":"keepalived","params":{"id":"550562d5151bc30f"} data={"id":3,"jsonrpc":"2.0","error":null,"result":{"status":"KEEPALIVED"}}.
実行すると、プロセスはプールとの通信を開始し、処理するジョブを取得します。
data={"jsonrpc":"2.0","method":"job","params":{"blob":"0e0e95a7ce8806d9152b51d43091e17f30a12f09814b5d732d1d6a077db35a6a49ca1e619ee567000000921868488b28bdc8ef3a856fb46819b46f77475ca5160b0d42f95800a27e15312151","job_id":"9s2","target":"b2df0000","algo":"rx/0","height":2424652,"seed_hash":"ecd3a12c863b63d19b9558d0554ce42e9b5eeceba9c08c7da75f409f1f2980a1"}}.
そして、バイナリは結果を次のようにサブミットします。
data={"id":13,"jsonrpc":"2.0","method":"submit","params":{"id":"5ccc9a1e092bd09e","job_id":"9si","nonce":"74060092","result":"744b58e43727853209fd371c84712e8f5df81e42f4fccd64a0c2a25025790000","algo":"rx/0"}}.
random nameプロセスのSyscall調査
もう1つのプロセスはランダムな文字列で名付けられ、異なるIP上でトラフィックを実行していました。抽出されたSyscallから、異なるポートを使って異なるパブリックIPにトラフィックが発生していることがわかります。

古いバージョンのバイナリからすでに報告されているように、Syscallを分析すると、このプロセスは、パブリックIPに接続しようとする他のマシンに複製して水平方向に拡散するとともに、バイナリにロードされたさまざまなエクスプロイトモジュールを実行する役割を担っていると言えます。
#3 情報収集フェーズと複製
スクリプトは、有用な情報や秘密を探すための情報収集フェーズで動作を進めます。
スクリプトは、/、/root、/homeディレクトリにあるSSH秘密鍵と設定ファイルを読み取って、SSH情報を収集します。

このスクリプトは、ユーザーやルートから取得したSSH鍵と組み合わせて使用します。ブラストが成功したら、新たな犠牲となるホストで ldr.sh スクリプトをダウンロードして実行します。
IOCと不審な活動のまとめ
IPs & URLs
- http[:]//194.145.227.21/ldr.ps1
- http[:]//194.145.227.21/ldr.sh
- http[:]//194.145.227.21/sys.exe
- http[:]//194.145.227.21/sys.x86_64
ファイル
- Ldr.sh
- ldr.ps1
- Sys.x86_64
- sys.exe
疑わしい活動
特筆すべきいくつかの不審な活動があります:- 特にコンテナ内で、ランタイム(ビルドタイムではない)にwgetやcurlが起動される
- パッケージや監視製品のインストールとアンインストール
- 攻撃者のマシンとのネットワーク通信や、インターネット上の異常な送信トラフィック
- 未知のプロセスが起動したことによるCPU使用率の急増
Falcoによるクリプトマイナーとボットネットの検出
この特定のクリプトマイナーのボットネットを検出するには、さまざまな方法やツールを使用します。クリプトマイナーは非常に特徴的なパターンに従うため、その挙動を利用して強力な検出を行うことができます。1つの方法は、インフラストラクチャー監視ツールを使用して、使用されているポッドリソースをスキャンし、CPUやGPUの使用率が高い場合に警告を出すことです。
もう1つの方法は、セキュリティ的なやり方で、ポッド内での不審な接続や悪意のあるバイナリの実行を検出することです。
それでは、この2つの方法について説明します。
Falcoで検出する
Falcoは、コンテナとKubernetesのランタイム脅威検出のためのCNCFオープンソースプロジェクトです。Falcoの利点の1つは、その強力で柔軟なルール言語を活用することにあります。その結果、Falcoは、カスタマイズ可能なルールセットで定義を用いて異常な動作を見つけたときに、セキュリティイベントを生成します。一方、Falcoには、アウトオブボックスの検出ルールがいくつか用意されています。
- rule: Unexpected outbound connection destination desc: Detect any outbound connection to a destination outside of an allowed set of ips, networks, or domain names condition: > consider_all_outbound_conns and outbound and not ((fd.sip in (allowed_outbound_destination_ipaddrs)) or (fd.snet in (allowed_outbound_destination_networks)) or (fd.sip.name in (allowed_outbound_destination_domains))) output: Disallowed outbound connection destination (command=%proc.cmdline connection=%fd.name user=%user.name user_loginuid=%user.loginuid container_id=%container.id image=%container.image.repository) priority: NOTICE tags: [network] - rule: Container Drift Detected (chmod) desc: New executable created in a container due to chmod condition: > chmod and consider_all_chmods and container and not runc_writing_var_lib_docker and not user_known_container_drift_activities and evt.rawres>=0 and ((evt.arg.mode contains "S_IXUSR") or (evt.arg.mode contains "S_IXGRP") or (evt.arg.mode contains "S_IXOTH")) exceptions: - name: proc_name_image_suffix fields: [proc.name, container.image.repository] comps: [in, endswith] - name: cmdline_file fields: [proc.cmdline, fd.name] comps: [in, in] values: - [["runc:[1:CHILD] init"], [/exec.fifo]] output: Drift detected (chmod), new executable created in a container (user=%user.name user_loginuid=%user.loginuid command=%proc.cmdline filename=%evt.arg.filename name=%evt.arg.name mode=%evt.arg.mode event=%evt.type) priority: ERROR - rule: Outbound Connection to C2 Servers desc: Detect outbound connection to command & control servers condition: outbound and fd.sip in (c2_server_ip_list) exceptions: - name: proc_proto_sport fields: [proc.name, fd.l4proto, fd.sport] output: Outbound connection to C2 server (command=%proc.cmdline connection=%fd.name user=%user.name user_loginuid=%user.loginuid container_id=%container.id image=%container.image.repository) priority: WARNING tags: [network] - rule: Write below etc desc: an attempt to write to any file below /etc condition: write_etc_common output: "File below /etc opened for writing (user=%user.name user_loginuid=%user.loginuid command=%proc.cmdline parent=%proc.pname pcmdline=%proc.pcmdline file=%fd.name program=%proc.name gparent=%proc.aname[2] ggparent=%proc.aname[3] gggparent=%proc.aname[4] container_id=%container.id image=%container.image.repository)" priority: ERROR tags: [filesystem, mitre_persistence]
ルールの全説明はGitHubで確認できます。
既存のFalcoルールは、初期スクリプトや起動されたバイナリによって実行される悪意のあるアクションを検出するのに非常に役立ちますが、本記事で報告されているような攻撃に対しても有効です。
特に、この記事で報告されたIoCでルールをカスタマイズすることで、この特定のボットネットに対して非常に強力な検出を行い、何か悪いことが起こった場合に警告を受けることができます。
リソースの監視
主な敵の目的は、インフラストラクチャーでクリプトマイニングを実行し、リソースを暗号通貨に使用することなので、インフラストラクチャー内で何かが高い割合でCPUを使用している場合には、あらゆる監視ツールを使用してチェックし、警告を受けることができます。
以下のPromQLクエリーは、各ワークロードのCPU使用率を提供します:
sum (rate (container_cpu_usage_seconds_total{container=~".+"}[1w])) by (container) / ignoring (container) group_left sum( machine_cpu_cores{}) * 100
適切なリミットとリクエストを設定すると、影響を受けるコンテナはCPUスロットルされます。それらのコンテナは、次のPromQLクエリーで見つけることができます。
(sum by (namespace,pod,container)(rate(container_cpu_usage_seconds_total{container!=""}[5m])) / sum by (namespace,pod,container)(kube_pod_container_resource_limits{resource="cpu"})) > 0.8
まとめ
今回のインシデントは、クリプトマイニング攻撃が増加傾向にあり、時間の経過とともにより創造的になっているという傾向を裏付けるものです。システム管理者としては、適切なツールを使用してこれらの攻撃を検知する必要があります。クラウド・ネイティブ環境のプロセス・アクティビティ、ファイル・アクティビティ、ネットワーク・アクティビティに対する深い洞察力と、スマートな検出エンジンの助けがなければ、このような攻撃を検出することは難しいでしょう。それを明らかにするのはさらに難しいでしょう。
また、統合されたセキュリティと監視のソリューションは、調査プロセスを迅速化するという点も重要です。1つの疑わしいイベントを特定したら、リソースの使用状況、ネットワーク接続、機密ファイルの読み取りなど、さまざまな角度からイベントを追跡するのに役立ちます。
Falcoについてもっと知りたい方は、こちらをご覧ください:
- Falco.orgで始める
- GitHubでFalcoプロジェクトをチェックしてください
- Falco コミュニティに参加する。
- Falco Slackでメンテナと交流する。
- ツイッターで @falco_org をフォローする。
Sysdig Secureで検出する
Sysdig Secure DevOps PlatformはFalcoの上に構築されており、この特定の攻撃を検出するために使用されました。Sysdig Secureのイメージプロファイリングの助けを借りて、DevOpsは以下のことができます:
- ランダムなプロセスからのポートバインドやリッスンを検出するポリシーの作成
- ホワイトリストに載っていない送信先IPを検出するポリシーの作成
- 許可リストにないプロセスやスクリプトの起動を検出するポリシーの作成(例:wget,curl,ldr.shなど)
Sysdig Secure DevOps Platformは、コンテナ、Kubernetes、クラウドサービスを自信を持って実行するためのセキュリティを提供します。Sysdigでは、ビルド・パイプラインの保護、ランタイムにおける脅威の検出とレスポンス、コンプライアンスの継続的な検証、クラウド・インフラストラクチャーとサービスの監視とトラブルシューティングを行うことができます。今すぐお試しください!