VMware Tools service discovery LPE (CWE-426) via regex-based binary discovery (CVE-2025-41244)
Reading time: 8 minutes
tip
Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Lernen & üben Sie Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Unterstützen Sie HackTricks
- Überprüfen Sie die Abonnementpläne!
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.
Diese Technik missbraucht regex-gesteuerte Service-Discovery-Pipelines, die laufende Prozess-Kommandozeilen parsen, um Service-Versionen zu ermitteln und dann ein Kandidaten-Binary mit einem "version"-Flag auszuführen. Wenn permissive Patterns untrusted, vom Angreifer kontrollierte Pfade akzeptieren (z. B. /tmp/httpd), führt der privilegierte Collector ein beliebiges Binary aus einem untrusted Speicherort aus, was zu einer lokalen Privilegienerhöhung führt. NVISO dokumentierte dies in VMware Tools/Aria Operations Service Discovery als CVE-2025-41244.
- Impact: Local privilege escalation to root (or to the privileged discovery account)
- Root cause: Untrusted Search Path (CWE-426) + permissive regex matching of process command lines
- Affected: open-vm-tools/VMware Tools on Linux (credential-less discovery), VMware Aria Operations SDMP (credential-based discovery via Tools/proxy)
How VMware service discovery works (high level)
- Credential-based (legacy): Aria führt Discovery-Skripte innerhalb des Guests über VMware Tools aus und verwendet konfigurierte privilegierte Anmeldeinformationen.
- Credential-less (modern): Die Discovery-Logik läuft innerhalb von VMware Tools, bereits mit erhöhten Rechten im Guest.
Beide Modi führen letztlich Shell-Logik aus, die Prozesse mit listening sockets scannt, einen passenden Kommando-Pfad via regex extrahiert und das erste argv-Token mit einem version-Flag ausführt.
Root cause and vulnerable pattern (open-vm-tools)
In open-vm-tools vergleicht das serviceDiscovery-Plugin-Skript get-versions.sh Kandidaten-Binaries mithilfe weit gefasster regulärer Ausdrücke und führt das erste Token ohne jegliche Prüfung des trusted-path aus:
get_version() {
PATTERN=$1
VERSION_OPTION=$2
for p in $space_separated_pids
do
COMMAND=$(get_command_line $p | grep -Eo "$PATTERN")
[ ! -z "$COMMAND" ] && echo VERSIONSTART "$p" "$("${COMMAND%%[[:space:]]*}" $VERSION_OPTION 2>&1)" VERSIONEND
done
}
Es wird mit permissiven Mustern aufgerufen, die \S (kein Leerzeichen) enthalten und problemlos mit Nicht-Systempfaden in von Benutzern beschreibbaren Orten übereinstimmen:
get_version "/\S+/(httpd-prefork|httpd|httpd2-prefork)($|\s)" -v
get_version "/usr/(bin|sbin)/apache\S*" -v
get_version "/\S+/mysqld($|\s)" -V
get_version "\.?/\S*nginx($|\s)" -v
get_version "/\S+/srm/bin/vmware-dr($|\s)" --version
get_version "/\S+/dataserver($|\s)" -v
- Extraktion verwendet grep -Eo und nimmt das erste Token: ${COMMAND%%[[:space:]]*}
- Keine Whitelist/Allowlist vertrauenswürdiger Systempfade; jeder gefundene Listener mit passendem Namen wird mit -v/--version ausgeführt
Dies erzeugt ein untrusted search path execution primitive: beliebige Binärdateien, die sich in weltweit beschreibbaren Verzeichnissen befinden (z. B. /tmp/httpd), werden von einer privilegierten Komponente ausgeführt.
Ausnutzung (sowohl ohne Credentials als auch mit Credentials)
Voraussetzungen
- Du kannst einen unprivilegierten Prozess ausführen, der auf dem Gast einen Listening-Socket öffnet.
- Der discovery-Job ist aktiviert und läuft periodisch (historisch ~5 Minuten).
Schritte
- Platziere eine Binärdatei in einem Pfad, der einem der permissiven regexes entspricht, z. B. /tmp/httpd oder ./nginx
- Starte sie als niedrig privilegierter Benutzer und stelle sicher, dass sie einen Listening-Socket öffnet
- Warte auf den Discovery-Zyklus; der privilegierte Collector führt automatisch /tmp/httpd -v (oder Ähnliches) aus, wodurch dein Programm als root läuft
Minimale Demo (unter Verwendung von NVISO’s Ansatz)
# Build any small helper that:
# - default mode: opens a dummy TCP listener
# - when called with -v/--version: performs the privileged action (e.g., connect to an abstract UNIX socket and spawn /bin/sh -i)
# Example staging and trigger
cp your_helper /tmp/httpd
chmod +x /tmp/httpd
/tmp/httpd # run as low-priv user and wait for the cycle
# After the next cycle, expect a root shell or your privileged action
Typische Prozessabfolge
- Credential-based: /usr/bin/vmtoolsd -> /bin/sh /tmp/VMware-SDMP-Scripts-.../script_...sh -> /tmp/httpd -v -> /bin/sh -i
- Credential-less: /bin/sh .../get-versions.sh -> /tmp/httpd -v -> /bin/sh -i
Artefakte (credential-based) Wiederhergestellte SDMP-Wrapper-Skripte unter /tmp/VMware-SDMP-Scripts-{UUID}/ können die direkte Ausführung des bösartigen Pfads zeigen:
/tmp/httpd -v >"/tmp/VMware-SDMP-Scripts-{UUID}/script_-{ID}_0.stdout" 2>"/tmp/VMware-SDMP-Scripts-{UUID}/script_-{ID}_0.stderr"
Verallgemeinerung der Technik: regex-driven discovery abuse (portable pattern)
Viele Agents und Monitoring-Suites implementieren Version-/Service-Discovery durch:
- Auflisten von Prozessen mit listening sockets
- Greppen von argv/command lines mit permissiven regexes (z. B. Muster, die \S enthalten)
- Ausführen des gefundenen Pfads mit einem harmlosen Flag wie -v, --version, -V, -h
Wenn das Regex untrusted Pfade akzeptiert und der Pfad aus einem privilegierten Kontext ausgeführt wird, erhält man CWE-426 Untrusted Search Path execution.
Missbrauchsrezept
- Benenne deine Binary wie gängige Daemons, die das Regex wahrscheinlich matched: httpd, nginx, mysqld, dataserver
- Platziere sie in einem beschreibbaren Verzeichnis: /tmp/httpd, ./nginx
- Stelle sicher, dass sie dem Regex entspricht und irgendeinen Port öffnet, um enumeriert zu werden
- Warte auf den geplanten Collector; du erhältst eine automatische privilegierte Invocation von
-v
Anmerkung zur Verschleierung: Dies stimmt mit MITRE ATT&CK T1036.005 (Match Legitimate Name or Location) überein, um die Trefferwahrscheinlichkeit und Tarnung zu erhöhen.
Wiederverwendbarer privilegierter I/O-Relay-Trick
- Baue deinen Helper so, dass er bei privilegiertem Aufruf (-v/--version) eine Verbindung zu einem bekannten Rendezvous (z. B. einem Linux abstract UNIX socket wie @cve) herstellt und stdio zu /bin/sh -i bridged. Das vermeidet Artefakte auf der Festplatte und funktioniert in vielen Umgebungen, in denen dieselbe Binary mit einem Flag erneut aufgerufen wird.
Erkennung und DFIR-Anleitung
Hunting-Abfragen
- Ungewöhnliche Children von vmtoolsd oder get-versions.sh wie /tmp/httpd, ./nginx, /tmp/mysqld
- Jede Ausführung von non-system absolute paths durch Discovery-Skripte (achte auf spaces in ${COMMAND%%...} expansions)
- ps -ef --forest zur Visualisierung von Ahnenbäumen: vmtoolsd -> get-versions.sh ->
Bei Aria SDMP (credential-based)
- Untersuche /tmp/VMware-SDMP-Scripts-{UUID}/ nach transienten Skripten und stdout/stderr-Artefakten, die die Ausführung von Angreiferpfaden zeigen
Policy/Telemetrie
- Alert, wenn privilegierte Collector aus non-system Präfixen ausgeführt werden: ^/(tmp|home|var/tmp|dev/shm)/
- File integrity monitoring für get-versions.sh und VMware Tools plugins
Abhilfemaßnahmen
- Patch: Apply Broadcom/VMware updates for CVE-2025-41244 (Tools and Aria Operations SDMP)
- Disable or restrict credential-less discovery where feasible
- Validate trusted paths: restrict execution to allowlisted directories (/usr/sbin, /usr/bin, /sbin, /bin) and only exact known binaries
- Avoid permissive regexes with \S; prefer anchored, explicit absolute paths and exact command names
- Drop privileges for discovery helpers where possible; sandbox (seccomp/AppArmor) to reduce impact
- Monitor for and alert on vmtoolsd/get-versions.sh executing non-system paths
Hinweise für Verteidiger und Implementierer
Sichereres Matching- und Ausführungsmuster
# Bad: permissive regex and blind exec
COMMAND=$(get_command_line "$pid" | grep -Eo "/\\S+/nginx(\$|\\s)")
[ -n "$COMMAND" ] && "${COMMAND%%[[:space:]]*}" -v
# Good: strict allowlist + path checks
candidate=$(get_command_line "$pid" | awk '{print $1}')
case "$candidate" in
/usr/sbin/nginx|/usr/sbin/httpd|/usr/sbin/apache2)
"$candidate" -v 2>&1 ;;
*)
: # ignore non-allowlisted paths
;;
esac
Referenzen
- NVISO – You name it, VMware elevates it (CVE-2025-41244)
- Broadcom advisory for CVE-2025-41244
- open-vm-tools – serviceDiscovery/get-versions.sh (stable-13.0.0)
- MITRE ATT&CK T1036.005 – Match Legitimate Name or Location
- CWE-426: Untrusted Search Path
tip
Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Lernen & üben Sie Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Unterstützen Sie HackTricks
- Überprüfen Sie die Abonnementpläne!
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.