Engineering

Building the Hunter: Engineering a Windows Privilege-Escalation Surface Scanner

The Sherlock EoP Auditor is the productization of a manual workflow our lab has run by hand for years. This is the high-level engineering story. Why Rust. Why native Windows. Why three modules. Why the report reads like a researcher wrote it. No vulnerability specifics. This is about the tool.

The design problem

A working vulnerability researcher hunting local privilege escalation on Windows runs the same workflow on every target. Enumerate privileged services. Walk their local interfaces. Check authorization. Map untrusted load paths. Watch privileged operations for the recurring failure modes. The targets change. The moves do not.

The design question for the Auditor was: how do you put that workflow into software in a way that produces useful results without producing thousands of false positives or requiring a researcher to interpret the output. Two failure modes to avoid. Output that drowns the user in raw data. Output that hides the actual findings under generic alerts.

The answer is a deliberate choice to keep the judgment in the workflow but mechanize the moves.

Why Rust

Three reasons. Memory safety. Native Windows access. Distribution as a single binary.

Memory safety. A privilege escalation scanner that crashes when it hits a malformed PE header is worse than no scanner. Rust's memory safety guarantees mean a malformed binary does not become an arbitrary crash. The tool can keep running across an entire host inventory without hand-holding.

Native Windows access. The Windows API is large and ugly. C bindings expose it directly. Rust bindings via the windows crate expose it almost as directly with type safety on top. The Auditor needs to call NTAPI for some surface enumeration, walk PE imports, query service security descriptors and inspect named pipe ACLs. All of that is available in Rust with less risk than C and less overhead than C-sharp.

Single-binary distribution. Rust statically links by default. The Auditor ships as one executable. No runtime to install. No installer. Run it from a USB stick on an air-gapped host. The portable model matters for defenders who need to scan endpoints without leaving installation residue.

Three detection modules

The Auditor's detection logic is organized into three modules. Each module maps to one of the recurring local privilege escalation classes that researchers find by hand. The modules are independent and run in sequence.

Surface enumeration module. This module builds the map. Every service on the host. Every privileged process. Every local interface exposed. Named pipes. COM endpoints. LRPC ports. File system watchers. Each item gets cataloged with its owning process, privilege level and access control posture. The surface enumeration output is the foundation everything else runs on.

Runtime monitoring module. This module watches the privileged services interact with the system. Phantom DLL load candidates surface here. The module instruments the service activity and flags load attempts against directories under-privileged users can write to. The output is the candidate list for the load-path class.

Managed-code analysis module. This module performs static binary inspection of privileged service binaries to identify candidate findings within the three class categories the Auditor covers. Class assignment for each finding is documented in the resulting verdict output. The Labs page hosts the public disclosure for all Sherlock Forensics Labs findings; the Auditor module output is private per scan and shared only with the customer running the scan.

The reporting layer

The hardest part of building a security scanner is not the detection. It is the reporting. A scanner that produces a thousand findings per host has produced zero findings per host. The defender will not read it. The findings get tuned out. The scanner becomes shelfware.

The Auditor's reporting layer applies three principles.

Verdict per finding. Every candidate from the detection modules gets a verdict from the reporting layer. What it is. Why it matters. Whether a standard user can really reach it. The verdict is the answer the defender actually needed, not the raw data the detection module produced.

Severity that means something. Severity ranges are calibrated against actual exploitability and real-world impact. A finding that requires a chain of preconditions to reach SYSTEM gets a different severity than a finding a standard user can trigger directly. The defender uses severity to prioritize, so severity has to be honest.

Output formats that match defender workflows. Console output for ad-hoc scanning. JSON for pipeline integration. PDF report for handoff to leadership or auditors. The same scan run produces all three. No conversion step.

Engineering decisions on what NOT to build

Every tool's design is defined by what the team decided not to build. The Sherlock EoP Auditor has three deliberate non-features that distinguish it from competitor products.

No automatic exploitation. The Auditor identifies privilege escalation candidates. It does not execute them. The reason is operational discipline: a tool that elevates itself to SYSTEM to prove a finding is a tool that changes the system state. Any change to the system state during an audit is a forensic artifact that has to be documented. The Sherlock Forensics design choice is to surface the candidate, explain why it qualifies and let the customer decide whether to verify in a controlled environment. The default behavior is non-destructive.

