-
タグ
タグ
- セキュリティ
- 人材開発・教育
- システム開発
- アプリ開発
- モバイルアプリ
- DX
- AI
- サイバー攻撃
- サイバー犯罪
- 標的型攻撃
- 脆弱性
- 働き方改革
- 企業市民活動
- 攻撃者グループ
- JSOC
- JSOC INSIGHT
- サイバー救急センター
- サイバー救急センターレポート
- LAC Security Insight
- セキュリティ診断レポート
- サイバー・グリッド・ジャパン
- CYBER GRID JOURNAL
- CYBER GRID VIEW
- ラックセキュリティアカデミー
- すごうで
- ランサムウェア
- ゼロトラスト
- ASM
- EDR
- XDR
- SASE
- デジタルアイデンティティ
- インシデントレスポンス
- 情シス向け
- 対談
- CIS Controls
- Tech Crawling
- クラウド
- クラウドインテグレーション
- データベース
- アジャイル開発
- DevSecOps
- OWASP
- CTF
- FalconNest
- セキュリティ診断
- IoT
- EC
- サプライチェーンリスク
- スレットインテリジェンス
- テレワーク
- リモートデスクトップ
- アーキテクト
- プラス・セキュリティ人材
- 障がい者採用
- 官民学・業界連携
- カスタマーストーリー
- 白浜シンポジウム
- CODE BLUE
- 情報モラル
- クラブ活動
- 初心者向け
- 趣味
- カルチャー
- 子育て、生活
- 広報・マーケティング
- コーポレート
- ライター紹介
- IR
ラックのサイバー救急センターは、2024年3月に中国を拠点とする攻撃者グループ「Winnti Group」による新たな攻撃キャンペーン「RevivalStone」を確認しました。この攻撃キャンペーンは、製造、素材、エネルギー分野の日本企業を標的にしたもので、新しい機能を備えた「Winntiマルウェア」が攻撃に使われていました。
そこで今回は、複数の日本組織を標的としたRevivalStoneキャンペーンの全体像とともに、新しいWinntiマルウェアの機能の詳細を説明します。さらに今後の対応策として、同様の攻撃に対する検知や対策手法を紹介します。
なお、本内容は2024年10月2日から4日に開催されたセキュリティカンファレンス「Virus Bulletin Conference 2024(VB2024)」の「RevivalStone: new puzzle posed by Winnti group」、および2024年12月11日、12日に開催されたThreat Analyst Summit(TAS'24)の「RevivalStone: New Puzzle Winnti Group Posed」というタイトルで発表した内容を加筆したものです。
Winnti Groupについて
本攻撃キャンペーンについて紹介する前に、Winnti Groupに関しての帰属や最近の活動について振り返ります。
Winnti Groupとは
Winnti Groupは、2010年頃からゲーム業界を主なターゲットとして攻撃を行っていた中国を拠点とする攻撃者グループです。時代の経過に伴いターゲットを変化させ、現在は、様々な分野の知的財産を扱う組織を標的としています。
Winnti Groupの攻撃活動は、サイバー犯罪とスパイ活動を並行して行ってきており、中国政府に代わって活動する民間の請負業者と関連があるAPT41のサブグループの1つとして分類されています(図1)。
スパイ活動については、その活動の多くが国家の戦略的目標に沿ったものであり、官民問わず世界中の産業界を広く標的としています。そして、この攻撃者グループの攻撃の特徴は、通信の隠蔽および操作を可能にする特有のルートキットを持つWinntiマルウェアの使用や、窃取した正規のデジタル証明書をマルウェアに使用するといったことが挙げられます。

Winnti Groupの活動とマルウェアの変遷
図2は、Winnti Groupの活動とWinntiマルウェアの変遷を時系列順にまとめたものです。Winnti Groupの活動をタイムラインから確認してみると、様々な業種が標的となっていることがわかります。2022年以降では、アジア地域の製造業や素材関連の組織などが狙われています。
一方、Winntiマルウェアに目を向けてみると、その起源は2013年のKaspersky社が報告したレポートまで遡ります。このマルウェアに関連する情報は限られていますが、マルウェアの機能は長年にわたって改善されており、その存在の脅威は広く知られるようになっています。2022年のCybereason社の「Operation CuckooBees」※1によれば、Version5.0とも考えられる機能をアップデートした新しいWinntiマルウェアが報告されています。
また、セキュリティカンファレンス「JSAC 2025」の中で、2024年にアジア太平洋地域に対してWinntiマルウェアを利用した攻撃が行われていたことがTrend Micro社より報告※2されており、近年、Winnti Groupの活動が活発化していることがうかがえます。以降の章では、2024年3月に確認した攻撃キャンペーンRevivalStoneにフォーカスを当て、その内容を詳しく見ていきます。
※1 Operation CuckooBees: Deep-Dive into Stealthy Winnti Techniques
※2 Stealth in the Shadows: Dissecting Earth Freybug's Recent Campaign and Operational Techniques

RevivalStoneキャンペーン
図3は、RevivalStoneキャンペーンの全体像です。攻撃者グループは、初期侵入として標的組織のWebサーバで稼働するERPシステムのSQLインジェクションの脆弱性を悪用し、Webサーバ上にWebShellを設置します。その後、WebShellを利用して、組織内のネットワーク内を横展開するため偵察と認証情報の収集を行い、このサーバを攻撃の足場とするためにWinntiマルウェアを配置します。
次に、侵害を拡大する過程で、運用保守業者の共通アカウントを窃取します。このアカウントを利用し、インフラを提供する組織のネットワークに横展開を行って攻撃活動を継続します。結果として、攻撃者グループはインフラを提供する組織のネットワークも侵害し、そのインフラ環境を利用している複数の組織のサーバにまで被害が拡大しました。

WinntiマルウェアとWebShell
ここでは、RevivalStoneキャンペーンで利用されていたWebShellと新しいWinntiマルウェアの詳細な機能について掘り下げて見ていきます。
WebShell
WebShellは、「China chopper」、「Behinder(冰蝎)」や「sqlmapファイルアップローダ」など複数が利用されていました。
China chopper
China chopperは、中国を拠点とする攻撃者グループが利用する汎用的なWebShellです。このChina chopperには、図4に示すように、POSTリクエストを受信するためのパラメータとして興味深い文字列が設定されています。攻撃者グループは、このWebShellを使用して標的ホスト上で様々な攻撃活動を行い、最終的には、Winntiマルウェアの展開を行っていました。

Behinder(冰蝎)
2つ目は、Behinder(冰蝎:ビンシエ)です。別名「IceScorpion」とも呼ばれています。このWebShellは、PHP、ASP、JSPなどマルチプラットフォームに対応しており、中国語話者の開発者によって作成※3されています。ファイル操作やシェルコマンド実行、プロキシ機能など様々なバックドア機能を持ち、AESで暗号化されたペイロードをロードします。今回のケースでは、図5のようにPHPで作成されていたものが攻撃で利用されていました。
※3 GitHub - rebeyond/Behinder: "冰蝎"动态二进制加密网站管理客户端

sqlmapファイルアップローダ
最後は、sqlmapファイルアップローダです。このWebShellはGUIベースのファイルアップロード機能を有するものであり、sqlmapによって作成することが可能なペイロードの1つです(図6)。この攻撃キャンペーンでは、初期侵入の手口としてsqlmapを使用し、このWebShellを配置していたことを確認しています。


Winntiマルウェアの実行フローと通信フロー
今回確認された新しいWinntiマルウェアの実行フローを図7に示します。実行フローの始まりは、Remote Desktop Configurationサービス(SessionEnvサービス)であり、このサービスでWinntiマルウェアが永続化されていました。
Winntiマルウェアの実行フローは次の通りです。
- 1.SessionEnvサービスの開始によって、正規ファイルであるSessEnv.dllが読み込まれます。
- 2.SessEnv.dllが改ざんされたTSMSISrv.dllを読み込みます(DLLハイジャック)。
- 3.TSMSISrv.dllがWinnti Loaderであるmresgui.dllを読み込み、実行します。
- 4.Winnti LoaderがWinnti RATを開始するためにDATファイルを読み込み、復号します。
- 5.Winnti LoaderがDATファイルを読み込み、Winnti RATを起動します。
- 6.Winnti RATが再度DATファイルを読み込み、Winnti Rootkitのデプロイを開始します。
- 7.Winnti RATがWinnti Rootkit Installerであるamonitor.sysをドロップし、AmdK8サービスのバイナリパスを一時的に書き換えて、Winnti Rootkit Installerをサービス起動します。
- 8.Winnti RATがWinnti Rootkit Installerを通じて、シェルコードを実行します。
- 9.シェルコードがWinnti Rootkitをデプロイします。

図8は、感染端末上にWinnti Rootkitが展開された後の通信フローです。上記の流れでWinnti Rootkitのデプロイが終わると、配備されたWinnti RootkitがTCPIPプロトコルドライバのハンドラをフックし、感染端末上の通信を傍受します。本キャンペーンでは、Winnti RATはコールバック通信を発生させないリスニングタイプとして動作しており、外部からの通信を待ち受けます。そして、Winnti Rootkitが外部のC2サーバから特定の通信を受信すると、その内容がWinnti RATに伝えられ、Winnti Rootkitを経由してレスポンスを送信しようとします。

Winnti Loader
Winnti Loader(別名PRIVATELOG)はWinnti RATをメモリ上にロードするためのマルウェアです。本キャンペーンでは、mresgui.dllという名前の64bitのDLLファイルがこのローダに該当します。ここでは、Winnti Loaderの3つの特徴について解説します。
難読化されたコードと文字列
このローダは、耐解析のためにジャンプベースのCFF(Control Flow Flatting)が施されており、コードが難読化されています。コードには、ジャンプテーブルと間接ジャンプ命令、SET命令が多く存在し、これらはIDAにおけるデコンパイルではSwitch-Case文に変換されるため、ジャンプテーブルのサイズに応じてcase文が増える形となり、コードが読みにくくなります(図9)。また、特徴的な文字列はXORまたはChaCha20で難読化された状態でマルウェア内に含まれています。

検知回避
EDR製品などによる検知を回避するために、Winnti Loaderは動作に必要な正規DLLファイルをSystem32フォルダへコピーし、ロードします。コピー対象のファイルは、図10に示す通り15個あります。この検知回避機能は、後述するWinntiマルウェアのコンポーネントの1つである「UNAPIMON」マルウェアでも実装されています。

また、Winnti Loaderは、ファイルコピー時にファイル名をアンダースコアと5-9文字のアルファベットから構成される名前(例:「_syFig.dll」や「_TcsTgyqmk.dll」など)に変更します。図11は、ランダムな文字列の文字数を決定するためのコードを示しており、この図では5から9までの数値を変数v1に代入していることがわかります。

その後、Winnti Loaderはコピーされたライブラリを動的にロードし、ロードが完了するとコピーしたファイルを削除します。
DATファイルの読み込みとWinnti RATのロード
Winnti Loaderのメインの挙動は、DATファイルを読み込んでデータを復号・ロードすることです。Winnti RATをメモリ上に展開後は、制御をWinnti RATへ移します。本キャンペーンでは、ローダ内に「c:¥windows¥Installer¥dmdwv.dat」の文字列がChaCha20で難読化された状態で埋め込まれており、ローダはこのパスにあるファイルを読み込みます(図12)。DATのファイルの復号処理の詳細については、次の節「DATファイルの復号処理」で紹介します。

DATファイルの復号処理
Winntiマルウェアが格納されているDATファイル(dmdwv.dat)は、AESとChaCha20で暗号化されています。図13は、Winnti LoaderおよびWinnti RATで行われる、DATファイルの復号処理の全体像です。復号にあたり、被害端末固有の情報であるIPアドレス、MACアドレス、ネットワークインタフェースのGUIDが必要となり、これらの情報から2種類の鍵AおよびBが生成されます(図13の左上)。
また、DATファイルは、初期化ベクトル(IV)、復号後データのSHA256ハッシュ値、AESで暗号化されたデータで構成されており、このAES復号を行う際(図13の中央)に使用するのが鍵Aです。さらに、AES復号後のデータはChaCha20で暗号化されており、この復号(図13の右下)に鍵Bを使用します。

このDATファイルの復号において特徴的な部分は、SHA256のハッシュ計算を多用することと、AES復号にあたって利用モードとしてOFB(Output Feedback)を用いることです。SHA256に関しては図13の青色強調箇所で表現されているように、鍵Aを元にハッシュ計算を複数回繰り返します。このような繰り返しは通常は不要であるため耐解析の意図があると思われます。なお、この処理は図だけでは伝えることが難しいためAppendixに例となるPythonスクリプトを記載しています。詳細はそちらをご参照ください。
復号鍵の導出例
DATファイルの復号で必要な被害端末の固有情報(IPアドレス、MACアドレス、ネットワークインタフェースGUID)は、Winnti LoaderおよびWinnti RATがGetInterfaceInfo関数とGetIPNetTable関数を呼び出すことで取得されます。GetInterfaceInfo関数はネットワークインタフェースアダプタの一覧を返し、GetIPNetTable関数はIPv4アドレスとMACアドレスのマッピングテーブル(arpコマンド相当)を返します。
図14に鍵の導出過程を示します。図14の左側はネットワークインタフェースGUIDの処理の例を表しており、図14の右側はIPv4アドレスとMACアドレスのマッピングテーブルの例を表しています。ネットワークインタフェースGUIDについては、先頭8バイトの値の順序が変更されて使用され、例えば、図14の左中央に記載の先頭4バイトは「D6 27 37 BB」から「BB 37 27 D6」の順に並び変えられます。そして、図14の下部に示すように、これらの3つの値を結合した0x1Aバイトのデータが鍵Aとなり、順序を変更したネットワークインタフェースGUID(0x10バイト)が鍵Bとなります。
なお、端末に複数のネットワークインタフェースがある場合や隣接する端末が複数ある場合は、その組み合わせのうちひとつだけが鍵として採用されます。

AES復号後のデータ構造
先述の通り、DATファイルは、初期化ベクトル(IV)、復号後データのSHA256ハッシュ値、AESで暗号化されたデータで構成されています。このAESで暗号化されたデータを復号した後のデータ構造を次に示します。復号後のデータは、4バイトのID、4バイトの暗号化データ長、2バイトのチェックサム、12バイトのChaCha20で使用するNonce、可変長のChaCha20で暗号化されたデータの配列で構成されています。
struct chacha_enc_data { DWORD id; DWORD encrypted_data_len; WORD check_sum; BYTE nonce[0xC]; BYTE encrypted_data[]; };
図15は、DATファイルの暗号化データをAESで復号した後のデータ構造を表したものです。上記の構造にしたがって複数のデータ([0]、[1]、...)が存在することがわかります。DATファイルに格納されていたデータは全部で4つあり、それぞれChaCha20でさらに暗号化されています。なお、DATファイルには、ID 2、5、4、3のデータが格納されており、これらは後述する表1のIDと対応しています。

ChaCha20と復号後のデータ
図16は、AES復号後のデータをさらにChaCha20で復号する際のWinnti Loaderのコードです。ChaCha20のカウンターは2、ラウンド数は20に指定されています。また、このとき使用される鍵は、鍵BのSHA256ハッシュ値です。

AES復号後の4つのデータを個別にChaCha20で復号すると、表1に示す内容のペイロードを得ることができます。これらのデータは、Winntiマルウェア実行時に読み込まれるもので、Winnti LoaderがWinnti RAT(表1のID 2のデータ)をロードし、Winnti RATがWinnti Rootkitをデプロイするために表1のID 3、4、5のデータをロードします。
ID | 内容 | ファイルサイズ (Bytes) |
ファイルタイプ |
---|---|---|---|
2 | Winnti RAT | 0x297200 | 64-bit DLL |
3 | Winnti Rootkit Installer | 0x2C50 | 64-bit Native |
4 | Winnti Rootkitのデプロイに使用するシェルコード | 0xAB0 | 64-bit Shellcode |
5 | Winnti Rootkit | 0x4200 | 64-bit Native |
Winnti RAT
Winnti RAT(別名DEPLOYLOG)は、Winnti Loaderによって実行されるRATです。本キャンペーンでは、Winnti RATはDATファイル(dmdwv.dat)に暗号化された状態で格納されており、実体は64bitのDLLファイルです。
大部分が削除されたPEファイルヘッダ
Winnti RATのPEファイルヘッダは、大部分がゼロ埋めされています。例えば、e_magic、Signature、Machine、Characteristics、SizeOfCode、SectionNameなどが0となっています(図17)。e_magicやSignatureなどの値(MZやPE)が書き換えられていたり、0で埋められていたりするマルウェアは多いですが、コードのサイズやセクション名までを0で埋めているものは比較的稀です。なお、後ほど紹介するWinnti RootkitもWinnti RATと同様、PEファイルヘッダの大部分がゼロ埋めされていました。このような手法は検知回避のために用いられ、過去のWinntiマルウェアでも見られる特徴です。

難読化されたコードと文字列
Winnti RATは、Winnti Loaderと同じく、ジャンプベースのCFFが施されており、コードが難読化されています。また、文字列の難読化は、XOR、ChaCha20に加えて、RC4も使用されています(図18)。

Winnti Rootkitのデプロイ
Winnti RATは通信を隠蔽するために、実行時にWinnti Rootkitをカーネルメモリに展開します。展開にあっては、Winnti Rootkit Installerである「amonitor.sys」を一時的にドロップし、正規のAmdK8サービス(AMD K8プロセッサカーネルドライバサービス)の内容を書き換えて起動します。なお、書き換えられたAmdK8サービスは、Winnti Rootkit展開後に元の状態に戻されます。
デプロイの流れは、次の通りです。
- 1.Winnti RATはWinnti Rootkitが配備済みかどうかを調べるために、バージョンチェックのコマンドをWinnti Rootkitへ送ります。
- 2.Winnti Rootkitが配備されていない場合は、amonitor.sysを「%SystemRoot%¥System32¥drivers¥」へドロップします。
- 3.AmdK8サービスのバイナリパス(別名ImagePath)を上記のドライバのパスへ変更します(図19)。
- 4.AmdK8サービスを開始して、Winnti Rootkit Installerを起動します。
- 5.Winnti Rootkit InstallerへシェルコードとWinnti Rootkitを送り、カーネルメモリにWinnti Rootkitを展開します。
- 6.展開が完了したら、AmdK8サービスを停止します。
- 7.AmdK8サービスのバイナリパスを元に戻します(図19)。
- 8.ドロップしたamonitor.sysを削除します。

C2コマンドとプラグイン管理
これまでの報告によれば、Winnti RATはコールバック通信を発生させるか、通信を待ち受けるかのいずれかで動作するとされています。今回のキャンペーンで見つかったWinnti RATは、後者のタイプであり、C2通信先が定義されていませんでした。この場合、Winnti Rootkitを通じて外部からの通信がWinnti RATに伝えられます。
Winnti RATに実装されているコマンド(一部)は、表2の通りです。表2は、マクニカネットワークス社(現 マクニカ社)による2018年の報告※4に基づいて、当該Winnti RATに実装されたコマンドを分析した結果を表しています。少なくとも6つのコマンドが実装されており、これらのコマンド間で実行される処理は重複していることがわかります。
また、プラグイン管理については、本攻撃キャンペーンの調査では痕跡を確認できませんでしたが、最近の事例でもWinnti RATがプラグイン(CmdPlusやListFileManagerなど)を使用したと考えられる動作がCybereason社の報告した「Operation CuckooBees」で触れられています。このため、表のコマンドとは別にプラグインを配備するためのコマンドなども別途存在するものと考えられます。
※4 日本を狙うサイバーエスピオナージ(標的型攻撃)の動向 2018年上半期|マクニカネットワークス株式会社
コマンドID | 内容 |
---|---|
0 | ネットワークソケットのバインド |
1 | パケットの傍受とIPアドレスの変更の検出、コンソール出力 |
2 | パケットの傍受とIPアドレスの変更の検出、コンソール出力 |
3 | コンソール出力 |
4 | パケットの傍受とコンソール出力 |
5 | パケットの傍受とコンソール出力 |
Winnti Rootkit Installer
Winnti Rootkit Installerは、Winnti RATによってロード・ドロップされるカーネルドライバで、Winnti Rootkitを展開するにあたって使用されるマルウェアです。本キャンペーンでは、DATファイル(dmdwv.dat)に暗号化された状態で格納されており、このマルウェアはWinnti RATによって「amonitor.sys」として「%SystemRoot%¥System32¥drivers¥」配下にドロップされます。
コードサイニング
図20に示す通り、amonitor.sysは署名されていましたが、その署名者の証明書は2015年4月13日(UTC)に失効していました。また、この証明書はCybereason社が報告したWinnti Rootkit(WINNKIT)の署名にも使用されており、Winnti Groupが使いまわしていたものと考えられます。

デバイスの制御
amonitor.sysのドライバエントリには、デバイスのシンボリックリンク名「Pipe2PortCtrl」が定義されています(図21)。これはユーザモードからデバイスにアクセスするために使われます。図22に示すコードから、Winnti RATがシンボリックリンク名「Pipe2PortCtrl」を通じて、ドライバを制御することがわかります。


制御コードとコマンド
このドライバに実装されているコマンドは、1つだけです。コマンドは、制御コード(IoControlCode)を0x8000C004とし、入力バッファ(InBuffer/SystemBuffer)の先頭4バイトを2にすると受理されます。
図23にWinnti Rootkit Installerのコマンドの実装箇所を示します。このコードから、上記の条件の場合にのみ関数(sub_140001060)を呼び出すことがわかります。この関数は入力バッファに指定したデータを非ページプールメモリへ展開し、展開したデータを呼び出すためのもので、一連の流れではWinnti RATから受け取ったシェルコードとWinnti Rootkitを展開し、シェルコードに制御を移してWinnti Rootkitを配備します。

図24は、コマンドを通じてシェルコードおよびWinnti Rootkitがメモリ上に展開された際のプール一覧です。本キャンペーンでは、プールタグとして「pccc」という文字列が使用されており、図からはWinnti Rootkitとシェルコードが展開された様子を確認することができます。なお、このプールタグは過去の攻撃キャンペーンでは異なる値が使用されているため、Winnti Groupの特徴的な文字列ということではありません。

Winnti Rootkit
Winnti Rootkit(別名WINNKIT)は、Winnti RATによって配備されるルートキットであり、通信を隠蔽するために使用されます。本キャンペーンでは、DATファイル(dmdwv.dat)に暗号化された状態で格納されていました。
ダミーのNDISプロトコルの登録とTCPIPプロトコルハンドラの書き換え
Winnti Rootkitは、NdisRegisterProtocolDriver関数を呼び出してダミーのNDISプロトコルドライバ「IPSecMiniPort」を登録します。そして、関数の実行結果として返ってきた情報を元にTCPIPプロトコルドライバのNDIS_OPEN_BLOCK構造体を特定し、TCPIPのプロトコルハンドラProtSendNetBufferListsCompleteとReceiveNetBufferListsの値をWinnti Rootkitの関数のアドレスに書き換えます。これにより、Winnti Rootkitは感染端末のTCPIPプロトコルのパケットを傍受・送信できるようになります。
図25は、Winnti Rootkitの実行前後のTCPIPプロトコルドライバのNDIS_OPEN_BLOCK構造体です。Winnti Rootkitの実行によって2つのハンドラの値が書き換わっていることが図25の赤枠からわかります。

また、Winnti Rootkitの実行後にNDISプロトコルドライバ一覧を取得すると、図26のようにダミーのNDISプロトコルドライバ「IPSecMiniPort」が登録されていることを確認できます。この「IPSecMiniPort」については、ドイツの連邦憲法擁護庁(BfV)が2019年12月に公開したWinnti Groupに関するサイバー攻撃報告書※5内のIOCに含まれており、当時から使用されていた特徴的な文字列と言えます。
※5 BfV Cyber-Brief Nr. 01/2019 - Hinweis auf aktuelle Angriffskampagne -

Winnti RATとWinnti Rootkit間の通信
Winnti Rootkitは、ユーザモードで動作するWinnti RATと通信するためにBeepデバイス(¥Device¥Beep)またはNullデバイス(¥Device¥Null)のIRP_MJ_DEVICE_CONTROLをフックします(図27)。過去に報告されているWinnti Rootkitでは、Nullデバイスのみを悪用していましたが、本キャンペーンのWinnti RootkitにはBeepデバイスも追加されており、Nullデバイスよりも優先的に悪用するようになりました。

上記のフックされたデバイスを介して、Winnti RATはWinnti Rootkitを制御します。このとき、制御コードは0x15E030または0x156008のどちらかを指定可能で、入力バッファに下記の構造体に従ったデータを指定します。また、Winnti Rootkitを操作するための実際のコマンドは、当該構造体のcommand_idに指定します。Winnti Rootkitがサポートするコマンドは、表3に示す通り、全部で6種類あり、バージョンを取得したり、感染端末のMACアドレス情報をWinnti Rootkitに送信したりすることができます。
struct ioctl_in_buffer { DWORD command_id; DWORD data_len; BYTE data[]; };
コマンドID | 内容 |
---|---|
0x10 | Winnti Rootkitのバージョン(0x20102615)を取得する |
0x20 | Winnti Rootkitからデータを受信する |
0x30 | Winnti Rootkitへデータを送信し、さらにその内容を接続元(C2サーバ)へレスポンスとして返す |
0x40 | Winnti Rootkitへデータを送信する |
0x60 | Winnti Rootkitの動作を停止させる |
0x70 | BaseNamedObjectsの値(イベント名)を取得する |
外部からの受信したTCPパケットのフォワード
TCPIPプロトコルドライバのハンドラの書き換え後、Winnti Rootkitは特殊なTCPパケット(マジックパケット)を外部から受信した場合にその内容をユーザモードで動作するWinnti RATへフォワードします。
本キャンペーンのWinnti Rootkitが使用するマジックパケットの正確なフォーマットや処理動作は判明していませんが、TCPペイロードの先頭4バイトをチェックサム値、それ以降を送信データ(可変長)としたフォーマットのデータを与えると受理することを確認しました。具体的なTCPペイロードの値を図28に示します。先頭4バイトの「80 81 88 9a」がチェックサム値、それ以降が送信データの内容です。なお、TCPペイロードは0x10バイト以上である必要があります。

上記に対応するチェックサム値の計算方法は、次のPythonスクリプトの通りです。固定値0x1003Fを使用して乗算することで求められます。この例では、0xCバイトの0x41('A')を送る場合の計算を行っており、最終的に得られる値は、「80 81 88 9a」です。

図30は、図28のマジックパケットをWinnti Rootkitが配備された端末に対して送信した際に、同端末上でWinnti RATがマジックパケットの内容をWinnti Rootkitから受信した様子です。このときデバッガは、Winnti RATがDeviceIoControl関数を制御コード0x15E30およびコマンド0x20(Winnti Rootkitからのデータの取得)で呼び出した直後の状態です。
また、デバッガのダンプ画面に表示しているデータは、DeviceIoControl関数の第5引数lpOutBufferで指定されたアドレスであり、関数の実行によって返却されたデータを受け取る出力バッファです。このダンプ画面の赤枠の箇所を見ると、当該パケットをWinnti Rootkitから取得できていることがわかります。このように、Winnti Rootkitは外部からマジックパケットを受信した場合のみWinnti RATへ通信データをフォワードします。

同様に逆方向の通信も行うことができます。図31は上記のパケット受信後のWinnti RATの動きです。デバッガのダンプ画面に表示しているデータは、DeviceIoControl関数の第3引数lpInBuffer(入力バッファ)で指定されたアドレスです。最初の4バイトがコマンドIDにあたり、この値は0x30(Winnti Rootkitへデータ送信後、接続元へデータ送信)であることがわかります。次の4バイトはデータ長(0x5C)、それ以降は送信データです。
ここで一連のTCP通信の例を図32に示します。これらのデータを比較するとTCPストリームのレスポンス(青色の部分)とダンプ画面の赤枠が一致します。この結果から、Winnti RATはWinnti Rootkitを介してレスポンスを行えるということがわかります。なお、赤枠よりも前の部分のデータはEthernetやIPパケット、TCPパケットのヘッダです。


UNAPIMON
UNAPIMONは、検出回避機能を含むWinntiマルウェアのコンポーネントの1つです。このマルウェアは、子プロセスが監視されるのを防ぐためのコードが実装されており、EDRやサンドボックス環境による解析や監視を迂回する機能を提供します。UNAPIMONの詳細な機能についての解説は、Trend Micro社が報告※6しているため、そちらをご覧ください。なお、このUNAPIMONについては、RevivalStoneキャンペーンでは、Winnti RATによって利用されていたことは確認していますが、攻撃の過程でどのように作成されたのかは正確に確認することはできていません。
※6 Earth Freybug Uses UNAPIMON for Unhooking Critical APIs | Trend Micro (US)
過去のWinntiマルウェアとの比較
本章では、今回のキャンペーンで使用されたWinntiマルウェアと過去のキャンペーンで使用されたWinntiマルウェアを比較し、その違いを紹介します。
Winnti Rootkitのコマンドの比較
表4は、類似する機能を持つWinntiマルウェアが使われた攻撃キャンペーン「Operation CuckooBees」のWinnti Rootkitと、本RevivalStoneキャンペーンで確認したWinnti Rootkitのコマンドの比較です。Winnti Rootkitを隠蔽する機能とBaseNamedObjectsの値(イベント名)を取得する機能の有無、コマンドIDの割り当て方法に変更はありますが、実装されているコマンドに大きな違いは見られないことが確認できます。
機能 | バージョン:0x19012317 (Operation CuckooBees) |
バージョン:0x20102615 (RevivalStone Campaign) |
---|---|---|
Winnti Rootkitの隠蔽 | 0x100 | - |
Winnti Rootkitのバージョンの取得 | 0x200 | 0x10 |
Winnti Rootkitのデータ受信 | 0x300 | 0x20 |
Winnti Rootkitへデータ送信後、接続元へデータ送信 | 0x400 | 0x30 |
Winnti Rootkitへデータ送信 | 0x500 | 0x40 |
Winnti Rootkitの動作停止 | 0x800 | 0x60 |
BaseNamedObjectsの値を取得 | - | 0x70 |
Winnti RootkitがサポートするNDISバージョンの比較
図33は、Winnti Rootkitバージョン0x19012317および0x20102615でサポートしているNDISバージョンの比較です。新しいバージョンのWinnti Rootkitの方がNDIS6.70から6.84までの広いバージョンをサポートしており、また、いずれのWinnti Rootkitも、NDIS 6.0以下はサポートしていないことがわかります。


Winnti Rootkitのマジックパケットの比較
Winnti Rootkitのマジックパケットで使用されるチェックサムの算出方法は、攻撃キャンペーンやWinnti Rootkitバージョン、マルウェアごとに異なっている可能性があります。
図34は、攻撃キャンペーンOperation CuckooBeesで使用されたWinnti Rootkit(バージョン:0x19012317)と本キャンペーンで使用されたWinnti Rootkit(バージョン:0x20102615)のコード比較です。左のコードでは固定値0x1505および0x21を使用しているのに対し、右のコードでは0x1003Fを使用しています。また、左のコードではループ処理が0xCの回数で終了しますが、右のコードではデータ長(図34の変数v10)に応じてループ回数が変化します。このように、Winnti Rootkitのバージョンによってチェックサムの算出方法が変わることがわかります。
なお、さらに古いWinnti Rootkit(バージョン:0x41126)では、同じバージョンであっても算出方法に相違がある検体が存在することを確認しています。

Winntiマルウェアの機能比較
最後にWinntiマルウェアが持つバージョンごとの特徴的な機能の違いを表5にまとめます。暗号化アルゴリズム、ペイロードの暗号化、耐解析機能、回避手法などに違いがあることがわかります。多くのマルウェアもそうですが、Winntiマルウェアも、時が経つごとにより洗練され、複雑になっています。
Winnti v3.0 | Winnti v4.0 | Winnti v5.0 (RevivalStone Campaign) |
||||
---|---|---|---|---|---|---|
初期暗号化 | DES | AES | AES & ChaCha20 + 端末固有の情報(IPアドレス、MACアドレス、ネットワークインタフェースのGUID) |
|||
ペイロードの暗号化 | 1バイトXOR | DPAPI / AES + 端末固有の情報(コンピュータ名 + プロダクトID) |
ChaCha20 + 端末固有の情報(IPアドレス、MACアドレス、ネットワークインタフェースのGUID) | |||
耐解析機能 | - | 未確認 | 文字列の暗号化(XOR / RC4 / ChaCha20) Control Flow Flattening (CFF) |
|||
検出回避機能 | - | Sysmonの停止 | DLLハイジャック APIアンフック |
|||
Winnti Rootkitのコマンド | IPとポート番号の設定 | Yes | No | No | ||
Rootkitの隠蔽 | Yes | Yes | No | |||
イベント名の値の取得 | No | No | Yes |
攻撃者グループの考察
図35は、RevivalStoneキャンペーンで見つかったWinntiマルウェアのコンポーネントに含まれるPDBファイルパスです。パスの文字列の中に「Treadstone」と「StoneV5」という単語が含まれていることが確認できます。
TreadStoneは、2019年の米国大陪審の起訴状※7によると、Winntiマルウェアと連携するように設計されたマルウェアのコントローラであり、中国のITサービス企業であるi-Soon(Anxun Information Technology)社から漏えいしたと考えられるデータにもLinux用のマルウェアコントローラとしてウィンドウタイトルにその名前が含まれていました(図36)。TreadStoneがWinntiマルウェアと同じ意味を持つものだとすると、推測の域を出ませんが、StoneV5はVersion 5という意味にも取れ、今回の攻撃で利用されたマルウェアは、Winnti v5.0であるとも言えそうです。


図37は、RevivalStoneキャンペーンをダイヤモンドモデルで整理し、分析したものです。また、RevivalStoneキャンペーンで利用された攻撃手法についてはAppendix「RevivalStoneキャンペーンのATT&CKマッピング」にまとめてあります。

ここまでの攻撃キャンペーンに関する分析の結果を踏まえて、以下の点からRevivalStoneキャンペーンはWinnti Groupに帰属すると考えています。
- Winnti Groupが使用する特徴的なWinntiマルウェアの新しいバージョン(Winnti v5.0)が使用されている
- Winntiマルウェアの実行過程で、特徴的なレジストリキー「IPSECMINIPORT」を利用している
- Winnti Rootkitは、台湾を拠点とする電気製品メーカーの期限切れの証明書でデジタル署名されている
- Operation CuckooBeesで報告されたWinnti GroupのTTPといくつかの内容が一致する
攻撃痕跡の確認方法と検出
今回紹介したWinntiマルウェアは、Winnti RootkitのインストールやWindowsサービスの利用、特徴的なレジストリキーの登録、ファイル作成などを行うため、これらの有無や内容を確認することで、攻撃痕跡を調査することが可能です。以下にその痕跡を確認する方法を一例として紹介します。
特徴的なファイル名のDLLおよびWinntiマルウェアの確認
Winntiマルウェアは、アンダースコアと5-9文字のアルファベットのファイル名でいくつかのシステムライブラリをSystem32フォルダにコピーするため、このようなファイルが作成されていないか確認します(図38)。また、今回のケースでは、Winntiマルウェアのペイロードは、DATファイル(dmdwv.dat)として「%systemroot%¥Installer」に配置されているため、当該ディレクトリに不審なDATファイルが存在しないか確認します。

レジストリの確認
本キャンペーンのWinnti Rootkitがデプロイされると、Winnti Rootkitの動作によりダミーのNDISプロトコル「IpSecMiniPort」が登録されます。このとき、レジストリキーに「IPSECMINIPORT」として登録されるため、当該レジストリキーの有無でWinnti Rootkitを確認できます(図39)。

イベントログの確認
システム イベントID 7036
端末やサーバが今回のWinntiマルウェアに感染した場合、DLLハイジャックにより、サービスの動作状態の変更が発生する可能性があることから、イベントログ(システム)に、イベントID 7036において、SessionEnvサービスが意図せず、停止および開始されていないか確認します。なお、OSによっては、既定ではSessionEnvサービスは手動実行となっており、サービスを開始することで、イベントID 7040が記録されるため、このタイプのイベントログが意図したものかを確認します。
Security-Mitigation カーネルモード イベント ID 11/ID 12
前述した通り、今回の攻撃キャンペーンでは、SessionEnvサービスが既定で存在しないライブラリ「TSMSISrv.DLL」をロードすることで、Winntiマルウェアが実行されます。ロードされる不正なDLLファイルはMicrosoft社によってデジタル署名されていないことから、Windows Server 2019以降のOSでは、Windowsのコード整合性の保護機能によって監査またブロックが行われ、イベントログが記録されることがあります。
デフォルトの設定では、svchost.exeについては「監査のみ」が有効になっており、図40に示すようなイベントID 11の監査のログが記録されます。この場合、ブロックされた可能性を表す内容のイベントログは記録されますが、署名のないDLLファイルの読み込み自体は行われている点にご注意ください。一方で、「監査のみ」の設定が無効になっている環境では、署名のないDLLファイルの読み込みがブロックされたことを表すイベントID 12がログに記録されます(図41)。


なお、Windows Server 2019におけるコード整合性の保護機能の設定は、WindowsセキュリティのExploit Protectionの設定から確認することができます。Exploit Protectionの設定で「svchost.exe」の編集ボタン(図42の青枠)を押下すると、下図の右のウィンドウが開かれます。このウィンドウの「コードの整合性ガード」項目上にある、「監査のみ」のチェックボックス(図42の赤枠)が設定項目です。ただし、この設定を変更する場合は、本番環境への影響がないかを事前に確認することを強く推奨します。

メモリイメージの確認
VolatilityやMemProcFSなどのツールを利用して、Winntiマルウェアに感染するホストよりダンプしたメモリイメージからマルウェアによって作成されたルートキットや不審なライブラリを見つけます。
Volatility
アンロードされたドライバに関する情報を提供するコマンド「windows.unloadedmodules」を利用します。図43に示すように、コマンド実行結果にWindowsのデフォルト設定では実行されない不審なドライバ「amonitor.sys」がアンロードされていたことが確認できます。

MemProcFS
Volatilityと同様にアンロードされたドライバやモジュールに関する情報が含まれる「¥modules¥unloaded_modules.txt」を確認します。図44に示すように、不審なドライバ「amonitor.sys」がアンロードされていたことが確認できました。また、異なるプロセスIDの「unloaded_modules.txt」を確認するとWinntiマルウェアがセキュリティ製品の検出回避のために正規ライブラリをコピーし、使用後に削除していた痕跡も確認できます。


ルールによる検出
Sigmaルール
Appendix「Sigmaルール」に示すようなSigmaルールを利用することで、Winntiマルウェアの挙動を検出することが可能です。
Yaraルール
Appendix「Yaraルール」に示すようなYaraルールを利用することで、Winntiマルウェアを検出することが可能です。
まとめ
今回は、Winnti Groupによる日本を狙った攻撃キャンペーンRevivalStoneと新しいバージョンのWinntiマルウェア(Winnti v5.0)について紹介しました。新しいWinntiマルウェアでは、難読化や暗号化アルゴリズムの更新、セキュリティ製品による検出回避といった機能が実装されており、この攻撃者グループは、今後もWinntiマルウェアの機能をアップデートしながら、攻撃に悪用していくことが考えられます。また、Winntiマルウェアは、Winnti RATを復号する際に感染端末上の固有情報を復号鍵として使用するため、Winntiマルウェアを発見しても、この固有情報が分からなければ復号できないという解析の難しさがあります。
Winnti Groupは、近年アジア地域が標的として報告されているケースが多くあり、現在も水面下で攻撃活動を続けている可能性が高いです。このため、自組織における情報資産の棚卸しを行い、脆弱性へのパッチ管理や設定不備の確認、必要のないサービスの停止といった、対策の実施を推奨します。また、適切なアカウント管理やアクセス制御、EDR製品を利用したエンドポイントの監視やネットワーク機器を利用した通信制御および監視といった、多層的にセキュリティ対策を講じていくことも重要です。
私たちは、今後もWinnti Groupおよび利用されたマルウェアについて、継続的に調査し、広く情報を提供していきますので、ご活用いただければ幸いです。
松本 拓馬、石川 芳浩
Appendix
Sigmaルール
特徴的なレジストリキー「IPSECMINIPORT」の作成
title: Suspicious create registry of Winnti malware status: Experimental description: Detects create registry of Winnti malware date: 09/13/2024 logsource: product: windows category: registry_event detection: selection: EventID: - 12 TargetObject|contains: - '¥Services¥IPSECMINIPORT' condition: selection falsepositives: - Unknown level: High
WinntiマルウェアによるDLLハイジャックの悪用
title: Suspicious DLL-Hijacking related of Winnti malware status: Experimental description: Detects the DLL-Hijacking related of Winnti malware date: 09/13/2024 logsource: category: image_load product: windows detection: selection_1: Image|endswith: ':¥Windows¥System32¥svchost.exe' ImageLoaded|endswith: ':¥Windows¥System32¥mresgui.DLL' condition: selection_1 falsepositives: - Unknown level: high
Winnti Rootkitの作成
title: Suspicious Winnti Rootkit creation status: Experimental description: Detects the Winnti Rootkit date: 09/13/2024 logsource: category: file_event product: windows detection: selection_1: TargetFilename|endswith: '¥System32¥drivers¥amonitor.sys' condition: selection_1 falsepositives: - Unknown level: high
※ 本番システムに導入する前に、適切なテストとチューニングを行うことを推奨します。
Yaraルール
Winnti RAT
rule Winnti_RAT { meta: description = "Detects New Winnti RAT" author = "LAC Co., Ltd." strings: $a6 = "AVCMyEngineNetEvent" ascii $a10 = "AVCNetMidLayer" ascii $a7 = "¥¥GLOBALROOT¥¥Device¥¥Null" ascii $a8 = "¥¥GLOBALROOT¥¥Device¥¥Beep" ascii $b1 = {89 5C 24 28 48 89 5C 24 20 48 89 [1-4] BA 04 C0 00 80 49 89 F0} condition: all of them }
Winnti Rootkit
rule Winnti_Rootkit { meta: description = "Detects Winnti Rootkit" author = "LAC Co., Ltd." strings: $str1 = "IPSecMiniPort" wide $str2 = "TCPIP" wide $str3 = "NDIS.SYS" ascii $str4 = "¥¥BaseNamedObjects¥¥" wide $str5 = "¥¥Device¥¥Null" wide $str6 = "¥¥Device¥¥Beep" wide condition: all of them }
※ 本番システムに導入する前に、適切なテストとチューニングを行うことを推奨します。
AESキーの導出スクリプト
Winntiペイロードを復号するためのAESキーを導出するためのPythonスクリプトです。
import hashlib def sha256_proc(data:bytes): b_sha256 = hashlib.sha256(data).digest() for i in range(64): concat_b_sha256 = b_sha256 for j in range(63): b_sha256 = hashlib.sha256(b_sha256).digest() concat_b_sha256 += b_sha256 b_sha256 = hashlib.sha256(concat_b_sha256).digest() return hashlib.sha256(b_sha256).digest() if __name__ == '__main__': victim_key_a = b"¥xBB¥x37¥x27¥xD6¥xEF¥x51¥x15¥x49¥x90¥x49¥xDA¥x9D¥x14¥xC9¥x11¥x38¥xC0¥xA8¥x0C¥x01¥x00¥x0C¥x29¥x99¥x99¥x9F" key = sha256_proc(victim_key_a) with open("aes_key.bin", "wb") as f: f.write(key)
RevivalStoneキャンペーンのATT&CKマッピング
Tactic | ID | Name | Description |
---|---|---|---|
Initial Access | T1190 | Exploit Public-Facing Application | SQLインジェクションの脆弱性を悪用 |
Execution | T1053.005 | Scheduled Task/Job: Scheduled Task | スケジュールタスクを利用したマルウェアやスクリプトファイルを実行 |
T1059.003 | Command and scripting interpreter: Windows command shell | バッチファイルを利用してマルウェアやWindowsコマンドを実行 | |
Persistence | T1505.003 | Server Software Component: Web Shell | WebShellを使用 |
T1574.001 | Hijack Execution Flow: DLL Search Order Hijacking | DLLハイジャックを利用してWinntiマルウェアを実行 | |
T1547.006 | Boot or Logon Autostart Execution: Kernel Modules and Extensions | Winnti Rootkitを実行 | |
Privilege Escalation | T1543.003 | Create or Modify System Process: Windows Service | AmdK8サービスを一時的に変更し、Winnti Rootkitをデプロイ |
T1078.002 | Valid Accounts: Domain Accounts | 運用保守業者の共通アカウントや管理者権限を有するアカウントを悪用 | |
Defense Evasion | T1574.001 | Hijack Execution Flow: DLL Search Order Hijacking | DLLハイジャックを利用してWinntiマルウェアを実行 |
T1014 | Rootkit | Winnti Rootkitを用いて通信を隠蔽 | |
T1036.005 | Masquerading: Match Legitimate Name or Location | WinRARをrundll.exeにリネーム後に使用 | |
T1070.004 | Indicator Removal: File Deletion | マルウェア、バッチファイルや圧縮ファイルを削除 | |
Discovery | T1016 | System Network Configuration Discovery | Windowsコマンドのarp.exeやroute.exeなどを利用 |
T1018 | Remote System Discovery | Windowsコマンドのnet.exeを利用 | |
T1201 | Password Policy Discovery | Windowsコマンドのnet.exeを利用 | |
T1069 | Permission Groups Discovery | Windowsコマンドのnet.exeを利用 | |
T1135 | Network Share Discovery | Windowsコマンドのnet.exeを利用 | |
T1007 | System Service Discovery | Windowsコマンドのnet.exeを利用 | |
T1049 | System Network Connections Discovery | Windowsコマンドのnetstat.exeを利用 | |
T1033 | System Owner/User Discovery | Windowsコマンドのquser.exeやwhoami.exeなどを利用 | |
T1082 | System Information Discovery | Windowsコマンドのsysteminfo.exeを利用 | |
T1120 | Peripheral Device Discovery | Windowsコマンドのfsutil.exeを利用 | |
Lateral movement | T1021.001 | Remote Services: Remote Desktop Protocol | RDP接続を使用 |
T1021.002 | Remote Services: SMB/Windows Admin Shares | SMB接続を使用 | |
Collection | T1560.001 | Archive Collected Data: Archive via Utility | WinRARでデータを圧縮 |
IOC(Indicator Of Compromised)
Indicator | Type | Context |
---|---|---|
e1e0b887b68307ed192d393e886d8b982e4a2fd232ee13c2f20cd05f91358596 | SHA-256 | Winnti Rootkit |
c649e75483dd0883de2fef001a44263a272c6b49a8d1c9ea7c00c044495200ad | SHA-256 | Winnti Rootkit |
569c1d9b2822c17e64214421409c5649eafc5df9abd88d40a5554f57f32588e8 | SHA-256 | Winnti Rootkit |
169d35bdb36c2bfcb3bbf64392de1b05d56553172a13cae43a43acbe2aa18587 | SHA-256 | Winnti Loader |
b9d4ec771a79f53a330b29ed17f719dac81a4bfe11caf0eac0efacd19d14d090 | SHA-256 | Winnti Loader |
4608a63c039975fb8f3ffd221ec6877078542def44767f50447db1d514eb0779 | SHA-256 | Winnti Loader |
1e53559e6be1f941df1a1508bba5bb9763aedba23f946294ce5d92646877b40c | SHA-256 | Winnti Loader |
タグ
- セキュリティ
- 人材開発・教育
- システム開発
- アプリ開発
- モバイルアプリ
- DX
- AI
- サイバー攻撃
- サイバー犯罪
- 標的型攻撃
- 脆弱性
- 働き方改革
- 企業市民活動
- 攻撃者グループ
- JSOC
- もっと見る +
- JSOC INSIGHT
- サイバー救急センター
- サイバー救急センターレポート
- LAC Security Insight
- セキュリティ診断レポート
- サイバー・グリッド・ジャパン
- CYBER GRID JOURNAL
- CYBER GRID VIEW
- ラックセキュリティアカデミー
- すごうで
- ランサムウェア
- ゼロトラスト
- ASM
- EDR
- XDR
- SASE
- デジタルアイデンティティ
- インシデントレスポンス
- 情シス向け
- 対談
- CIS Controls
- Tech Crawling
- クラウド
- クラウドインテグレーション
- データベース
- アジャイル開発
- DevSecOps
- OWASP
- CTF
- FalconNest
- セキュリティ診断
- IoT
- EC
- サプライチェーンリスク
- スレットインテリジェンス
- テレワーク
- リモートデスクトップ
- アーキテクト
- プラス・セキュリティ人材
- 障がい者採用
- 官民学・業界連携
- カスタマーストーリー
- 白浜シンポジウム
- CODE BLUE
- 情報モラル
- クラブ活動
- 初心者向け
- 趣味
- カルチャー
- 子育て、生活
- 広報・マーケティング
- コーポレート
- ライター紹介
- IR