今年の3月に検出したマルウェアの中に、AISURU と全く同じ暗号アルゴリズムを使う検体が見つかりました。このマルウェアの感染活動は現在まで継続しており、最新版の Command and Control (C2) サーバの名前解決には、Ethereum Name Service (ENS)と Solana Name Service (SNS)が併用されています。C2 サーバからは800件/日以上のペースで現在も活発な DDoS 攻撃コマンドが送信されています。
AISURU と同じ暗号アルゴリズム
3月に検出した検体は、Virus Total にも投稿されており、2月には既に活動していたと推測されます。この検体は、C2ドメインがwww[.]sendtuna[.]comであることから、Nokia Deepfield Emergency Response Team (ERT) と Comcast Threat Research Lab (CTRL) が詳しく報告している 1 JackSkid と呼ばれているボットネットの検体の一つのようです。他にもwww[.]boatdealers[.]su www[.]gokart[.]su kieranellison[.]cecilioc2[.]xyz nineeleven[.]gokart[.]su ida[.]boatdealers[.]su mail[.]gokart[.]su moo[.]6yd[.]ru dvrip[.]6yd[.]ru log[.]6yd[.]ruといったドメインが難読化文字列に含まれていますが、この検体のコードのなかで実際に使われることはありません。報道によれば JackSkid を含む複数のボットネットの C2 ドメインは既に押収されており 2、2名の運用者に対する家宅捜索も行われたようです 3。この2名が JackSkid に関わっているのかどうかは不明です。
この検体の難読化文字列を復号するコードの構成は AISURU とは異なりますが、Nokia Deepfield と Comcast の報告にもある通り、結果的には全く同じアルゴリズムを使用しています。以下の Python スクリプトは この3月の検体の難読化文字列を復号するものですが、RC4鍵を16進数のdeadbeefcafebabee0a4cbd6badc0de5から文字列のPJbiNbbeasddDfscに変えるだけで、AISURU の難読化文字列を復号できます。
inputarray = bytearray(bytes.fromhex("90f6d3754b7af7e956a7af")) # Encrypted Hex String
#rc4key = b"PJbiNbbeasddDfsc" # for AISURU
rc4key = bytes.fromhex("deadbeefcafebabee0a4cbd6badc0de5")
rc4keyarray = []
for i in range(4):
rc4keyarray.append(int.from_bytes(rc4key[i*4:i*4+4],"big"))
rc4keylen = len(rc4keyarray)
S = []
j = 0xd
for i in range(256):
S.append(j)
j = (j + 0xa7) & 0xff
j = 0
for i in range(256):
j = (j + S[i] + (rc4keyarray[i % rc4keylen] >> (i & 0x1f))) & 0xff
S[i],S[j] = S[j],S[i]
r = 0xe0a4cbd6
for i in range(5):
for k in range(256):
r = r * 0x41c64e6d + 0x3039
l = (S[k] ^ rc4keyarray[(i+k) & 3] ^ r) & 0xff
j = (j + ((r * S[k]) >> 0x18) + l) & 0xff
S[k] = S[j]
S[j] = l
j = 0; k = 0; l = 0; m = 1; o = 0
for i in range(len(inputarray)):
j = (j + 1) & 0xff
l = (l + S[j]) & 0xff
n = (l + j) & 0xff
o = (o + S[n]) & 0xff
S[l],S[j] = S[j],S[l]
m = ((m << 1) | (m >> 31))&0xffffffff
if m & 1 == 1:
m = m ^ 0xd800a4
p = (S[(S[(o+l) & 0xff] + S[n & 0xff]) & 0xff] ^ m) & 0xff
inputarray[i] = ((((p>>5) | (p<<3)) ^ inputarray[i]) ^ (p>>4)) & 0xff
print(inputarray.decode("utf-8"))
# Output = "here we are"
このアルゴリズムのベースとなっていると思われるオリジナルの RC4 を同様に書くと以下のようになり、大枠のフローは同じですが、各所に改変や追加がされていることが分かると思います。
inputarray = bytearray(bytes.fromhex("7f094799") # Encrypted Hex String
rc4key = b"key"
rc4keyarray = bytearray(rc4key)
rc4keylen = len(rc4key)
S = []; N = 256
for i in range(N):
S.append(i)
j = 0
for i in range(N):
j = (j + S[i] + rc4keyarray[i % rc4keylen]) % N
S[i],S[j] = S[j],S[i]
j = 0; k = 0
for i in range(len(inputarray)):
k = (i + 1) % N
j = (j + S[k]) % N
S[k],S[j] = S[j],S[k]
inputarray[i] = inputarray[i] ^ S[(S[k]+S[j])%N]
print(inputarray.decode("utf-8"))
# Output = "test"
一時的ですが、4月の検体の難読化にはqE6MGAbIという文字列が使われました。これは昨年6月の MooBot でも使用されていた文字列で、当時の難読化は比較的簡単なものでした。
新しい4月の検体では、最初に作成されるシードに同じ文字列が使われており、それ以降のアルゴリズムは AISURU とは異なるものです。また、この検体から、起動に成功したことを示すコンソール出力がhere we areからhail china mainlandに変わりました。何れも過去のボットネットで使用された既知の文字列です 4 5 6。5月にはさらに別のRC4ベースのアルゴリズムに変更されています。
ブロックチェーンベースの C2 名前解決
4月には Ethereum Name Service (ENS) を使う名前解決をするようになり、Nokia Deepfield と Comcast の報告とは ENS ドメインが異なりますが、NICT の調査結果もマルウェアの開発が止まっていないことを示しています。5月に入ると、Solana Name Service (SNS) による名前解決が追加されました。これは、ENS の一部の Remote Procedure Call (RPC) エンドポイントが不安定だったことがきっかけの可能性があります。ブロックチェーンベースの名前解決といっても、実際に Ethereum の Peer to Peer (P2P) ネットワークに接続するわけではなく、それを仲介するエンドポイントを提供するサービスを利用しています。利用するエンドポイントは以下の通りです。一般的なサービスであり、攻撃者と関連があるわけではありません。
| サービス | アドレス |
|---|---|
| Ethereum | eth[.]llamarpc[.]com ethereum[.]publicnode[.]com ethereum-rpc[.]publicnode[.]com eth-mainnet[.]public[.]blastapi[.]io eth[.]drpc[.]org rpc[.]mevblocker[.]io eth-protect[.]rpc[.]blxrbdn[.]com 1rpc[.]io |
| Solana | sdk-proxy[.]sns[.]id sns-sdk-proxy[.]bonfida[.]workers[.]dev |
名前解決にはテキストレコードが利用され、ENS の場合は JSON-RPC 形式のペイロードをエンドポイントに POST する必要があります。名前解決に使われるのは、
- ENS ドメイン名
ukranianhorseriding[.]eth(ハッシュ化して使用) - キー
ipv6(最新の検体はnetwork) - Ethereum Smart Contract
0xF29100983E058B709F3D539b0c765937B804AC15
(攻撃者に紐つくものではなく ENS Public Resolver の一般的なアドレスです)
になります。 テキストレコードにはキーの名前通り IPv6 アドレスのリストが登録されていますが、実際の C2 サーバは IPv4 アドレスで、IPv6 アドレスの一部をデコードして取得します。このデコード手法は検体のバージョンによって異なります。
Solana のドメイン名は、Ethereum ドメインの location に記載されている住所と同じ、イギリスの特定の住所を示すものになっているため記載は控えますが、ドメイン名の Top Level Domain .sol を除いた名前を使ってテキストレコードを取得します。ただし、全ての ENS エンドポイントが応答しなかった場合にしか使われないため、複数の ENS エンドポイントが登録された最新版では、SNS が使われる可能性はほとんどありません。
この ENS による名前解決が始まった後、一旦 Public DNS による名前解決に回帰したことがあります。その際に使われた C2 ドメインはnode[.]androiddebugbridge[.]suで、Telnet スキャナーのレポートサーバwow[.]androiddebugbridge[.]suと同じ親ドメインでした。この一時的な Public DNS の利用は、不安定な RPC エンドポイントを暫定回避するためだったと推測されます。スキャナーについては、最新版では削除されています。
MountBot と同じ scanner_connection 構造体
スキャナープロセスは、ポート 23 2323 に対してブルートフォース攻撃でマルウェアの拡散を試みますが、大量のスキャン接続を並列に処理するため、接続状態を管理するのに必要なメモリを確保します。そのサイズはボットネットやそのバージョンによって異なりますが、5月の検体がメモリを確保するコードは次のようなものです。
この0x134という構造体のサイズには見覚えがありました。
格納できる最大数が256件(0x100)から128件(0x80)に減っていますが、308バイト(0x134)という中途半端な構造体のサイズが MountBot 7と一致しています。このような大きいサイズの構造体の中身を分析するのは手間がかかるため、暫定的に MountBot で解析済みの構造体定義をあてはめてみました。
その結果、MountBot の構造体がそのままの状態で綺麗にあてはまり、入れ子になっている認証情報の構成も一致しています。この検体は Telnet ログインに成功すると、IPアドレスやログイン認証情報をレポートサーバに送ります。
活発な DDoS 攻撃
最新の DDoS 攻撃ベクタと、直近5月18日までの一週間に利用されたコマンド数は以下の通りで、一部のベクタ ID は未定義です。
| ID | 攻撃内容 | コマンド数 |
|---|---|---|
| 1 | UDP flood string data | 1,281 |
| 2 | UDP flood single byte | 1,971 |
| 3 | SYN flood | 78 |
| 4 | TCP stomp | 958 |
| 5 | FIN flood | 131 |
| 6 | 欠番 | - |
| 7 | 欠番 | - |
| 8 | UDP flood random target | 396 |
| 9 | TCP data flood 64-128 bytes | 157 |
| 10 | 欠番 | - |
| 11 | UDP flood random data | 163 |
| 12 | TCP data flood single byte | 147 |
| 13 | TCP flood zero window | 26 |
| 14 | Spoofed TCP flood | 23 |
| 15 | TCP handshake | 428 |
| 16 | 欠番 | - |
| 17 | TCP data flood after FIN | 323 |
オプションで攻撃先のポートを指定することが可能ですが、ポートオプションを含む攻撃コマンドのうち、ポート番号の上位15件をプロットすると、他のボットネット同様に、各ゲームサーバのデフォルトポートが含まれており、やはりゲーム関連用途での DDoS 攻撃利用が多いと推測されます。
国別の攻撃時間も他のボットネット同様で中国への攻撃が多く、比較的 US よりもブラジルへの攻撃が多めです。日本への攻撃は少なく、割合としては約0.3%ありますが、それも実際には中国から利用されているサーバが含まれています。
ほとんどの DDoS 攻撃コマンドの攻撃時間に60秒が指定されており、必然的に1日あたりのコマンド数には限度があります。攻撃時間の推移を見ると、1日24時間のうち約半分の時間、攻撃をし続けていることになります。
まとめ
一連のマルウェア検体を分析した結果、AISURU と同じ暗号アルゴリズム、Fodcha や hailBot と同じコンソール出力、MooBot と同じ暗号シード、MountBot と同じスキャナー構造体、といった、あらゆる痕跡が確認されました。この中で、暗号アルゴリズムや構造体を模倣するのはソースコードがなければ比較的難しいため、これらの開発リソースは共通かもしれません。また、ブロックチェーンベースの名前解決を使って C2 サーバに接続するマルウェアが増えています。対策の一つとして、ENS の RPC エンドポイントなど、P2P ネットワークを仲介するサービスへのアクセスを監視、もしくは遮断することが考えられます。正規のソフトウェアが使用する可能性もあるため適用できる範囲は限られますが、暗号通貨関連サーバにアクセスするはずのない狭い組織単位であれば、対策となり得るのではないかと考えます。
IoC
マルウェア
31e9e337bad2ad58ecc00d3056047e61f6df5d09be02df5e73118d1834ea6cbb 3月の検体
838b326d32b16440811c1b113abfcc0ec1fb54211bd2abc898522329271348c8 4月の検体
1f8949958021f6323bff76a6317a86c865d07a299a9ebaba5133605012e60306 5月の検体
f49a98d30e59c74ef08c3b1d67e068363b4daf09c8f607dd8e1d0e4f986bad92 5月の検体
026350ae32415cb25fb0868634e148b013588bcca30fba984b6fb5748b6ecbdd 5月の検体
C2 IP アドレス(コマンド実績のある IP のみ)
DigitalOcean, LLC
137.184.164[.]103
139.59.105[.]112
143.110.134[.]237
170.64.224[.]89
68.183.212[.]72
Akamai Connected Cloud
104.64.43[.]42
139.162.113[.]188
139.162.23[.]194
172.104.161[.]36
172.105.192[.]211
172.232.248[.]124
172.236.245[.]200
172.236.32[.]134
172.237.55[.]23
172.238.120[.]210
172.238.232[.]149
Tencent Global
43.129.55[.]206
43.133.154[.]239
43.134.188[.]2
43.135.128[.]3
43.135.143[.]17
43.157.149[.]8
43.157.53[.]175
Alibaba Cloud LLC
47.81.26[.]4
-
https://corporate.comcast.com/stories/reverse-engineering-jackskid-from-bare-bones-mirai-fork-to-persistent-tv-box-botnet ↩︎
-
https://www.justice.gov/usao-ak/pr/authorities-disrupt-worlds-largest-iot-ddos-botnets-responsible-record-breaking-attacks ↩︎
-
https://www.reuters.com/business/media-telecom/us-says-it-disrupted-botnets-that-infected-over-3-million-devices-worldwide-2026-03-20/ ↩︎
-
https://nsfocusglobal.com/mirai-botnets-new-wave-hailbot-kiraibot-catddos-and-their-fierce-onslaught/ ↩︎