CVE-2025-59953

LMDeploy Pickle Deserialization RCE via zmq_rpc.call_and_response() (CVE-2025-59953)

Initial Access Execution Last updated:

Detects exploitation of CVE-2025-59953, a critical (CVSS 9.8) unsafe Python pickle deserialization remote code execution vulnerability in InternLM's LMDeploy. The ZeroMQ RPC layer (zmq_rpc.call_and_response()) deserializes attacker-controlled messages with Python's pickle module, allowing an unauthenticated attacker who can reach the internal ZMQ RPC sockets to execute arbitrary code via a malicious pickle payload (CWE-502). Affected versions are >= 0.9.1 and < 0.10.2; fixed in 0.10.2. This detection surfaces suspicious child processes spawned by the LMDeploy Python service, anomalous inbound connections to LMDeploy ZMQ RPC ports, and pickle __reduce__ gadget indicators in traffic/logs.

Vulnerability Intelligence

Public PoC

Affected Software

Vendor
pip
Product
lmdeploy
Versions
>= 0.9.1, < 0.10.2

Weakness (CWE)

Timeline

Disclosed
September 16, 2026

CVSS

9.8
Critical (9.0–10)
CVSS vector not yet published
Write-up coming soon

What is CVE-2025-59953 LMDeploy Pickle Deserialization RCE via zmq_rpc.call_and_response() (CVE-2025-59953)?

LMDeploy Pickle Deserialization RCE via zmq_rpc.call_and_response() (CVE-2025-59953) (CVE-2025-59953) maps to the Initial Access and Execution tactics — the adversary is trying to get into your network in MITRE ATT&CK.

This page provides production-ready detection logic for LMDeploy Pickle Deserialization RCE via zmq_rpc.call_and_response() (CVE-2025-59953), covering the data sources and telemetry it touches: Microsoft Defender for Endpoint, DeviceProcessEvents. The queries below are rated critical severity at high confidence, and ship for 7 SIEM platforms — KQL, SPL, Elastic, QRadar, Sumo, YARA-L, LogScale.

MITRE ATT&CK

Tactic
Initial Access Execution
Microsoft Sentinel / Defender
kusto
let lmdeployParents = dynamic(["python","python3","lmdeploy","uvicorn","gunicorn"]);
let suspiciousChildren = dynamic(["sh","bash","dash","zsh","nc","ncat","netcat","curl","wget","powershell.exe","cmd.exe","whoami","id","perl","ruby"]);
DeviceProcessEvents
| where InitiatingProcessFileName has_any (lmdeployParents)
    and (InitiatingProcessCommandLine has_any ("lmdeploy","zmq_rpc","turbomind","pytorch_engine","api_server") )
| where FileName has_any (suspiciousChildren)
| project Timestamp, DeviceName, InitiatingProcessFileName, InitiatingProcessCommandLine, FileName, ProcessCommandLine, AccountName, InitiatingProcessId, ProcessId
| order by Timestamp desc

Flags shell/recon/network child processes spawned by an LMDeploy Python service, the primary post-exploitation signal of the pickle RCE.

critical severity high confidence

Data Sources

Microsoft Defender for Endpoint DeviceProcessEvents

Required Tables

DeviceProcessEvents

False Positives

  • Legitimate LMDeploy startup scripts that shell out to nvidia-smi or environment-setup wrappers
  • Administrators or CI pipelines running diagnostic commands inside the model-serving container
  • Model deployment automation invoking curl/wget to fetch weights or health-check endpoints

Sigma rule & cross-platform mapping

The detection logic for LMDeploy Pickle Deserialization RCE via zmq_rpc.call_and_response() (CVE-2025-59953) (CVE-2025-59953) above is provided in a vendor-neutral form so you can deploy it on any SIEM. The same logic is shipped here as native KQL (Microsoft Sentinel / Defender), SPL (Splunk), Elastic (Elastic Security (EQL)), QRadar (IBM QRadar (AQL)), Sumo (Sumo Logic CSE), YARA-L (Google Chronicle / SecOps), LogScale (CrowdStrike LogScale (CQL)) queries. In Sigma terms, this detection targets the following logsource:

logsource:
  category: process_creation
  product: windows

Browse the community-maintained Sigma rules for this technique:


Testing Methodology

Validate this detection against 3 adversary techniques from Atomic Red Team. Each test below lists the behaviour to exercise and the telemetry you should expect to see. Executable commands and cleanup steps are available with Pro.

  1. Test 1Simulate LMDeploy pickle RCE child shell spawn

    Expected signal: Process-creation event with parent image lmdeploy_sim (python) spawning /bin/sh executing id/whoami

  2. Test 2Malicious pickle __reduce__ gadget execution (lab)

    Expected signal: python3 process invoking os.system which spawns sh -c touch, plus creation of /tmp/cve_2025_59953_poc

  3. Test 3Inbound connection to LMDeploy ZMQ RPC port

    Expected signal: Network connection event to TCP/5555 carrying a pickle protocol marker (\x80) payload


Response Playbook

