VMware Tools service discovery LPE (CWE-426) via regex-based binary discovery (CVE-2025-41244)
Reading time: 8 minutes
tip
Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez le hacking Azure :
HackTricks Training Azure Red Team Expert (AzRTE)
Soutenir HackTricks
- Vérifiez les plans d'abonnement !
- Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez-nous sur Twitter 🐦 @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PR au HackTricks et HackTricks Cloud dépôts github.
Cette technique abuse des pipelines de découverte de services pilotés par des regex qui analysent les lignes de commande des processus en cours d'exécution pour déduire les versions des services, puis exécutent un binaire candidat avec un flag "version". Quand des patterns permissifs acceptent des chemins non fiables contrôlés par l'attaquant (p. ex. /tmp/httpd), le collecteur privilégié exécute un binaire arbitraire depuis un emplacement non fiable, entraînant une escalade de privilèges locale. NVISO a documenté ceci dans VMware Tools/Aria Operations Service Discovery comme CVE-2025-41244.
- Impact : Escalade de privilèges locale vers root (ou vers le compte de découverte privilégié)
- Root cause : Untrusted Search Path (CWE-426) + permissive regex matching of process command lines
- Affected : open-vm-tools/VMware Tools sur 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 exécute des scripts de découverte à l'intérieur du guest via VMware Tools en utilisant des identifiants privilégiés configurés.
- Credential-less (modern) : La logique de découverte s'exécute dans VMware Tools, déjà privilégié dans le guest.
Les deux modes exécutent finalement une logique shell qui scanne les processus avec des sockets en écoute, extrait un chemin de commande correspondant via une regex, et exécute le premier token argv avec un flag version.
Root cause and vulnerable pattern (open-vm-tools)
Dans open-vm-tools, le script plugin serviceDiscovery get-versions.sh matche les binaires candidats en utilisant des expressions régulières larges et exécute le premier token sans aucune validation du 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
}
Il est invoqué avec des motifs permissifs contenant \S (caractère non blanc) qui correspondent facilement à des chemins non système dans des emplacements accessibles en écriture par l'utilisateur :
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'extraction utilise grep -Eo et prend le premier token : ${COMMAND%%[[:space:]]*}
- Pas de whitelist/allowlist des chemins système de confiance ; tout listener découvert avec un nom correspondant est exécuté avec -v/--version
This creates an untrusted search path execution primitive: arbitrary binaries located in world-writable directories (e.g., /tmp/httpd) get executed by a privileged component.
Exploitation (modes sans identifiants et avec identifiants)
Préconditions
- Vous pouvez exécuter un processus non privilégié qui ouvre une socket d'écoute sur la machine guest.
- Le discovery job est activé et s'exécute périodiquement (historiquement ~5 minutes).
Étapes
- Placez un binaire dans un chemin correspondant à l'un des regex permissifs, par ex. /tmp/httpd ou ./nginx
- Lancez-le en tant qu'utilisateur peu privilégié et assurez-vous qu'il ouvre une socket d'écoute
- Attendez le cycle de discovery ; le collector privilégié exécutera automatiquement : /tmp/httpd -v (ou similaire), lançant votre programme en tant que root
Minimal demo (using NVISO’s approach)
# 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
Lignée de processus typique
- Basé sur des identifiants: /usr/bin/vmtoolsd -> /bin/sh /tmp/VMware-SDMP-Scripts-.../script_...sh -> /tmp/httpd -v -> /bin/sh -i
- Sans identifiants: /bin/sh .../get-versions.sh -> /tmp/httpd -v -> /bin/sh -i
Artefacts (basés sur des identifiants) Les scripts wrapper SDMP récupérés sous /tmp/VMware-SDMP-Scripts-{UUID}/ peuvent montrer l'exécution directe du chemin malveillant:
/tmp/httpd -v >"/tmp/VMware-SDMP-Scripts-{UUID}/script_-{ID}_0.stdout" 2>"/tmp/VMware-SDMP-Scripts-{UUID}/script_-{ID}_0.stderr"
Généralisation de la technique: regex-driven discovery abuse (portable pattern)
Beaucoup d'agents et de suites de monitoring implémentent la découverte de version/service en :
- Énumérant les processus avec des sockets d'écoute
- Grepping argv/command lines avec des regexes permissives (p. ex., patterns contenant \S)
- Exécutant le chemin correspondant avec un flag bénin comme -v, --version, -V, -h
Si la regex accepte des chemins non fiables et que le chemin est exécuté depuis un contexte privilégié, on obtient CWE-426 Untrusted Search Path execution.
Abuse recipe
- Nommez votre binaire comme des daemons courants que la regex est susceptible de matcher : httpd, nginx, mysqld, dataserver
- Placez-le dans un répertoire inscriptible : /tmp/httpd, ./nginx
- Assurez-vous qu'il match la regex et ouvre un port quelconque pour être énuméré
- Attendez le collecteur planifié ; vous obtenez une invocation privilégiée automatique de
-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
- Concevez votre helper de sorte que lors d'une invocation privilégiée (-v/--version) il se connecte à un rendezvous connu (p. ex., un socket UNIX abstrait Linux comme @cve) et relie stdio à /bin/sh -i. Cela évite les artefacts sur disque et fonctionne dans de nombreux environnements où le même binaire est ré-invoqué avec un flag.
Détection et conseils DFIR
Hunting queries
- Enfants inhabituels de vmtoolsd ou get-versions.sh tels que /tmp/httpd, ./nginx, /tmp/mysqld
- Toute exécution de chemins absolus non-système par des scripts de découverte (recherchez des espaces dans les expansions ${COMMAND%%...})
- ps -ef --forest pour visualiser les arbres d'ascendance : vmtoolsd -> get-versions.sh ->
On Aria SDMP (credential-based)
- Inspectez /tmp/VMware-SDMP-Scripts-{UUID}/ pour des scripts transitoires et des artefacts stdout/stderr montrant l'exécution de chemins d'attaquants
Policy/telemetry
- Alerter quand des collectors privilégiés exécutent depuis des préfixes non-système : ^/(tmp|home|var/tmp|dev/shm)/
- File integrity monitoring sur get-versions.sh et les plugins VMware Tools
Mitigations
- Patch : Appliquez les mises à jour Broadcom/VMware pour CVE-2025-41244 (Tools and Aria Operations SDMP)
- Désactivez ou restreignez la découverte sans credentials lorsque c'est possible
- Validez les chemins de confiance : restreignez l'exécution aux répertoires allowlistés (/usr/sbin, /usr/bin, /sbin, /bin) et uniquement aux binaires connus exacts
- Évitez les regexes permissives avec \S ; préférez des chemins absolus ancrés explicites et des noms de commande exacts
- Baissez les privilèges des helpers de découverte quand c'est possible ; sandboxez (seccomp/AppArmor) pour réduire l'impact
- Surveillez et alertez sur vmtoolsd/get-versions.sh exécutant des chemins non-système
Notes pour les défenseurs et les implémenteurs
Pattern de matching et d'exécution plus sûr
# 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
Références
- NVISO – Vous le nommez, VMware l'élève (CVE-2025-41244)
- Avis de Broadcom pour 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
Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez le hacking Azure :
HackTricks Training Azure Red Team Expert (AzRTE)
Soutenir HackTricks
- Vérifiez les plans d'abonnement !
- Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez-nous sur Twitter 🐦 @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PR au HackTricks et HackTricks Cloud dépôts github.