No automatic remediation. The Auditor identifies the path and the candidate fix. It does not apply the fix automatically. The reason is that local privilege escalation fixes often involve permission tightening on directories and registry keys that legitimate applications depend on. An auto-fix tool that breaks the customer's payroll application has produced negative value. The customer applies the recommended fix during a maintenance window with verification testing. The Auditor's role is to make the customer's decision easier, not to make it for them.

No agent. No always-on monitoring. The Auditor is a portable executable run on demand. It does not install an agent. It does not run continuously. The reason is that always-on agents are an attack surface in their own right (the agent itself becomes a privileged service that an attacker can target). The Auditor's design is "run when you need it, get the answer, go away." For continuous monitoring needs, integration with existing SIEM or MDR products is on the roadmap, where the integration writes findings to the customer's existing telemetry stream rather than maintaining its own.

Detection module deep-dive

The three detection modules each implement a distinct technical approach matched to the class they target.

The surface enumeration module uses native Windows API calls (NtQuerySystemInformation, QueryServiceConfig, NtOpenDirectoryObject) to build a comprehensive list of privileged services and their exposed local interfaces. Named pipes get enumerated through directory object queries. COM endpoints get pulled from the COM catalog. The enumeration runs without elevated privilege when possible and with elevation when comprehensive coverage requires it.

The runtime monitoring module uses Event Tracing for Windows (ETW) to observe privileged service behavior in real time. The module subscribes to relevant ETW providers (file system, registry, process creation) and filters the event stream to actions taken by SYSTEM-level processes. Pattern matching on the filtered stream surfaces phantom DLL load candidates and untrusted load path patterns without requiring kernel-level instrumentation.

The managed-code analysis module uses static binary inspection plus disassembly to walk the command handler logic in privileged service binaries. The module identifies the entry points where the service reads commands from local interfaces and follows the handler dispatch logic to identify authorization patterns or their absence. The output is class-pattern matching against the lab's vulnerability research history, with each candidate annotated for severity and exploitability.

Why we build the tools we use

The Sherlock Forensics product line is the productization of internal tooling. The PST Viewer started as an internal forensic mailbox analysis tool before it shipped. The Disk Imager started as an internal acquisition tool. The Universal Events Viewer started as an internal Windows event log triage tool. The EoP Auditor follows the same pattern.

The reason is that building the tools we use forces clarity about what the tool actually needs to do. Internal use cases are the harshest critic. The team that has to use the tool in earnest does not tolerate inferior versions of work they could do by hand. The result is products that meet a higher bar than tools built without that feedback loop.

The downside is that every internal tool we ship was first a working product for one team for years. The development cycle is long. The shipping cadence is slow. The trade-off is product depth.

How the Sherlock EoP Auditor fits the existing product ecosystem

The Auditor does not replace anything in the Sherlock Forensics catalog. It complements the existing tools by covering a surface none of them addressed. The Sherlock Disk Imager covers acquisition. The Sherlock Universal Events Viewer covers Windows event log triage. The Sherlock PST Viewer covers mailbox forensics. The Sherlock NSF Viewer covers Lotus Notes archives. The Sherlock Android Acquirer covers mobile evidence. The EoP Auditor covers the preventive question "what attacker paths exist on this host before a breach occurs" that the other tools answer reactively post-breach.

For Sherlock Forensics services customers, the workflow becomes preventive plus reactive on the same toolchain. Before an incident: run the EoP Auditor on the fleet, surface the candidate findings, prioritize remediation. After an incident: the same examiner who scanned the fleet preventively now reads the breach timeline with the inventory baseline already in hand. The reconstruction is faster because the surface was already mapped.

For customers without an active Sherlock Forensics services engagement, the Auditor is a standalone product. Run it on whatever cadence your team can sustain. Use the findings to drive vendor pressure on the third-party software in your fleet. Integrate the JSON output into your SIEM or ticketing system to track remediation across endpoints. The product is designed to be useful without requiring a services engagement, while also fitting cleanly into an engagement when one is appropriate.

The roadmap

Sherlock EoP Auditor 1.0.0 is in early access while the PARTY LINE disclosure window completes with Brother. The product page is live with an early-access notification list.

Post 1.0.0 the roadmap focuses on three areas. Detection module expansion (new classes as the lab identifies them). Output integration (SIEM, ticketing system, MDR partner integrations). Cross-platform expansion (Linux privilege escalation surface is similar enough to motivate a port).

For the engineering-curious or anyone who wants to follow along, the Sherlock Forensics blog covers tool architecture as products mature. For the early-access notification list directly, sign up here.

The tool is the productization of a manual workflow our lab has run for years. Join the EoP Auditor early-access list or track our active research disclosures.