Triage

  1. Confirm the LMDeploy version on the affected host (pip show lmdeploy); any version >= 0.9.1 and < 0.10.2 is vulnerable and should be treated as exploitable.
  2. Identify the parent LMDeploy/Python process and inspect its command line for api_server/turbomind/zmq_rpc arguments and the listening ZMQ RPC ports.
  3. Review the suspicious child process command line, user context, and working directory to determine whether execution is malicious or benign automation.
  4. Correlate inbound network connections to the LMDeploy ZMQ RPC sockets around the process-spawn timestamp to identify the source host.

Containment

  1. Isolate the affected host/container from the network to stop further RPC-delivered pickle payloads.
  2. Restrict access to LMDeploy ZMQ RPC ports via firewall/security-group rules so only trusted internal hosts can reach them, and stop the exposed api_server if not needed.
  3. Upgrade LMDeploy to 0.10.2 or later on all affected systems before returning them to service.

Evidence Collection

  1. Capture the full process tree, command lines, and environment of the LMDeploy service and any spawned children.
  2. Preserve ZMQ RPC endpoint logs and any packet captures of traffic to the RPC ports, which may contain the pickle payload.
  3. Collect the LMDeploy application logs, container image digest, and pip freeze output for version confirmation.

Escalation Criteria

  • ! Escalate to incident response if any child process performed reconnaissance, credential access, lateral movement, or outbound C2 connections.
  • ! Escalate if the LMDeploy RPC port was reachable from untrusted networks (internet-exposed) or if payload delivery from an external source is confirmed.

Investigation Guide

Forensic Artifacts

  • > Process-creation records showing python/lmdeploy spawning shell or network utilities
  • > ZMQ RPC socket logs and packet captures containing pickle opcodes (e.g. leading \x80 protocol markers and 'c__builtin__' / posix system references)
  • > LMDeploy application and container logs around the spawn timestamp
  • > pip metadata (lmdeploy version) confirming exposure window

Tuning Guidance

Baseline the legitimate child processes of your LMDeploy deployment (e.g. nvidia-smi, environment wrappers, health-check curl) and add them to an allowlist keyed on parent command line plus child image plus arguments. Focus alerting on interactive shells, netcat, and reverse-shell patterns. If LMDeploy runs in a locked-down container that never legitimately spawns shells, tighten to alert on ANY unexpected child process. Prioritize hosts where the ZMQ RPC port is reachable beyond localhost.


Hunting Queries

Hunts for LMDeploy service processes spawning shell/network child processes across the fleet.

Hunting — KQL
kql
DeviceProcessEvents | where InitiatingProcessCommandLine has_any ("lmdeploy","zmq_rpc","api_server") | where FileName in~ ("sh","bash","nc","curl","wget") | summarize count() by DeviceName, InitiatingProcessCommandLine, FileName, bin(Timestamp,1h)
Hunting — SPL
spl
index=edr (parent_process=*lmdeploy* OR parent_process=*zmq_rpc*) process_name IN ("sh","bash","nc","curl","wget") | stats count by host parent_process process_name

Atomic Red Team Tests

Test 1 Simulate LMDeploy pickle RCE child shell spawn
linux

Emulates the post-exploitation signal by having a process named like the LMDeploy service spawn a shell command, matching the detection logic without exploiting a real instance.

Command

bash
cp /usr/bin/python3 /tmp/lmdeploy_sim 2>/dev/null; /tmp/lmdeploy_sim -c "import subprocess; subprocess.call(['/bin/sh','-c','id; whoami'])"

Cleanup

bash
rm -f /tmp/lmdeploy_sim

Expected Telemetry

Process-creation event with parent image lmdeploy_sim (python) spawning /bin/sh executing id/whoami

Expected Detection

KQL/SPL/EQL rules fire on the python-parent -> sh child correlation

Test 2 Malicious pickle __reduce__ gadget execution (lab)
linux

Deserializes a locally crafted malicious pickle in an isolated lab to reproduce the code-execution primitive behind CVE-2025-59953.

Command

bash
python3 -c "import pickle,os,base64; payload=pickle.dumps(type('e',(object,),{'__reduce__':lambda s:(os.system,('touch /tmp/cve_2025_59953_poc',))})()); pickle.loads(payload)"

Cleanup

bash
rm -f /tmp/cve_2025_59953_poc

Expected Telemetry

python3 process invoking os.system which spawns sh -c touch, plus creation of /tmp/cve_2025_59953_poc

Expected Detection

Endpoint rules flag the python-to-shell child process chain and file-creation artifact

Test 3 Inbound connection to LMDeploy ZMQ RPC port
linux

Generates an anomalous inbound TCP connection to a simulated LMDeploy ZMQ RPC listener to validate network-side detection and triage correlation.

Command

bash
python3 -c "import socket,threading,time; srv=socket.socket(); srv.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1); srv.bind(('0.0.0.0',5555)); srv.listen(1); threading.Thread(target=lambda:(time.sleep(1), socket.create_connection(('127.0.0.1',5555)).sendall(b'\x80\x04pickle_payload'))).start(); c,_=srv.accept(); print(c.recv(64)); srv.close()"

Cleanup

bash
pkill -f 'bind..0.0.0.0.,5555' 2>/dev/null; true

Expected Telemetry

Network connection event to TCP/5555 carrying a pickle protocol marker (\x80) payload

Expected Detection

Network/triage correlation flags inbound traffic to the LMDeploy RPC port around a process-spawn event

Related Detections