GitHub 上で OpenClaw の便利ツールを装った不審なリポジトリが発見され、実際に解析したところマルウェア(シェルコードローダー)であることが判明した。ひよっこサウナ氏(@hiyoko_sauna)による詳細な解析レポートを基に、この攻撃手法の全体像を紹介する。
対象リポジトリの特徴
github.com/sdwadsagw/OpenClawInstaller という、「Open Claw を簡単にインストールできるツール」として公開されていたリポジトリが対象だ。
| 項目 | 値 |
|---|---|
| アカウント作成日 | 2026-02-11(リポジトリと同日作成) |
| Star / Fork | 2 / 0 |
| 説明文 | 「AI assistant for Open Claw」 |
使い捨てアカウント(リポジトリと同日作成)という時点で怪しさ満点だ。
ZIP の中身
Claw-Installer-Open-2.8-alpha.3.zip を展開すると 4 ファイルが入っていた。
| ファイル | サイズ | VT 検出率 | 説明 |
|---|---|---|---|
| StartApp.bat | 22 bytes | - | start luau.exe asm.txt を実行するだけ |
| luau.exe | 288,768 bytes | 25/76 | LuaJIT 2.1.0-beta3(正規バイナリ) |
| lua51.dll | 390,144 bytes | 1/75 | LuaJIT 用ランタイム DLL |
| asm.txt | 309,298 bytes | 0/76 | 難読化された Lua スクリプト |
注目すべきは asm.txt の検出率が 0/76 という点だ。悪意のあるコードは asm.txt に書かれているのに検出されず、無害な luau.exe の方が検出されるという逆転現象が起きている。
LOLBin としての LuaJIT
luau.exe は正規の LuaJIT ランタイムで、攻撃者はこれを LOLBin(Living off the Land Binary) として悪用している。LOLBin とは、正規の署名付きバイナリを悪用して攻撃を行う手法で、正規ツールを使っているためセキュリティソフトによる検出が難しくなる。
asm.txt の難読化手法
309KB すべてが改行なしの 1 行で構成されており、以下のような難読化が施されていた。
| 手法 | 詳細 |
|---|---|
| カスタム VM | ディスパッチテーブルベースの仮想マシンで実行フローを隠蔽 |
| 文字列のバイトエンコード | すべての文字列が Lua デシマルエスケープに変換(\097\099\107 → “ack”) |
| 算術定数の難読化 | 単純な数値が (0x12345678 - 0x12344444) のような演算式に置換 |
| 関数名のランダム化 | 意味のない文字列に置換 |
| アンチタンパー | 解析環境の改ざん検知機構を搭載 |
解析で判明した悪意ある挙動
1. PE 構造体の定義(RunPE の準備)
スクリプトが ffi.cdef で Windows の PE ヘッダ構造体を定義していた。これは RunPE(Process Hollowing) と呼ばれる、別プロセスの中身を入れ替えて悪意あるコードを実行する手法の準備だ。
2. ウィンドウの非表示化
GetConsoleWindow() → ShowWindow(hwnd, SW_HIDE)
ユーザーに実行中であることを気づかせないための処理。
3. RWX メモリ確保とシェルコード実行
VirtualAlloc(size=10, protect=0x40) ← PAGE_EXECUTE_READWRITE
ffi.copy(rwx_mem, payload, 10) ← ペイロード書き込み
PAGE_EXECUTE_READWRITE(0x40) は読み取り・書き込み・実行がすべて可能なメモリ領域を確保するフラグで、正規アプリケーションがこのフラグを使うことはほぼない。
4. C2 通信の準備
Windows VM での動的解析では、正規の LuaJIT では通常ロードされない DLL が大量にロードされていた。
| DLL | 用途 |
|---|---|
| wininet.dll | HTTP/HTTPS 通信 |
| winhttp.dll | HTTP 通信 |
| WS2_32.dll | ソケット通信(Winsock) |
| urlmon.dll | URL 経由のダウンロード |
| DNSAPI.dll | DNS 名前解決 |
5. ボット ID の生成
%TEMP%\.ses(53 bytes)というセッションファイルが作成され、UNIX タイムスタンプ(感染時刻)と GUID(被害者の一意識別子)が記録されていた。
攻撃チェーン全体像
StartApp.bat
→ luau.exe asm.txt(正規 LuaJIT で難読化スクリプトを実行)
→ FFI で Windows API を呼び出し
→ コンソールウィンドウを非表示化
→ RWX メモリ確保 → シェルコード書き込み → 実行
→ ネットワーク系 DLL をロード(C2 通信準備)
→ %TEMP%\.ses にボット ID 生成
→ C2 サーバーへ通信
GitHub からツールを導入する際のチェックポイント
- アカウントの作成日が最近すぎないか
- Star 数や Fork 数が不自然に少なくないか
- README の内容がリポジトリの説明と一致しているか
- 難読化されたスクリプトやバイナリが含まれていないか
- VirusTotal で検出されなくても安全とは限らない
「便利そうだから」とすぐに実行するのではなく、一歩立ち止まって確認する習慣が大切だ。特に今回のケースでは、悪意あるスクリプト(asm.txt)の VT 検出率が 0/76 であり、「VirusTotal で引っかからなかったから安全」とは言い切れないことが示されている。
AI コーディングツールはマルウェアを検出できるか
Claude Code のような AI コーディングアシスタントを使う場合、リポジトリのコードが自動的にマルウェアスキャンされることを期待するかもしれないが、現状ではそのような機能はデフォルトで提供されていない。
Claude Code が提供する保護
- ツール実行時の許可確認: Bash コマンドやファイル操作の実行前にユーザーに許可を求めるパーミッションモードがある
- コードレビューでの指摘: 依頼すればセキュリティ上の懸念を指摘できる
- コマンド内容の可視化: 実行前にコマンドの内容を確認できる
Claude Code では防げないこと
- リポジトリのクローンやダウンロード時の自動マルウェアスキャン
- 難読化されたスクリプト(今回の asm.txt のような 309KB 1 行の Lua スクリプト)の自動検出
- 依存パッケージの網羅的なセキュリティ監査
多層防御が必要
今回のケースのように、正規バイナリ+検出不能な難読化スクリプトという組み合わせは、単一のツールでは防ぎきれない。以下のような多層防御が推奨される。
| レイヤー | ツール・手法 | 今回のケースでの有効性 |
|---|---|---|
| 静的解析 | VirusTotal、ClamAV | asm.txt は検出率 0/76 で 無効 |
| プラットフォーム | GitHub Secret scanning、Dependabot | 既知の脆弱性のみ対象、限定的 |
| エンドポイント | EDR(CrowdStrike、Defender for Endpoint 等) | 実行時の振る舞い検知で 有効な場合あり |
| 人間の判断 | アカウント作成日、Star 数、コードレビュー | 今回の発見のきっかけ、最も有効 |
| AI アシスタント | Claude Code 等でのコードレビュー依頼 | 依頼すれば不審なパターンを指摘可能、補助的 |
AI コーディングツールに過度な期待をせず、従来のセキュリティプラクティスと組み合わせて利用することが重要だ。