Skip to content

[Security] Five local privilege-boundary vulnerabilities (LPE, RCE, DOS/BUGCHECK, SYSTEM exec and telemetry bypass) #56

Description

@8damon

Hello OpenEDR maintainers,

I am reporting five reproducible local security issues affecting the stock OpenEDR 2.5.1 Windows endpoint.

PoC & Evidence

Full technical analysis, benign proof-of-concept clients, hashes, console output, Sysmon XML/EVTX evidence, and cleanup records are available here:

https://github.com/8damon/Pwning-OpenEDR

https://github.com/8damon/Pwning-OpenEDR/blob/main/reports/assessment.md

Findings

TSS-OEDR-004: Unauthenticated localhost RPC permits SYSTEM command execution

The LocalSystem edrsvc.exe service exposes an HTTP JSON-RPC listener on TCP 5889. Loopback is enforced, but the local caller is not authenticated or authorized.

The request encryption uses a static key embedded in the public source. After decryption, the RPC server dispatches caller-selected commands to objects.application. Its run command executes a caller-supplied executable and arguments as the service identity.

A standard user received HTTP 200 and caused edrsvc.exe to spawn a command as NT AUTHORITY\SYSTEM. Sysmon independently recorded the SYSTEM child process.

TSS-OEDR-002: Filename-derived trust can be chained into SYSTEM DLL loading

OpenEDR classifies processes whose paths end in names such as edrsvc.exe or edrcon.exe as product processes and forces them into the trusted state. Privileged driver configuration IOCTLs rely on this trust result.

This filename-only trust primitive was previously discussed in issue #49. A spoof-named standard-user process selects a protected application-dir path as the driver's log file. The kernel creates or overwrites that path, but the resulting file is owned by the requesting standard user.

After the driver releases the handle, the user can replace the file with an unsigned app-local dbghelp.dll. The genuine SYSTEM edrsvc.exe subsequently loads dbghelp.dll by bare filename.

TSS-OEDR-001: Standard user can stop and restart kernel monitoring

The START and STOP monitoring IOCTLs use FILE_ANY_ACCESS. Their dispatch handlers call startMonitoring() and stopMonitoring(true) without an administrator, service-SID, or authenticated-channel check. A standard user opened the driver device with zero requested access, successfully stopped monitoring, created activity during the gap, and restarted monitoring. The proof restored the original state.

TSS-OEDR-005: Standard user can control the user-mode telemetry gate

The service creates Global\edrCaptureEvent using a NULL DACL. Injected clients wait on this event before delivering user-mode telemetry. A standard user opened the event with modify rights, reset it, verified that it became nonsignaled, and restored it. This affects injected user-mode telemetry; it does not stop kernel-telemetry.

Tested environment

  • OpenEDR MSI: 2.5.1
  • edrsvc.exe: 2.5.1.0, running as LocalSystem
  • edrdrv.sys: 2.4.0.14
  • Windows 11 Pro x64
  • Stock local-mode installation with no custom policy or debug configuration
  • Source: release-2.5.1 at commit 95324d5414d9c700cdbb237047f0319eb7e9262c
  • Attacker: Medium-integrity local standard user

I also compared the affected source paths with current main at commit 30b36f203afbe5106c61812832bcd302d16c38fb. The relevant implementations remain unchanged.

Recommended remediation

  1. Remove generic process execution from the localhost RPC interface, or replace it with authenticated OS IPC restricted to a dedicated service SID.
  2. Do not use executable names or path suffixes as process identity. Authenticate the service through a protected per-boot channel or equivalent kernel-verifiable identity.
  3. Prevent untrusted callers from selecting privileged kernel file paths.
  4. Load service DLLs using absolute, protected paths and secure DLL-search settings.
  5. Require explicit authorization for every state-changing IOCTL and named synchronization object.
  6. Restrict minifilter communication ports and enforce per-message, per-client, and global allocation quotas.
  7. Treat STOP/START operations as privileged administrative controls and audit every attempt.

Please acknowledge receipt and provide a private security contact if you would prefer further coordination outside this public issue. I am available to retest proposed fixes and provide additional evidence.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions