BOFの実行などに対応した新たなマルウェアSLOTAGENT

2026年初頭、IIJは日本からパブリックマルウェアリポジトリにアップロードされたZIPファイルに含まれる未知のマルウェアを発見しました。

マルウェア解析を行った結果、これは攻撃者によって発出された様々な命令を実行できる多機能なRATであることが判明しました。特徴的な要素として、Cobalt Strikeを含む複数のPost-Exploitationフレームワークと同じくBOF (Beacon Object File) 形式のペイロードが実行できること、タイムストンピングのようなアンチフォレンジック機能が実装されていることなどが挙げられます。

内部で使用している文字列 (ファイルパス等) から、我々はこのマルウェアをSLOTAGENTと呼んでいます。この記事ではSLOTAGENTの解析結果や検知ルールなどを共有します。

ローダおよびシェルコード

ZIPファイルに含まれる実行ファイル WindowsOobeAppHost.AOT.exe が実行されると、DLLファイル WindowsOobeAppHost.AOT.dll のエクスポート関数 __managed__Main が呼び出されます。

__managed__Main 関数が呼び出されると、まずXORおよびROR11を組み合わせた独自のアルゴリズムを使用したAPI Hashingによって NtCreateFile といった複数のWindows API関数アドレスを動的解決します。

その後、ファイル db.config 内のデータを鍵 easdbadshyfab でRC4復号して、NtCreateThreadEx 関数等を使用して復号したデータをシェルコードとして実行します。

シェルコード内にはXORエンコードされたSLOTAGENT (DLLファイル) が含まれていて、実行後にオフセット0x297に存在する16バイトのキーを使ってXORデコードした後、リフレクティブロードします。

SLOTAGENT

SLOTAGENTが実行されると、ハードコードされたアドレス 43.156.59[.]110:699 に対して独自プロトコルを使用してTCP通信を行います。

まず、送信データの長さ (4バイト)、続いてHTTPリクエスト時に使用されるようなパス文字列 (/api/v1/stream/data など) を送信します。その後、区切り文字 | に続けてJSON形式の送信データ本体を平文で送ります。

C2サーバとの疎通が確認できしだい、SLOTAGENTは初期通信として以下の情報をJSON形式のデータにまとめて送信します。

キー
aid感染ホスト固有のID
hコンピュータ名
uユーザ名
iローカルIPアドレス
mMACアドレス
oOSバージョン情報
x用途不明 (ランダムなバイト列)
pPID
nモジュールファイル名
eプロセスが管理者権限で実行されているか否か
stスリープタイム (5)
jジッター (10)
_d用途不明 (ランダムなバイト列)

次にコマンドの受信を試行して、成功した場合は対応する処理を実行します。今回観測したSLOTAGENTに実装されていたコマンドは以下の通りです。

コマンド名説明
screenshotスクリーンショット (BMP形式) を取得する
downloadファイルをダウンロードする
shellリモートシェルを実行する
sysinfoシステム情報を取得する
ps実行中のプロセスの情報を取得する
ls作業ディレクトリ内のファイル・フォルダのパスを取得する
pwd現在の作業ディレクトリのパスを取得する
uploadファイルをアップロードする (1)
sleepC2サーバとの通信間隔を変更する
killtaskkill コマンドを使用して任意のプロセスをキルする
catファイルの内容を取得する
writeファイルへの文字列の書き込み
rmファイルを削除する
touchファイルの $SI 属性内のタイムスタンプを改ざんする
bofBOF (Beacon Object File) を実行する
savememoryプロセスのメモリダンプを取得する
upload_chunkedファイルをアップロードする (2)
download_url指定したURLからファイルをダウンロードする
exitマルウェアの実行を終了する
destroyマルウェアに関連するファイルを削除して、実行を終了する

コマンドの実行結果は、データの受信時に使用したものと同じプロトコルを使用して (JSONデータにまとめられて) C2サーバに送信されます。

解析妨害

SLOTAGENTには複数の解析 (リバースエンジニアリング) 妨害を目的とした機能が実装されていました。

API Hashing

