Skip to Main Content
Faint pattern of 1s and 0s on top of hexagons

Anatomy of a Cyber Attack: Stopping a Fileless Malware Breach

Faint pattern of locks, 1s and 0s on top of hexagons

Recently, the Mondas Security Operations Centre (SOC) successfully detected and contained a highly advanced GootLoader infection targeting one of our clients. This incident is a reminder of how easily a sophisticated attack can bypass standard defences, and why human-led monitoring, paired with best-in-class tools, is essential for robust information security.

Phishing Lure

On August 14, 2026, an employee inadvertently triggered a malware infection by interacting with a malicious link delivered via Microsoft Outlook. The link directed the user to a Gofile host, prompting the download of a ZIP archive containing a disguised JavaScript file. From the users perspective this was a potential client, sending documents in a very typical fashion, hard to detect and the result of a multi-stage phishing process.

Unaware of the danger, the user double-clicked the extracted file. Because the script executed silently in the background without any visual interface, the user believed nothing had happened. Consequently, they executed the malicious script a second time, and eventually re-downloaded the ZIP archive to try a third time.

This behaviour underscores a critical vulnerability in many organisations: honest human mistakes can rapidly escalate into severe security incidents if users are not adequately trained to recognise the implications of their actions.

GootLoader

The payload delivered was a variant of GootLoader, a sophisticated JavaScript-based malware loader active since 2020. GootLoader is notorious for its fileless execution, keeping its commands running entirely in the system’s Random Access Memory (RAM) to evade detection by standard antivirus software.

Once executed via the Windows Script Host, the malware immediately took steps to blind the system’s defences:

  • EDR Evasion: The script accessed low-level operating system functions by inspecting and unhooking ntdll.dll on the disk, successfully bypassing the monitoring hooks of Endpoint Detection and Response (EDR) tools. This method is used to bypass having to use BYOVD, this is not as effective but ntdll.dll is the lowest usermode layer.
  • AMSI Patching: It patched the Antimalware Scan Interface (AMSI) in memory, tricking the Windows operating system into believing all subsequent, heavily obfuscated code was clean.
  • Payload Delivery: A secondary payload was downloaded from a Command-and-Control (C2) server and executed via memory-only PowerShell commands.
  • Persistence: The malware established persistence by writing configurations into registry keys and registering a self-healing scheduled task disguised as an Adobe Updater, configured to run every 60 seconds. Malware of this nature is used as Initial Access, it creates a direct backdoor allowing attackers to drop any malware onto the device as fileless (loading them straight into memory). Decrypting raw Portable Executable bytes from registry into a heap buffer, manual maps sections into remote processes via WriteProcessMemory and NtAllocateVirtualMemory, fixes relocations, resolves imports, and finally hijacks execution with a pointer at the remote thread’s RIP at the entry point.

For more context on how threat actors leverage these techniques, 🔗read more about fileless threats and GootLoader tactics via the MITRE ATT&CK framework.

Containment by the SOC team

Despite the malware’s successful evasion of initial endpoint defences, the anomalous behaviour was detected by the Mondas SOC.

  • 09:34 AM: Mondas alerted the client to the suspicious activity and requested permission to isolate the virtual machine.
  • 09:46 AM: The device was fully isolated, completely stopping the threat in its tracks.

By moving quickly, our team prevented the threat actor from capitalising on their initial access. Had the attack not been interrupted, the attacker could have sold this access on the dark web or deployed destructive ransomware across the wider network. To ensure absolute safety, the compromised asset was permanently powered down and a fresh virtual machine was deployed.

Core Recommendations

Based on our forensic analysis of this incident, we recommend organisations take the following proactive steps to harden their environments:

  1. Implement Security Awareness Training: Phishing attacks are becoming increasingly sophisticated, often leveraging AI to enhance social engineering. Enrolling staff in regular security awareness training and phishing simulations is a proven way to reduce human risk.
  2. Harden GPO Script Associations: Modify default Group Policy Objects (GPO) so that .js and .jse files open with notepad.exe rather than the Windows Script Host (wscript.exe). This ensures that if a user accidentally clicks a malicious script, it opens as harmless text.
  3. Conduct User Acceptance Testing (UAT): Before rolling out GPO changes globally, conduct a UAT phase with a representative group of users to ensure legitimate business scripts remain functional.
  4. Strict Asset Decommissioning: If an asset is confirmed to have active backdoor persistent hooks, it must be completely wiped. Never power a compromised virtual machine back on in its current state.

About the Author: Lance Nevill, Cyber Security Director at Mondas 🔗Connect with Lance on LinkedIn.

If you are struggling with the issues outlined in this article, or if you want to ensure your organisation is protected against evasive fileless malware, Mondas specialises in this topic. Contact our expert SOC team today to secure your digital estate.

Article First Published: August 17, 2026

Deeper dive…

See the anatomy of the attack in our team’s deeper analysis:

Stage 1 & 2: JavaScript Dropper & Environment Check

The initial vector is a weaponized .js file executed locally by Windows Script Host (wscript.exe). It uses heavy string array obfuscation, dead-code loops, and character encoding to evade static antivirus signatures. Stage 2 checks the execution environment (WScript.FullName) to ensure it isn’t running inside an automated sandbox before issuing outbound HTTP Get requests via WinHttp.WinHttpRequest.

Stage 3: Obfuscated Batch Launcher (.bat)

The dropped batch file hides a 32-bit PowerShell command across dozens of dummy environment variables (set “asifniqeasifniqe919=…” ) interspersed with noise comments (REM). The script reassembles these environment variables into a single Base64-encoded, UTF-16LE Unicode string and executes it using 32-bit PowerShell (SysWOW64).

Stage 4: PowerShell Bootstrap Downloader

The decoded PowerShell script sets TLS 1.2 protocol compliance, strips inline string junk (.Replace(‘zahra’,’’) ) to construct C2 URLs, and attempts to pull the Stage 5 payload using System.Net.WebClient. If WebClient fails, it falls back to Invoke-WebRequest -UseBasicParsing. The downloaded script is compiled into memory as a script block
( [scriptblock]::Create ) and invoked filelessly.

Stage 5: Registry Stager & Scheduled Task Persistence

Stage 5 ensures single-instance execution via a system named Mutex (oeyrzvwpujkouuvv1133). It downloads a raw response string, slices out a specific offset
( $raw.Substring(268974, 1157120) ), and writes the configuration, C2 URLs and encrypted payload bytes into a newly created registry hive at HKCU:\Software\ftsagemgeuasfmgeas268

It establishes persistence by registering a hidden Windows Scheduled Task (AdobeGCUpdateTask213) using the Schedule.Service COM object to run every minute via conhost.exe

Stage 6: Native Shellcode Loader & Memory Injector

Stage 6 reads the hex string ($hx) stored in the registry, decrypts it using a multi-byte XOR key (ge34ui2g), and imports unmanaged Window APIs from kernel32.dll using C# P/Invoke (Add-Type). It creates a private executable heap (HeapCreate with flag 0x00040000), allocates buffer space (HeapAlloc), copies the raw shellcode bytes into RAM (Marshal.Copy), changes memory protection to PAGE_EXECUTE_READWRITE (0x40 via VirtualProtect), and executes the code via a C# delegate function pointer ($dd.Invoke() ).