Back to Intelligence

CVE-2026-20350: Cisco ThousandEyes Virtual Appliance DHCP Command Injection — Detection and Remediation Guide

SA
Security Arsenal Team
September 22, 2026
14 min read

The Zero Day Initiative has published ZDI-26-719, disclosing CVE-2026-20350 — a command injection vulnerability in the DHCP client component of the Cisco ThousandEyes Virtual Appliance that allows remote attackers to execute arbitrary code on affected installations. ZDI has assigned a CVSS rating of 7.2 (High).

This one matters more than the score might suggest. ThousandEyes virtual appliances are deployed deep inside enterprise networks — in data centers, branch offices, and cloud VPCs — precisely so they can observe internal network performance. That means they sit on trusted segments with broad visibility into internal routing, DNS, and application paths. A compromised ThousandEyes agent is a compromised vantage point inside your perimeter, running with the privileges of a network monitoring platform that defenders rarely treat as a hostile asset.

The vulnerability class is equally important: DHCP client-side command injection. This means the attack surface is not a management web interface or an authenticated API — it is the appliance's handling of DHCP responses. Any attacker who can position a rogue or compromised DHCP server (or intercept DHCP traffic) on the same Layer 2 segment as the appliance's interface can potentially deliver malicious DHCP options that get executed by shell scripts in the DHCP client hook chain. ZDI's advisory notes that authentication context applies to exploitation (the summary indicates authentication is required in the documented scenario), but DHCP-adjacent attacks typically only require network adjacency on the broadcast domain — defenders should treat any host with a DHCP-configured interface on an untrusted or flat segment as exposed.

If you run ThousandEyes Enterprise Agents as virtual appliances, you need to inventory them, verify their network placement, apply Cisco's fix, and hunt for signs of abuse. This post walks through all of it.

Technical Analysis

Affected Products

AttributeDetail
ProductCisco ThousandEyes Virtual Appliance (Enterprise Agent)
ComponentDHCP client (dhclient / DHCP hook scripts)
CVECVE-2026-20350
ZDI AdvisoryZDI-26-719
CVSS7.2 (High)
ImpactArbitrary command/code execution on the appliance
Advisory URLhttp://www.zerodayinitiative.com/advisories/ZDI-26-719/

ThousandEyes virtual appliances are Ubuntu-based Linux images distributed as OVA/VM packages, deployed on hypervisors (VMware, Hyper-V) or cloud marketplaces. The vulnerable component is the DHCP client stack and its associated hook/exit scripts, which process server-supplied options such as hostname, domain name, and other string fields. These scripts are a historically fertile injection surface because DHCP option values are frequently interpolated into shell commands without adequate sanitization.

How the Vulnerability Works (Defender's View)

The attack chain, from a blue-team perspective, looks like this:

  1. Positioning: The attacker gains a foothold on the same Layer 2 broadcast domain as the ThousandEyes appliance's DHCP-configured interface — e.g., via a compromised host in the same VLAN, a malicious VM in the same virtual switch, or an attacker-controlled device plugged into a branch network. In cloud deployments, this could mean another tenant workload or a compromised instance sharing the virtual network segment.
  2. Rogue DHCP response: The attacker operates a rogue DHCP server (or performs DHCP spoofing/starvation to win the race against the legitimate server). When the appliance boots, renews its lease, or requests an address, the rogue server responds first.
  3. Malicious option injection: The crafted DHCP response includes a maliciously formed option value (classically, fields like hostname or domain-name containing shell metacharacters such as backticks, $(), or ;).
  4. Execution via hook scripts: The DHCP client processes the response through its hook scripts (/etc/dhcp/dhclient-enter-hooks.d/, /etc/dhcp/dhclient-exit-hooks.d/, or distribution equivalents such as NetworkManager dispatcher scripts). The unsanitized option value is evaluated in a shell context, and the injected command executes — typically as root, since DHCP client hooks run with elevated privileges.
  5. Post-exploitation: Root on the appliance means persistence (cron, systemd units, SSH keys), credential harvesting, and lateral movement from a host that legitimately talks to internal services and to Cisco's cloud.

Key exploitation characteristics:

  • No prior authentication to the appliance itself is required for the network-adjacent attack path — the attacker interacts with the DHCP client, not a login interface. ZDI's CVSS 7.2 vector reflects the requirements around attacker positioning and context; regardless of scoring nuance, the practical exposure is determined by who controls DHCP on the segment where your agents live.
  • Trigger events are predictable: lease renewal (often every few hours), interface bounce, and appliance reboot all re-expose the client.
  • Code execution context is privileged: DHCP hook scripts execute as root, making this a full appliance compromise, not a sandboxed foothold.

Exploitation Status

As of this writing, ZDI-26-719 is a coordinated disclosure — the vulnerability was reported to Cisco through ZDI's program and published per their advisory timeline. There is no confirmed in-the-wild exploitation, no public proof-of-concept, and CVE-2026-20350 is not currently listed in CISA's Known Exploited Vulnerabilities (KEV) catalog.

That said, DHCP client injection flaws are well understood by offensive practitioners, and the technique (rogue DHCP + option injection) requires no novel exploit development once details are public. Treat the window between disclosure and your patch as your exposure window. If your appliances sit on segments where rogue DHCP is plausible — shared branch networks, poorly segmented VLANs, or cloud VPCs with mixed trust workloads — treat this as urgent.

Detection & Response

Detection strategy for this flaw centers on three observable behaviors:

  1. DHCP client processes spawning shells or interpreters — dhclient hook execution of attacker commands will appear as child processes of dhclient, NetworkManager, or hook script interpreters.
  2. Rogue DHCP server activity on the segment — unexpected DHCPOFFER/DHCPACK sources, or multiple DHCP servers responding.
  3. Post-exploitation artifacts — new root-owned persistence (cron, systemd units, authorized_keys) on the appliance.

SIGMA Rules

These rules target Linux endpoint telemetry (Sysmon for Linux, auditd, or equivalent EDR process creation logs) ingested from ThousandEyes appliances or your Linux estate broadly. The DHCP-client-spawning-shell rule is high-fidelity: legitimate dhclient hooks never spawn interactive shells, curl/wget pipes, or base64 decoders.

YAML
---
title: DHCP Client or Hook Script Spawning Suspicious Child Process
id: 3f8a2c71-9b4e-4d5a-a1c6-7e2f8b0d1a3c
status: experimental
description: Detects shells, interpreters, or download tools spawned as children of DHCP client processes or hook scripts, consistent with DHCP option command injection (e.g., CVE-2026-20350 against Cisco ThousandEyes Virtual Appliance).
references:
  - http://www.zerodayinitiative.com/advisories/ZDI-26-719/
  - https://attack.mitre.org/techniques/T1059/004/
author: Security Arsenal
date: 2026/04/06
tags:
  - attack.execution
  - attack.t1059.004
logsource:
  category: process_creation
  product: linux
detection:
  selection_parent:
    ParentImage|endswith:
      - '/dhclient'
      - '/dhclient-script'
      - '/NetworkManager'
      - '/dhcpcd'
  selection_hooks:
    ParentImage|contains:
      - '/dhclient-enter-hooks.d/'
      - '/dhclient-exit-hooks.d/'
      - '/dispatcher.d/'
  selection_child:
    Image|endswith:
      - '/bash'
      - '/sh'
      - '/dash'
      - '/python'
      - '/python3'
      - '/perl'
      - '/curl'
      - '/wget'
      - '/nc'
      - '/ncat'
      - '/base64'
      - '/socat'
  condition: (selection_parent or selection_hooks) and selection_child
falsepositives:
  - Rare; legitimate dhclient hooks do not spawn interactive shells or download tools. Custom NTP/DNS hook scripts may invoke resolvconf or ntpdate — those are excluded by the child image list.
level: high
---
title: Shell Execution via Shell Metacharacters in Environment or Command Line After DHCP Event
id: 8c1d4e92-5a6b-4f3c-9d2e-1b7a6c0e5f2d
status: experimental
description: Detects command lines containing command substitution or chained shell execution patterns typical of injected DHCP option values being evaluated, on systems acting as network monitoring appliances.
references:
  - http://www.zerodayinitiative.com/advisories/ZDI-26-719/
  - https://attack.mitre.org/techniques/T1059/
author: Security Arsenal
date: 2026/04/06
tags:
  - attack.execution
  - attack.t1059.004
logsource:
  category: process_creation
  product: linux
detection:
  selection_user:
    User|contains:
      - 'root'
  selection_pattern:
    CommandLine|contains:
      - '`wget'
      - '`curl'
      - '$(wget'
      - '$(curl'
      - '; wget'
      - '; curl'
      - '; bash'
      - '; sh -c'
      - '| bash'
      - '| sh'
      - 'base64 -d'
      - 'base64 --decode'
  filter_legit:
    ParentImage|endswith:
      - '/apt'
      - '/dpkg'
      - '/cloud-init'
  condition: selection_user and selection_pattern and not filter_legit
falsepositives:
  - Package management and cloud-init operations legitimately use some of these patterns; excluded via parent filter. Tune for your automation tooling (Ansible, SSM) if it produces similar command lines.
level: medium
---
title: New Persistence Mechanism Created Under Root on Network Appliance
id: 5e2b7f04-3c8d-4a1e-b6f9-0d4c8a2e7b1f
status: experimental
description: Detects creation of cron jobs, systemd units, or authorized_keys modifications shortly following potential DHCP-based compromise of a Linux network appliance.
references:
  - http://www.zerodayinitiative.com/advisories/ZDI-26-719/
  - https://attack.mitre.org/techniques/T1053/003/
  - https://attack.mitre.org/techniques/T1543/002/
  - https://attack.mitre.org/techniques/T1098/004/
author: Security Arsenal
date: 2026/04/06
tags:
  - attack.persistence
  - attack.t1053.003
  - attack.t1543.002
  - attack.t1098.004
logsource:
  category: file_event
  product: linux
detection:
  selection:
    TargetFilename|contains:
      - '/etc/cron.d/'
      - '/etc/crontab'
      - '/var/spool/cron/'
      - '/etc/systemd/system/'
      - '/root/.ssh/authorized_keys'
      - '/home/'
  selection_keys:
    TargetFilename|endswith:
      - '/.ssh/authorized_keys'
  condition: selection or selection_keys
falsepositives:
  - Legitimate system administration and configuration management (Ansible, Puppet) writing units or keys. Baseline appliance change windows and alert on out-of-window writes.
level: medium

KQL (Microsoft Sentinel / Defender)

If you forward syslog/auditd from your ThousandEyes appliances (or Linux estate) into Sentinel — and you should — these hunts identify both the injection behavior and rogue DHCP indicators. The first query hunts the process-execution chain via Syslog; the second hunts anomalous DHCP server sources in network device logs (CEF/syslog from switches, firewalls, DHCP guard-capable infrastructure).

KQL — Microsoft Sentinel / Defender
// Hunt 1: Shells/interpreters spawned by DHCP client components (CVE-2026-20350 pattern)
Syslog
| where TimeGenerated > ago(7d)
| where ProcessName in~ ("dhclient", "dhclient-script", "NetworkManager", "dhcpcd", "bash", "sh")
    or SyslogMessage has_any ("dhclient", "dhclient-script", "dispatcher.d")
| where SyslogMessage has_any ("/bin/bash", "/bin/sh", "wget", "curl", "base64 -d", "nc ", "python", "$(", "; sh", "| sh", "| bash")
| project TimeGenerated, Computer, ProcessName, SyslogMessage, HostIP
| order by TimeGenerated desc
;
// Hunt 2: Potential rogue DHCP server indicators from network/security device telemetry
CommonSecurityLog
| where TimeGenerated > ago(7d)
| where Message has_any ("DHCPOFFER", "DHCPACK", "rogue dhcp", "dhcp snooping", "DHCP_SNOOPING")
    or DeviceVendor has_any ("Cisco", "Aruba", "Juniper") and Message has "dhcp"
| where Message has_any ("denied", "blocked", "rogue", "unexpected", "untrusted")
| summarize EventCount = count(), SampleMessages = make_set(Message, 5) by SourceIP, DestinationIP, DeviceProduct, bin(TimeGenerated, 1h)
| order by EventCount desc

For Defender for Endpoint onboarded Linux appliances, this process-tree hunt is the tighter, lower-noise option:

KQL — Microsoft Sentinel / Defender
// Hunt 3: DHCP client process tree spawning shells or tooling (MDE Linux)
let dhcpParents = dynamic(["dhclient", "dhclient-script", "NetworkManager", "dhcpcd"]);
DeviceProcessEvents
| where TimeGenerated > ago(7d)
| where InitiatingProcessFileName in~ (dhcpParents)
| where FileName in~ ("bash", "sh", "dash", "curl", "wget", "nc", "ncat", "socat", "base64", "python3", "perl")
    or ProcessCommandLine has_any ("$(", "`curl", "`wget", "base64 -d", "| sh", "| bash")
| project TimeGenerated, DeviceName, InitiatingProcessFileName, InitiatingProcessCommandLine,
          FileName, ProcessCommandLine, AccountName, ReportId
| order by TimeGenerated desc

Velociraptor VQL

Deploy this as a hunt across your ThousandEyes appliances (Velociraptor supports Linux clients) to sweep for the two primary forensic artifacts: suspicious process lineage involving DHCP components, and recent persistence writes. Run it immediately, then again after lease-renewal cycles.

VQL — Velociraptor
-- CVE-2026-20350 hunt: DHCP client child processes and recent persistence artifacts on ThousandEyes appliances

-- Part 1: Process lineage — shells or tooling parented to DHCP client components
SELECT Pid, Ppid, Name, Exe, CommandLine, Username, CreateTime
FROM pslist()
WHERE CommandLine =~ '(?i)(wget|curl|base64|nc |ncat|socat|/bin/bash|/bin/sh|\$\()'
   OR Name =~ '(?i)^(dhclient|dhclient-script|dhcpcd)$'
ORDER BY CreateTime DESC

-- Part 2: Recent persistence modifications (cron, systemd, SSH keys) in the last 14 days
SELECT FullPath, Size, Mtime, Ctime
FROM glob(globs=[
  '/etc/cron.d/*',
  '/etc/cron.daily/*',
  '/etc/systemd/system/*.service',
  '/etc/systemd/system/*.timer',
  '/root/.ssh/authorized_keys',
  '/home/*/.ssh/authorized_keys'
])
WHERE Mtime > (now() - 1209600)
ORDER BY Mtime DESC

-- Part 3: Established outbound connections from non-standard processes (post-exploitation beaconing)
SELECT Pid, Name, Path, Status, LocalAddr, LocalPort, RemoteAddr, RemotePort
FROM netstat()
WHERE Status =~ 'ESTABLISHED'
  AND NOT Name =~ '(?i)(te-agent|thousandeyes|sshd|systemd|chronyd|ntpd|snapd)'

Verification & Hardening Script

Run the following on each ThousandEyes virtual appliance (via console/SSH) to verify DHCP configuration exposure, check for signs of compromise, and apply interim hardening while you schedule Cisco's update. Where the appliance is a locked-down vendor image, some checks may require Cisco TAC guidance — adapt accordingly.

Bash / Shell
#!/bin/bash
# CVE-2026-20350 — ThousandEyes Virtual Appliance exposure & integrity check
# Run as root. Review output; do NOT blindly auto-remediate a vendor appliance image.

echo "=== [1] Appliance identity and version ==="
cat /etc/os-release 2>/dev/null | head -5
# Check ThousandEyes agent version — compare against Cisco's fixed release in their advisory
( te-agent --version 2>/dev/null || dpkg -l 2>/dev/null | grep -i thousandeyes || rpm -qa 2>/dev/null | grep -i thousandeyes )

echo "=== [2] DHCP usage on interfaces (static IP eliminates this attack surface) ==="
# Any interface using DHCP is exposed to rogue-server injection
nmcli -t -f NAME,DEVICE,STATE connection show --active 2>/dev/null
for iface in $(ls /sys/class/net | grep -v lo); do
  method=$(nmcli -t -g ipv4.method connection show "$iface" 2>/dev/null)
  echo "$iface: ipv4.method=$method"
done

echo "=== [3] DHCP client hook scripts inventory ==="
ls -la /etc/dhcp/dhclient-enter-hooks.d/ /etc/dhcp/dhclient-exit-hooks.d/ 2>/dev/null
ls -la /etc/NetworkManager/dispatcher.d/ 2>/dev/null
# Flag hooks that interpolate variables unsafely
grep -rnE '\$\{|\$[a-z_]+' /etc/dhcp/dhclient-*-hooks.d/ /etc/NetworkManager/dispatcher.d/ 2>/dev/null | grep -vE '(^\s*#)' | head -20

echo "=== [4] Indicators of compromise: shells/tooling spawned near DHCP events ==="
# Correlate dhclient activity with suspicious subsequent process execution
journalctl -u NetworkManager --since "7 days ago" 2>/dev/null | grep -iE "dhclient|dhcp" | tail -20
grep -iE "dhclient|dhcp" /var/log/syslog 2>/dev/null | tail -20
# Suspicious recent executions as root involving download tooling
journalctl _UID=0 --since "7 days ago" 2>/dev/null | grep -iE "wget|curl|base64|nc |ncat|socat|/tmp/|/dev/shm/" | head -30

echo "=== [5] Persistence check ==="
ls -lat /etc/cron.d/ /etc/cron.daily/ 2>/dev/null | head -20
systemctl list-unit-files --state=enabled 2>/dev/null | grep -vE "te-|thousandeyes|sshd|cron|systemd-|network|rsyslog|chrony|snap" | head -20
cat /root/.ssh/authorized_keys 2>/dev/null
find /home /root -name authorized_keys -mtime -14 2>/dev/null

echo "=== [6] Rogue DHCP detection on local segment (listen for multiple DHCP servers) ==="
# Requires dhcpdump or tcpdump; multiple distinct DHCPOFFER sources = rogue server present
timeout 20 tcpdump -i any -n port 67 or port 68 -c 50 2>/dev/null | grep -iE "BOOTP|DHCP" | head -20

echo "=== [7] INTERIM MITIGATION (if DHCP is required and patch is pending) ==="
echo "Preferred: reconfigure the appliance interface with a STATIC IP to remove the DHCP client from the equation:"
echo "  nmcli connection show   # identify connection name"
echo "  sudo nmcli connection modify <name> ipv4.method manual ipv4.addresses <IP>/<prefix> ipv4.gateway <GW> ipv4.dns '<DNS1> <DNS2>'"
echo "  sudo nmcli connection up <name>"
echo "Also enforce DHCP snooping + dynamic ARP inspection on the switch VLAN (see post)."

echo "=== Done. Preserve output for IR review if anomalies found. ==="

Remediation

1. Apply Cisco's fix immediately. ZDI-26-719 was published as a coordinated disclosure — consult the advisory at http://www.zerodayinitiative.com/advisories/ZDI-26-719/ and Cisco's corresponding security advisory (cisco.com/go/psirt) for the fixed ThousandEyes Virtual Appliance/Enterprise Agent version. ThousandEyes agents typically auto-update via the platform; verify in the ThousandEyes dashboard that every Enterprise Agent has reached the patched agent version, and force-update or redeploy appliances that have not. Do not assume auto-update succeeded — confirm version numbers per agent.

2. Eliminate DHCP where operationally possible. The cleanest mitigation for this entire vulnerability class is to assign ThousandEyes appliances static IP addresses. A monitoring appliance with a static configuration has no DHCP client attack surface. For most data center and VPC deployments this is trivially achievable; branch deployments should be the exception, not the rule.

3. Segment and constrain appliance interfaces. ThousandEyes agents do not need to live on user VLANs. Place them on dedicated management/monitoring segments with:

  • DHCP snooping enabled on access switches, with the legitimate DHCP server ports marked trusted — this directly kills the rogue-server delivery vector.
  • Dynamic ARP Inspection (DAI) and IP Source Guard on the same VLANs to block spoofed responses.
  • Egress filtering limiting the appliance to ThousandEyes cloud endpoints and explicitly required test targets.

4. Instrument the appliances for telemetry. Forward syslog/auth logs from virtual appliances to your SIEM (Sentinel, Splunk, etc.), and onboard them to your EDR where the vendor image permits. A monitoring appliance with no telemetry is a blind spot with credentials — exactly the kind of host attackers target after CVEs like this drop.

5. Hunt before and after patching. Patching closes the hole; it does not evict an attacker who got in during the exposure window. Run the process-lineage and persistence hunts above on all appliances, paying special attention to any appliance that rebooted or renewed leases on untrusted segments in the weeks prior to patching.

6. Reassess trust relationships. If any appliance shows compromise indicators, rotate credentials reachable from it, audit what internal targets it could reach, and treat it as a full IR engagement — root-level DHCP injection means total appliance compromise.

There is currently no CISA KEV deadline for CVE-2026-20350, but federal and compliance-driven organizations should apply their standard High-severity remediation SLAs (typically 7–15 days) — and faster for appliances on flat or untrusted segments.

Related Resources

Security Arsenal Penetration Testing Services AlertMonitor Platform Book a SOC Assessment vulnerability-management Intel Hub

Is your security operations ready?

Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.