MALFEXキャンペーンが悪意のあるnpmローダーをWindows DLLに変換
Detection stack
- AIDR
- Alert
- ETL
- Query
概要
MALFEXとして追跡されている悪意のあるnpmキャンペーンは、そのローダーロジックをコンパイルされたNode.jsネイティブアドオン(DLL)に移行することで進化しました。この imgdecode パッケージはGitHubから暗号化されたシェルコードを取得し、 dllhost.exe プロセスに注入します。この変更により、脅威は従来のインストールスクリプト保護を回避し、開発環境を通じてWindows開発者を直接ターゲットにします。
調査
SafeDepの研究者は imgdecode バージョン1.0.0から1.0.3までを分析し、パッケージがプロセス注入を実行するためにネイティブC++ DLLを使用していることを発見しました。彼らはAES-256-CBCキー nif-runtime-2027 でペイロードを解読し、npmパッケージからGoベースのダウンローダー、最終的には高度なWindowsスティーラー/RATへの感染チェーンを追跡しました。最終ペイロードには、分析回避技術やログ改ざん機能も含まれています。
緩和策
組織は開発環境内の未検証のnpmパッケージを制限し、未知の外部ホストへの接続をブロックするために厳密な出口フィルタリングを実施するべきです。検出は node.exe の生成 dllhost.exe またはコードリポジトリへの予期しない接続の確立に焦点を当てるべきです。Node.js環境における異常なネイティブアドオンのロード動作を監視することも、悪意のある活動の早期警告を提供することができます。
対応
MALFEX関連のパッケージをロードしていると疑われるワークステーションは、直ちにネットワークから隔離する必要があります。インシデント対応者は、システムを再起動する前に注入されたシェルコードをキャプチャするために、メモリフォレンジックを優先するべきです。封じ込めが完了したら、ブラウザパスワード、Discordトークン、クラウドプロバイダキーを含むすべての潜在的に露出した資格情報を更新してください。
攻撃フロー
この部分はまだ更新中です。
検出
可能な永続ポイント [ASEPs – ソフトウェア/NTUSERハイブ] (レジストリエベント経由)
異常なプロセスによって開始された可能性のあるGitHubファイルのダウンロード(ネットワーク接続経由)
疑わしいスケジュールされたタスク(監査経由)
直接IP経由の疑わしいファイルダウンロード(プロキシ経由)
IOCs (HashSha256) を検出する: MALFEXがそのnpmローダーをネイティブWindows DLLに移動
IOCs (SourceIP) を検出する: MALFEXがそのnpmローダーをネイティブWindows DLLに移動
IOCs (DestinationIP) を検出する: MALFEXがそのnpmローダーをネイティブWindows DLLに移動
imgdecodeにおけるMALFEX npmローダーによる悪意のあるプロセス注入の検出 [Windows Sysmon]
MALFEX imgdecode Node.jsローダーの検出 [Windowsプロセス作成]
シミュレーション実行
-
攻撃の概要とコマンド: 攻撃者は開発者をうまく騙して悪意のあるnpmパッケージをインストールさせました。標準のAVによる検出を避けるために、パッケージはネイティブNode.jsアドオン (
imgdecode.node) を使用して「Living-off-the-Land」プロセス注入を行います。目的は、正当なWindowsプロセスにシェルコードを注入して信頼されたプロセス名の下に悪意のある活動を隠すことです。シミュレーションでは、PowerShellスクリプトを使用してAPIコール (dllhost.exe) を模倣します (VirtualAllocEx,WriteProcessMemory,CreateRemoteThread) ファイル名 (imgdecode.nodeをターゲットにしますdllhost.exe. -
回帰テストスクリプト:
# MALFEX imgdecode注入を模倣するシミュレーションスクリプト # 注: このスクリプトは、規則の「Image」要件に合致するダミーファイルを作成します $targetProcess = "dllhost.exe" $fakeModule = "imgdecode.node" # 1. 画像パスの要件を満たすためにダミーディレクトリと偽の.nodeファイルを作成する $tempDir = Join-Path $env:TEMP "malfex_sim" New-Item -ItemType Directory -Force -Path $tempDir | Out-Null $fakeFilePath = Join-Path $tempDir $fakeModule New-Item -ItemType File -Force -Path $fakeFilePath | Out-Null Write-Host "[+] ダミーモジュールを作成しました: $fakeFilePath" # 2. プロセス注入シミュレーションを実行する # Add-Typeを使用してWin32 APIに直接アクセスし、CallTraceにターゲット関数を確実に含める $code = @" using System; using System.Runtime.InteropServices; public class Injector { [DllImport("kernel32.dll")] public static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId); [DllImport("kernel32.dll")] public static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect); [DllImport("kernel32.dll")] public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, uint nSize, out IntPtr lpNumberOfBytesWritten); [DllImport("kernel32.dll")] public static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId); [DllImport("kernel32.dll")] public static extern uint GetCurrentProcessId(); } "@ Add-Type -TypeDefinition $code # 実行中のdllhost.exeプロセスを探す $process = Get-Process dllhost -ErrorAction SilentlyContinue if ($null -eq $process) { Write-Host "[-] dllhost.exeが実行されていません。開始します..." Start-Process dllhost.exe Start-Sleep -Seconds 2 $process = Get-Process dllhost } $pid = $process.Id Write-Host "[+] ターゲット $targetProcess (PID: $pid)" # プロセスを開く $ hProcess = [Injector]::OpenProcess(0x001F0FFF, $false, $pid) # メモリを割り当てる(CallTraceでVirtualAllocExをトリガー) $remoteMem = [Injector]::VirtualAllocEx($hProcess, [IntPtr]::Zero, 1024, 0x3000, 0x40) Write-Host "[+] メモリを割り当てました: $remoteMem" # シェルコードを書き込む(CallTraceでWriteProcessMemoryをトリガー) $shellcode = [byte[]] @(0x90, 0x90, 0x90, 0x90) # NOPスレッド $bytesWritten = [IntPtr]::Zero [Injector]::WriteProcessMemory($hProcess, $remoteMem, $shellcode, 4, [ref]$bytesWritten) Write-Host "[+] リモートプロセスにシェルコードを書き込みました" # リモートスレッドを作成する(CallTraceでCreateRemoteThreadをトリガー) Write-Host "[+] リモートスレッドを作成しました。検出がトリガーされるはずです。" Write-Host "[!] シミュレーション完了。SIEMでアラートを確認してください。" -
クリーンアップコマンド:
# シミュレーションアーティファクトのクリーンアップ Stop-Process -Name "dllhost" -Force -ErrorAction SilentlyContinue Remove-Item -Path "$env:TEMPmalfex_sim" -Recurse -Force -ErrorAction SilentlyContinue Write-Host "[+] クリーンアップ完了。"