SLOTAGENTは実行中、複数のWindows API関数を呼び出しますが、これらのAPI関数のアドレスはDJB2ベースのアルゴリズムを用いたAPI Hashingによって実行時に動的解決されます。

文字列の暗号化

コマンド名を含むSLOTAGENT内部のほとんどの文字列は、TEAに近しいアルゴリズムによって暗号化されていました。これらの文字列はすべて実行時に復号されるため、静的解析では内容を確認することができません。

私たちは解析の効率化のために、SLOTAGENT内の暗号化された文字列を静的に復号するIDAPythonスクリプトを作成・公開しました。ぜひインシデント対応や脅威ハンティング等でお役立てください。

decrypt_slotagent_string.py
https://github.com/mopisec/research/blob/main/decrypt_slotagent_string.py

さいごに

SLOTAGENTは非常に多機能なRATであり、今後もサイバー攻撃で使用される可能性があります。Appendix Aにてファイルハッシュや通信先を、Appendix BにてSLOTAGENTの検知が可能なYARAルールを共有します。よろしければご活用ください。

Appendix A: IoCs

ファイル

SHA256説明
e62bbb6d100cac48018170a991f34dddfcbd0ca2b8f020800f97c85ef690e41b実行に必要なファイルを含むZIPアーカイブ
97e0714ee7279feb558aa38ab9d4c279731d3000c501aff7ad5c2967c3cb987f暗号化されたSLOTAGENT (db.config)
c1681d3aae736585c1dd656fe3ad66dafd3712ad4125e09fc97a4f1e5f367548SLOTAGENTローダ (WindowsOobeAppHost.AOT.dll)
a9c46b67ff938930b16b377df9ddf86f3a56ef9876267387f30299a069c98472SLOTAGENT (メモリ上で実行される)

ネットワーク

  • 43.156.59[.]110 (SG; AS 132203; Tencent Building, Kejizhongyi Avenue)

Appendix B: YARAルール

SLOTAGENTローダ

rule SLOTAGENT_Loader {
    meta:
      description = "SLOTAGENT loader"
      author = "Internet Initiative Japan Inc."
      hash = "c1681d3aae736585c1dd656fe3ad66dafd3712ad4125e09fc97a4f1e5f367548"

    strings:
        $xorKey  = { C6 84 24 ?? 01 00 00 65
                     C6 84 24 ?? 01 00 00 61
                     C6 84 24 ?? 01 00 00 73
                     C6 84 24 ?? 01 00 00 64
                     C6 84 24 ?? 01 00 00 62
                     C6 84 24 ?? 01 00 00 61
                     C6 84 24 ?? 01 00 00 64
                     C6 84 24 ?? 01 00 00 73
                     C6 84 24 ?? 01 00 00 68
                     C6 84 24 ?? 01 00 00 79
                     C6 84 24 ?? 01 00 00 66
                     C6 84 24 ?? 01 00 00 61
                     C6 84 24 ?? 01 00 00 62
                     C6 84 24 ?? 01 00 00 00 }
        $xorLoop = { B9 00 01 00 00 F3 AA    }

    condition:
        all of ($xor*)
}Code language: plaintext (plaintext)

SLOTAGENT

rule SLOTAGENT_RAT {
    meta:
      description = "SLOTAGENT paths and internal strings (in plaintext)"
      author = "Internet Initiative Japan Inc."
      hash = "a9c46b67ff938930b16b377df9ddf86f3a56ef9876267387f30299a069c98472"

    strings:
        $path0 = "/api/v1/users/profile"
        $path1 = "/api/v1/session/refresh"
        $path2 = "/api/v1/analytics/event"
        $path3 = "/api/v1/stream/data"

        $str0  = "{\"error\":\"Failed to get drives\"}"
        $str1  = "{\"name\":\"%c:\",\"type\":\"dir\",\"size\":0,\"modified\":0,\"accessed\":0,\"changed\":0,\"drive_type\":\"%s\"}"

    condition:
        all of ($path*) or all of ($str*)
}Code language: plaintext (plaintext)

シェアする