NIKKEのPCランチャー改ざんと「乗っ取られた」insightjs.comの正体
目次
TL;DR
起きたこと Windows版PCランチャーが読み込む公式CDN上のJavaScriptファイル4件が9月27日に改ざんされ、外部サーバーから遠隔操作ツールをダウンロードする状態になっていた。9月27日15時41分以降にPCランチャーを起動した環境が対象で、モバイル版は影響を受けない。
ドメインの経緯 公式は insightjs.com を「乗っ取られた」としているが、研究者の調査では失効後に9月27日10時59分に再取得されたドメインだった。改ざん前の公式ファイルはこのドメインを参照しておらず、CDNへの不正な書き込み経路は分かっていない。
確認する場所 ランチャーのログ Launcher\intl_service\debug.log に k2f_chan registered の文字列があれば、遠隔操作ツールが起動・通信した痕跡を示す。ブラウザのパスワード保存データのコピー %TEMP%\k2f-bcreds-*.db は読み取り直後に削除されるため、不在でも漏洩がなかった証明にはならない。
「勝利の女神:NIKKE」のPCランチャーが、9月末から不正プログラムを配布できる状態になっていた。 運営のLevel Infiniteは11月5日に経緯を公表し、その中で「insightjs.com ドメインが第三者により悪意を持って乗っ取られる」と説明している。 ドメインが乗っ取られたとは具体的に何が起きたのか、それがランチャーの改ざんとどうつながるのかを、公式告知と研究者の解析レポートから確認した。 内容は11月5日22時時点の情報に基づく。
公式発表の経緯
Level Infiniteは11月5日に、経緯と対応をまとめたお知らせと、手動で確認する手順の案内を公開した(PCランチャーのセキュリティインシデントおよび今後の対応について、PCランチャーのセキュリティに関する手動確認方法のご案内)。 公表された経緯は次のようになる。
| 日時 | 公式の説明 |
|---|---|
| 9月27日 10時59分 | ゲームサービスの一部で利用していた insightjs.com ドメインが第三者に乗っ取られる |
| 9月27日 15時41分〜42分 | ランチャーがダウンロードする公式CDNのスクリプトファイル4件が改ざんされ、特定のドメインへ接続する不正なコードが追加される |
| 10月30日 3時52分 | 改ざんされたスクリプトを通じて、利用者のPCへ不正プログラムの配布が始まる |
| 11月4日 0時ごろ | ランチャーのスクリプトの異常に気づき、調査と対応を始める |
| 11月4日 2時4分〜23分 | 不正なスクリプト3件を差し替え、追加の配布を止める(第1次対応) |
| 11月4日 12時9分 | 残り1件に関係するCDNキャッシュの更新を終える(第2次対応) |
| 11月5日 8時 | 公式PCクライアントに、不正プログラムを検査・削除する機能が追加される |
CDN(Content Delivery Network)は、ファイルを世界各地のキャッシュサーバーに複製して高速に配信するインフラで、ランチャーの画面表示に使うJavaScriptファイルもここから読み込まれる。 対象は9月27日15時41分以降にWindows版PCランチャーを1回以上起動した環境で、モバイル版のみのプレイヤーは確認不要とされている。
配布の開始時期については、利用者側の報告と食い違いが見られる。 独立系の研究者MotherSphereがGitHub Gistで公開している解析レポート(MotherSphereの解析レポート)のコメント欄には、日本時間10月24日1時40分に遠隔操作ツールが起動した記録が寄せられており、公式発表の10月30日より6日早い。 この解析レポートは、被害者からの報告を取り込みながら更新が続いている。
「乗っ取られた」insightjs.comの登録履歴
ドメイン名は、登録事業者を通じて期間を決めて契約する仕組みになっている。 更新を行わずに期限が切れると、一定期間を経て誰でも同じ名前を再登録できる状態に戻る。 公式の「乗っ取られる」という表現からは使っていたドメインを奪われたようにも受け取れるが、解析レポートに記録された登録情報は、失効したドメインを第三者が新しく取得した形を示している。
| 項目 | 解析レポートの記載 |
|---|---|
| 登録日時 | 9月27日1時59分(GMT)、日本時間で10時59分。公式の「乗っ取られた」時刻と一致する |
| 登録事業者 | PDR Ltd.(PublicDomainRegistry)、所有者は非公開 |
| ネームサーバー | ns0.1984.is などアイスランドのホスティング事業者1984のもの |
| 以前の利用 | 証明書の公開記録(crt.sh)に、2019年8月〜2022年7月に api.insightjs.com と cdn.insightjs.com へ発行されたAmazonの証明書が19件ある。Wayback Machineには2017年のWebサーバー(IIS)の記録が残っている |
| 以前の利用者と今回の攻撃 | 両者を結び付ける証拠は見つかっていない |
公式は insightjs.com を「ゲームサービスの一部で利用していた」と説明しているが、2017年〜2022年に利用していた組織がLevel Infiniteだったのかは、公式告知にも解析レポートにも言及がない。
登録から書き換えまでの時間も約5時間と短かった。 登録情報や証明書の発行履歴、Wayback Machineの保存記録を日本時間で整理すると、ドメイン取得から短時間で公式ファイルが改ざんされている。
| 9月27日(日本時間) | 出来事 |
|---|---|
| 10時59分 | insightjs.com が再登録される |
| 12時0分 | insightjs.com と www.insightjs.com の最初の証明書が発行される |
| 13時8分 | insightjs.com がHTTPSへの自動転送を返し始める(13時56分にはnginxの403拒否画面を応答) |
| 15時41分〜42分 | 公式CDNの4ファイルが書き換えられる |
ただし、ドメインを取得しただけでは公式CDNのファイルを書き換えることはできない。 解析レポートでも、改ざん前のファイルには insightjs.com への参照が含まれていなかったことが確かめられている。 ランチャーが元々参照していたドメインを奪われたのではなく、ドメインの再取得と公式CDNの改ざんは別々に行われていた。
公式発表でも、どの経路でファイルが改ざんされたかを特定するためにCDNを含むネットワークを調査中としており、侵入経路は判明していない。 解析レポートでも、CDNへの書き込み権限がどのように奪われたかは未解明としたうえで、同様の手法で別のドメインを使って再び改ざんが行われる懸念を指摘している。
書き換えられたファイルと読み込みの流れ
改ざんされたのは次の4ファイルで、それぞれに insightjs.com からスクリプトを読み込むコードが追加されていた(MotherSphereの解析レポート)。
| 公式ファイル | 読み込む先 |
|---|---|
sg-gpts.playerinfinite.com の aegis-fix.min.js | https://insightjs.com/l.js?f=aegis |
na-webassets.playerinfinite.com の images.7fec4c32.js | https://insightjs.com/l.js?f=images |
na-webassets.playerinfinite.com の FeedList.feb647c9.js | https://insightjs.com/l.js?f=feedlist |
na-webassets.playerinfinite.com の vue-bucket.min.js | https://insightjs.com/l.js?f=vue |
追加されたコードは、接続先URLを数値配列に変換して難読化されていた。
insightjs.com へ接続できない場合は、ドメイン末尾を切り替えた insightjs.org へ接続を試みる。
FeedList.feb647c9.js では、追加された708バイトがファイルの最後ではなく最後の export 文の直前に挿入されており、末尾の差分比較だけでは検知をすり抜ける細工が施されていた。
読み込まれた l.js は、ランチャー本体が持つファイルダウンロード機能を利用して、https://analytics.insightjs.com/comm/assets/insight.bundle を取得する。
これが遠隔操作ツール(RAT: Remote Access Trojan)の本体(内部名K2F)で、中身はLuaJITの中間コード(バイトコード)だ。ランチャー側にLuaの実行環境が組み込まれていたため、実行ファイル(.exe)ではなくても動作した。
ランチャーはこれを Launcher\log\tinyget\ に .log 拡張子のファイル名で保存し、実行後にファイルを削除する。
10月24日ごろに報告された初期バージョンは k2f.lua という名前で保存されており、自己削除処理を持たなかったため、ファイルがそのまま残存している事例がある。
本体の配信は起動ごとに毎回行われるわけではなく、解析された環境では約19回の起動中3回のみ配信が確認された。
flowchart TD
A["9月27日10時59分<br/>insightjs.com を再登録"] --> C
B["9月27日15時41分<br/>公式CDNのJS 4件にコードを挿入<br/>侵入経路は調査中"] --> C
C["ランチャー起動時に<br/>insightjs.com の l.js を読み込む"] --> D
D["l.js がランチャーのダウンロード機能で<br/>insight.bundle を取得"] --> E
E["遠隔操作ツール K2F が起動<br/>debug.log に k2f_chan registered"] --> F
F["攻撃者サーバーの指示に基づき<br/>パスワード・Cookie・認証鍵を送信"]
予備として指定されていた insightjs.org は、11月3日時点では誰にも登録されていなかった。 日本時間11月4日2時55分に第三者によって登録され、現在は「NIKKE PC Launcher Security Alert」という警告ページが表示される。 このページは公式とは無関係の有志による注意喚起と記載されており、Level Infiniteの公式対応ではない。
遠隔操作ツールK2Fの動作と機能
K2Fは、定型処理を自動実行するタイプのマルウェアではなく、攻撃者のサーバーから届く命令を待って実行し、結果を返す遠隔操作ツールだ。 解析レポートが本体コードから確認した主な命令は次のようになっている。
| 命令 | 内容 |
|---|---|
exec | 任意のプログラムやコマンドを実行して出力を返す |
ls、cd、cat、download | フォルダー内を探索し、任意のファイルを持ち出す |
screens | 接続されている全ディスプレイのスクリーンショットを取得する |
creds | 通常版およびHMT(台湾・香港・マカオ)版ランチャーが保存したNIKKEのアカウントとパスワードを復号する(Google Play Games版の保存先は対象外だが、cat や download で持ち出し可能) |
browserscan | Chrome、Edge、Brave、Vivaldi、Opera、Firefoxの保存パスワードを収集する。設定(collect_cookies)が有効ならChromium系ブラウザのCookieも収集する |
keyscan | 認証情報や設定ファイルが存在する既知のパス264か所を探索して秘密情報を探す |
wallet_files | Chromeに導入された暗号資産ウォレット拡張機能28種のデータを取得する |
chrome_install | ChromeにDLLを読み込ませる仕組みを登録し、ランチャー終了後も常駐を維持する |
これらの命令はランチャーの通常ログには記録を残さないため、ログから過去にどの命令が実行されたかを特定することはできない。
解析レポートでは、ランチャーの実行マニフェストが管理者権限を要求する設定になっている点も報告されており、その場合はK2Fも管理者権限で動作する。
LinuxやSteam DeckのProton環境で動かしていた場合も、Wine経由でホームディレクトリやルート直下が Z: などのドライブとして認識されるため、cat や download によってファイルが取得される可能性がある。
保存パスワードの一時保存と復号
ブラウザの保存パスワードを収集する browserscan は、感染PC上でパスワードを復号(平文に戻す)してから送信する仕組みではない。
ChromeやEdgeのプロファイルごとに、パスワード保存用データベース(Login Data と Login Data For Account)、およびCookie収集設定時の Cookies を、1ファイルずつ一時フォルダー(%TEMP%)にコピーする。
作成されるコピーのファイル名は k2f-bcreds-<UNIX時刻>-<ランダム文字列>.db となる。
ツールはそのデータベースから対象サイト、ユーザー名、暗号化されたままのパスワード値を読み出し、復号鍵とともにサーバーへ送信し、実際の復号処理はサーバー側で行われる。
作成された一時ファイルはデータ抽出直後に削除される。
削除に失敗したファイルが残っていれば、ファイル名に含まれるUNIX時刻から browserscan が実行された日時を特定できる。
ただし、一時ファイルが見つからない場合でも、正常に消去されただけの可能性があるため、情報が盗まれていない証明にはならない。
全画面のスクリーンショットも同様に、%TEMP%\k2f_screen_<UNIX時刻>_<番号>.jpg として一時保存されたのちに送信・削除される。
Firefoxの場合は logins.json と key4.db がそのまま送信される。
解析されたPCの設定では collect_cookies は無効になっていたが、cat や download 命令を使えばCookieファイルを直接窃取できるため、無効設定であってもCookieの安全は担保されない。
ChromeやEdgeには、保存データを特定アプリからしか復号できないように保護する仕組み(App-Bound Encryption)が備わっている。
K2Fは、services.exe が保持するSYSTEM権限のトークンを取得してこの保護の回避を試み、ランチャーが管理者権限で動作している場合に回避が成功する。
開発環境やAIツールの認証情報
keyscan が探索する264か所のパスには、SSH秘密鍵、AWSやGoogle Cloudなどのクラウド認証情報、GitHub CLIやnpmの設定ファイルに加え、ローカル開発環境の認証ファイルが含まれている。
~\.claude\.credentials.json、Codexの auth.json、Gemini CLIの oauth_creds.json、VS Codeの mcp.json などが代表例だ。
ユーザーのホームディレクトリ(%USERPROFILE%)配下の code、dev、source、Documents、Desktop といったディレクトリも探索され、.env や docker-compose.yml が探される。
パスワードを変更するだけではこれらのAPIキーやトークンは無効化されないため、公式がパスワードの変更だけでなく、各種APIキーやアクセストークンの破棄と再発行を求めているのもこれが理由だ。
感染と遠隔操作の痕跡を確かめる場所
公式の手動確認手順では debug.log 内の文字列を第一の確認対象としており、解析レポートではそれ以外の痕跡も挙げられている。
表中の Launcher\ で始まるパスはNIKKEのインストール先フォルダを基準にした表記で、公式手順ではインストール先の例として C:\NIKKE や C:\NIKKE_GOOGLE(Google Play Games版)が示されている。
| 確認する場所 | 確認する項目 | 判明する内容 |
|---|---|---|
Launcher\intl_service\debug.log | k2f_chan registered | 遠隔操作ツールの起動・通信登録の履歴。公式手順でも、これが見つかった場合は不正プログラムが実行された可能性が高いとしている |
Launcher\log\tinyget\tinyget.*.log | insight.bundle の行 | 本体のダウンロード記録。処理行の後に curl perform success と total=205135 などの0より大きいサイズが記録されていれば取得完了を示す(result=2 や total=0 なら失敗) |
Launcher\log\tinyget\ | k2f.lua、先頭バイトが 1B 4C 4A 01 のファイル | 遠隔操作ツール本体。初期バージョンは k2f.lua として残存する場合がある。ファイル名に関わらず先頭がこのバイト列であればLuaJIT中間コード |
%APPDATA%\nikke_launcher\tbs_cache\Local Storage\leveldb\ | k2f.agent | 遠隔操作ツールの内部状態の記録。圧縮された .ldb ファイルに格納されると単純な文字列検索ではヒットしない場合がある |
HKEY_CURRENT_USER\Software\Classes\CLSID | {E77CC89B-7401-4C04-8CED-149DB35ADD04} | ChromeへのDLL読み込み設定。同名キーがHKLM(HKEY_LOCAL_MACHINE)にも存在するが、そちらはWindowsの標準項目 |
%LOCALAPPDATA%\Google\Chrome\User Data\PlatformExperienceHelper\ | 64桁の16進数フォルダと platform_experience_helper.dll | 常駐用のDLLファイル(PlatformExperienceHelper フォルダ自体はChromeが正規に作成するもの) |
%TEMP% | k2f-bcreds-*.db、k2f_screen_*.jpg | 一時ファイルの削除漏れ。ファイル名からパスワード収集や画面取得が行われた時刻を特定できる |
| DNSサーバーやルーターの通信ログ | insightjs.com、analytics.insightjs.com の名前解決記録 | 前者はスクリプト読み込み段階、後者はツール本体の取得段階まで進んだ可能性が高い |
debug.log はランチャー起動ごとに追記されるため、過去の起動ログも保持される。
ただし、NIKKEのフォルダ自体を削除・再インストールしている場合はログも消失する。
公式PCクライアントの検査機能は、不正プログラムを検知すると関連ログ、DLL、レジストリを削除するか確認するダイアログを表示する。
解析レポートでは、ランチャーのキャッシュフォルダ tbs_cache にも痕跡が残るため、削除前に確認するかバックアップを取るよう推奨している。
感染の有無を後から調べる場合は、検査機能による削除前に debug.log と tbs_cache を退避しておく必要がある。
ただし、これらの痕跡から持ち出された具体的なデータの内容までは特定できない。
公式と解析レポートが求めている対応
公式発表では、不正プログラムの影響を受けていない別端末、またはセキュリティチェックを完了したPCから、次の対応を行うよう求めている。
| 対応 | 内容 |
|---|---|
| パスワードの変更 | 該当PCで利用したことのある全アカウントのパスワードを変更する |
| APIキーとアクセストークンの再発行 | 該当PCで利用・保存していた認証情報をすべて破棄し、新規発行する |
ゲーム外アカウントの異常や金銭的被害については、公式カスタマーサポートで相談を受け付けている。 再発防止策としては、ランチャーおよび関連システムの監視強化、外部読み込みリソースの改ざん検知(完全性検証)の導入、ランチャー機能の権限最小化が挙げられている。
解析レポートでは、マルウェアが動作していた場合の追加対応として次の項目を推奨している。
| 推奨対応 | 理由 |
|---|---|
| 全セッションからのログアウト | 盗まれたセッションCookieがあれば、パスワード変更後も不正ログインを維持されるため |
| SSH鍵や開発用認証情報の再生成 | keyscan によって秘密情報が探索・窃取された恐れがあるため |
| 暗号資産ウォレットの移行 | ブラウザ拡張機能のデータと入力済み復元フレーズが狙われているため |
| Windowsの再インストール | exec による任意コード実行が可能だったため(常駐DLLを検知できなかったセキュリティソフトの報告もある) |
| 不審な通信先の遮断 | insightjs.com、analytics.insightjs.com、insightjs.org および攻撃者サーバーIP(89.127.233.127, 89.126.250.172)を hosts やルーターでブロックする |
insightjs.com と analytics.insightjs.com は、日本時間11月5日8時の時点でも攻撃者のサーバーIPを指した状態が続いていた。 ランチャーの改ざん自体は修正されたものの、PC側での痕跡確認と認証情報の更新は各自で速やかに行う必要がある。