← All posts

Auditing Windows Installer Repair Abuse: When MSI Self-Healing Becomes Persistence

How attackers abuse Windows Installer repair actions and elevated custom actions for persistence, plus the controls and telemetry defenders should verify.

Windows Installer is built to make software resilient. If a user deletes a key file or registry value, an advertised shortcut or application launch can trigger msiexec.exe to repair the product automatically. That convenience creates a subtle persistence surface: an attacker who can alter an MSI source, transform, cached package, or repairable resource may turn a routine self-heal into code execution.

This is different from the well-known AlwaysInstallElevated misconfiguration. Repair abuse can exist even when that policy is disabled. The important questions are what causes repair, where Windows Installer obtains the repair material, and which security context executes custom actions.

How self-healing becomes an attack path

Windows Installer tracks products, components, key paths, and source locations. When a component's key path is missing, the installer can restore it from the registered package. Attackers look for weak links in that chain:

A signed MSI is not a permanent guarantee of safe repair. The effective trust boundary includes every source file, transform, cache directory, and custom action used after installation.

What defenders should inventory

Start with products installed for all users and correlate them with the Windows Installer registry under HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer. Do not delete entries from this database: inventory them, then validate the package and source locations.

Get-CimInstance Win32_Product |
  Select-Object IdentifyingNumber, Name, Version, LocalPackage

Get-ChildItem 'HKLM:\SOFTWARE\Classes\Installer\Products' |
  Select-Object PSChildName

Be cautious with Win32_Product in production: querying it can initiate consistency checks. Prefer your software inventory platform or registry-based collection at fleet scale. For each product, verify that LocalPackage resolves beneath the protected C:\Windows\Installer cache, inspect registered source paths, and test ACLs with Get-Acl. A standard user should not be able to modify machine-wide installer sources or deployed transforms.

Telemetry that exposes suspicious repairs

A normal repair is usually rare, attributable to a deployment, and limited to a known product. Investigate clusters of installer activity outside maintenance windows and repairs followed by unusual child processes.

Hardening the repair chain

  1. Protect sources with least privilege. Deployment shares should grant endpoints read access only; package publishing must require a separate administrative identity.
  2. Remove unsafe custom actions. Vendors should avoid elevated custom actions that consume user-controlled properties or paths.
  3. Require package integrity. Sign packages and transforms, validate hashes in deployment tooling, and investigate cache/source mismatches.
  4. Use application control. WDAC or AppLocker can prevent a repaired application from loading an unexpected executable, DLL, or script.
  5. Baseline and monitor. Record installed product codes, source paths, transform registrations, and directory ACLs so drift becomes visible.

Where WinSentinel fits

On one machine, WinSentinel's full 64-module audit is free and unlimited. It helps expose the conditions that make installer repair dangerous: weak filesystem permissions, suspicious persistence points, unsafe policy settings, and unexpected software or process behavior.

WinSentinel Pro adds fleet orchestration rather than unlocking local checks. A central node can roll findings across dozens or hundreds of endpoints, highlight machines whose installer-related ACLs or policies drifted, dispatch follow-up scans, and produce compliance rollups. That distinction matters: the security logic runs with full power on every individual machine; Pro makes the resulting posture manageable as an organization.

Installer repair is supposed to restore a trusted state. Treat the entire repair chain as privileged infrastructure, and verify that every package, transform, source, and permission boundary preserves that trust.