VMware Tools service discovery LPE (CWE-426) via regex-based binary discovery (CVE-2025-41244)
Reading time: 8 minutes
tip
Impara e pratica il hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)
Impara e pratica il hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporta HackTricks
- Controlla i piani di abbonamento!
- Unisciti al 💬 gruppo Discord o al gruppo telegram o seguici su Twitter 🐦 @hacktricks_live.
- Condividi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos github.
Questa tecnica sfrutta pipeline di service discovery basate su regex che analizzano le command line dei processi in esecuzione per ricavare le versioni dei servizi e poi eseguono un binario candidato con il flag "version". Quando pattern permissivi accettano percorsi non attendibili controllati dall'attaccante (es. /tmp/httpd), il collector privilegiato esegue un binario arbitrario da una posizione non attendibile, ottenendo una escalation locale di privilegi. NVISO ha documentato questo in VMware Tools/Aria Operations Service Discovery come CVE-2025-41244.
- Impact: escalation locale dei privilegi a root (o all'account privilegiato di discovery)
- Root cause: Untrusted Search Path (CWE-426) + permissive regex matching of process command lines
- Affected: open-vm-tools/VMware Tools su 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 esegue gli script di discovery all'interno del guest tramite VMware Tools usando credenziali privilegiate configurate.
- Credential-less (modern): La logica di discovery gira all'interno di VMware Tools, già privilegiato nel guest.
Entrambi i metodi eseguono, in ultima analisi, script shell che scansionano i processi che hanno socket in ascolto, estraggono un percorso di comando corrispondente tramite una regex e eseguono il primo token argv con il flag version.
Root cause and vulnerable pattern (open-vm-tools)
In open-vm-tools, lo script del plugin serviceDiscovery get-versions.sh confronta i binari candidati usando espressioni regolari ampie e esegue il primo token senza alcuna validazione del trusted-path:
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
}
Viene invocato con pattern permissivi che contengono \S (non-whitespace) che corrisponderanno volentieri a percorsi non di sistema in posizioni scrivibili dall'utente:
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
- L'estrazione usa grep -Eo e prende il primo token: ${COMMAND%%[[:space:]]*}
- Non esiste una whitelist/allowlist di percorsi di sistema attendibili; qualsiasi listener scoperto con un nome corrispondente viene eseguito con -v/--version
Questo crea una primitiva di esecuzione untrusted search path: binari arbitrari situati in world-writable directories (es., /tmp/httpd) vengono eseguiti da un componente privilegiato.
Sfruttamento (modalità sia senza credenziali che basata su credenziali)
Precondizioni
- Puoi eseguire un processo non privilegiato che apre una socket in ascolto sulla guest.
- Il job di discovery è abilitato e viene eseguito periodicamente (storicamente ~5 minuti).
Passaggi
- Posiziona un binario in un percorso che corrisponde a una delle permissive regex, p.es. /tmp/httpd o ./nginx
- Eseguilo come utente a basso privilegio e assicurati che apra una socket in ascolto
- Attendi il ciclo di discovery; il collector privilegiato eseguirà automaticamente: /tmp/httpd -v (o simile), eseguendo il tuo programma come root
Demo minima (usando l'approccio di NVISO)
# 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
Tipica catena dei processi
- Basato su credenziali: /usr/bin/vmtoolsd -> /bin/sh /tmp/VMware-SDMP-Scripts-.../script_...sh -> /tmp/httpd -v -> /bin/sh -i
- Senza credenziali: /bin/sh .../get-versions.sh -> /tmp/httpd -v -> /bin/sh -i
Artefatti (basati su credenziali) Gli script wrapper SDMP recuperati sotto /tmp/VMware-SDMP-Scripts-{UUID}/ possono mostrare l'esecuzione diretta del rogue path:
/tmp/httpd -v >"/tmp/VMware-SDMP-Scripts-{UUID}/script_-{ID}_0.stdout" 2>"/tmp/VMware-SDMP-Scripts-{UUID}/script_-{ID}_0.stderr"
Generalizzare la tecnica: abuso della discovery guidata da regex (pattern portatile)
Molti agenti e suite di monitoraggio implementano la discovery di versioni/servizi tramite:
- Enumerare i processi con socket in ascolto
- Scansionare argv/linee di comando con regex permissive (es., pattern contenenti \S)
- Eseguire il percorso corrispondente con un flag benigno come -v, --version, -V, -h
Se la regex accetta percorsi non attendibili e il percorso viene eseguito da un contesto privilegiato, si ottiene CWE-426 Untrusted Search Path execution.
Abuse recipe
- Nomina il tuo binario come daemon comuni che la regex è probabile che corrisponda: httpd, nginx, mysqld, dataserver
- Posizionalo in una directory scrivibile: /tmp/httpd, ./nginx
- Assicurati che corrisponda alla regex e apra una porta qualunque per essere enumerata
- Attendi il collector programmato; otterrai un'invocazione privilegiata automatica di
-v
Masquerading note: This aligns with MITRE ATT&CK T1036.005 (Match Legitimate Name or Location) to increase match probability and stealth.
Reusable privileged I/O relay trick
- Build your helper so that on privileged invocation (-v/--version) it connects to a known rendezvous (e.g., a Linux abstract UNIX socket like @cve) and bridges stdio to /bin/sh -i. This avoids on-disk artifacts and works across many environments where the same binary is re-invoked with a flag.
Rilevamento e indicazioni DFIR
Hunting queries
- Figli non comuni di vmtoolsd o get-versions.sh come /tmp/httpd, ./nginx, /tmp/mysqld
- Qualsiasi esecuzione di percorsi assoluti non di sistema da parte di script di discovery (cerca spazi nelle espansioni ${COMMAND%%...})
- ps -ef --forest per visualizzare gli alberi di parentela: vmtoolsd -> get-versions.sh ->
Su Aria SDMP (credential-based)
- Ispeziona /tmp/VMware-SDMP-Scripts-{UUID}/ per script transitori e artefatti stdout/stderr che mostrano l'esecuzione di percorsi dell'attaccante
Policy/telemetria
- Allerta quando i collector privilegiati eseguono da prefissi non di sistema: ^/(tmp|home|var/tmp|dev/shm)/
- Monitoraggio dell'integrità dei file su get-versions.sh e VMware Tools plugins
Mitigazioni
- Patch: Applicare gli aggiornamenti Broadcom/VMware per CVE-2025-41244 (Tools and Aria Operations SDMP)
- Disabilitare o limitare la discovery senza credenziali quando possibile
- Validare i percorsi trusted: restringere l'esecuzione alle directory consentite (/usr/sbin, /usr/bin, /sbin, /bin) e solo ai binari esatti noti
- Evitare regex permissive con \S; preferire percorsi assoluti espliciti ancorati e nomi di comando esatti
- Ridurre i privilegi per gli helper di discovery quando possibile; sandboxare (seccomp/AppArmor) per ridurre l'impatto
- Monitorare e allertare su vmtoolsd/get-versions.sh che eseguono percorsi non di sistema
Note per i difensori e gli implementatori
Pattern di matching ed esecuzione più sicuro
# 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
Riferimenti
- NVISO – You name it, VMware elevates it (CVE-2025-41244)
- Avviso Broadcom per 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
Impara e pratica il hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)
Impara e pratica il hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporta HackTricks
- Controlla i piani di abbonamento!
- Unisciti al 💬 gruppo Discord o al gruppo telegram o seguici su Twitter 🐦 @hacktricks_live.
- Condividi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos github.