VMware Tools service discovery LPE (CWE-426) via regex-based binary discovery (CVE-2025-41244)

Reading time: 7 minutes

tip

Ucz się i ćwicz Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Ucz się i ćwicz Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Wsparcie dla HackTricks

Ta technika wykorzystuje pipeline'y service discovery oparte na regex, które analizują linie poleceń uruchomionych procesów, aby wywnioskować wersje usług, a następnie uruchamiają wybrany binarny plik z flagą "version". Gdy permisywne wzorce akceptują nieufne, kontrolowane przez atakującego ścieżki (np. /tmp/httpd), uprzywilejowany collector uruchamia dowolny binarny z nieufnej lokalizacji, prowadząc do lokalnej eskalacji uprawnień. NVISO udokumentowało to w VMware Tools/Aria Operations Service Discovery jako CVE-2025-41244.

  • Impact: Lokalna eskalacja uprawnień do root (lub do uprzywilejowanego konta discovery)
  • Root cause: Untrusted Search Path (CWE-426) + zbyt permisywne dopasowywanie regex do linii poleceń procesów
  • 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 uruchamia discovery scripts wewnątrz gościa za pomocą VMware Tools używając skonfigurowanych uprzywilejowanych poświadczeń.
  • Credential-less (modern): Logika discovery działa wewnątrz VMware Tools, już uprzywilejowana w gościu.

Oba tryby ostatecznie uruchamiają shellową logikę, która skanuje procesy z nasłuchującymi socketami, wyciąga pasującą ścieżkę polecenia za pomocą regex i wykonuje pierwszy token argv z flagą wersji.

Root cause and vulnerable pattern (open-vm-tools)

W open-vm-tools, plugin serviceDiscovery skrypt get-versions.sh dopasowuje kandydackie binarki przy użyciu szerokich wyrażeń regularnych i wykonuje pierwszy token bez żadnej walidacji zaufanej ścieżki:

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

Jest wywoływany z luźnymi wzorcami zawierającymi \S (non-whitespace), które z łatwością dopasują ścieżki spoza systemu w lokalizacjach zapisywalnych przez użytkownika:

bash
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
  • Ekstrakcja używa grep -Eo i bierze pierwszy token: ${COMMAND%%[[:space:]]*}
  • Brak whitelist/allowlist zaufanych ścieżek systemowych; każdy wykryty listener z pasującą nazwą jest uruchamiany z -v/--version

To tworzy prymityw wykonania z nieufnej ścieżki wyszukiwania: dowolne binarki znajdujące się w katalogach zapisywalnych przez wszystkich (np. /tmp/httpd) są uruchamiane przez uprzywilejowany komponent.

Eksploatacja (zarówno bezpoświadczeniowy, jak i oparty na poświadczeniach)

Preconditions

  • Możesz uruchomić nieuprzywilejowany proces, który otwiera gniazdo nasłuchujące na gościu.
  • Zadanie discovery jest włączone i uruchamia się okresowo (historycznie ~5 minut).

Steps

  1. Umieść binarkę w ścieżce pasującej do jednego z permisywnych regexów, np. /tmp/httpd or ./nginx
  2. Uruchom ją jako użytkownik o niskich uprawnieniach i upewnij się, że otwiera dowolne gniazdo nasłuchujące
  3. Poczekaj na cykl discovery; uprzywilejowany collector automatycznie wykona: /tmp/httpd -v (lub podobne), uruchamiając Twój program jako root

Minimal demo (wykorzystując podejście NVISO)

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

Typowy ciąg procesów

  • Oparte na poświadczeniach: /usr/bin/vmtoolsd -> /bin/sh /tmp/VMware-SDMP-Scripts-.../script_...sh -> /tmp/httpd -v -> /bin/sh -i
  • Bez poświadczeń: /bin/sh .../get-versions.sh -> /tmp/httpd -v -> /bin/sh -i

Artefakty (oparte na poświadczeniach) Odzyskane skrypty wrapper SDMP w /tmp/VMware-SDMP-Scripts-{UUID}/ mogą wykazywać bezpośrednie uruchomienie nieautoryzowanej ścieżki:

bash
/tmp/httpd -v >"/tmp/VMware-SDMP-Scripts-{UUID}/script_-{ID}_0.stdout" 2>"/tmp/VMware-SDMP-Scripts-{UUID}/script_-{ID}_0.stderr"

Uogólnienie techniki: nadużycie odkrywania opartego na regexach (przenośny wzorzec)

Wiele agentów i pakietów monitorujących implementuje wykrywanie wersji/usług przez:

  • enumerację procesów z nasłuchującymi socketami
  • przeszukiwanie argv/linii poleceń przy użyciu permisywnych regexów (np. wzorców zawierających \S)
  • wykonanie dopasowanej ścieżki z nieszkodliwą flagą taką jak -v, --version, -V, -h

Jeśli regex akceptuje niezaufane ścieżki i ścieżka jest wykonywana z uprzywilejowanego kontekstu, otrzymujesz CWE-426 Untrusted Search Path execution.

Sposób nadużycia

  • Nazwij swój plik binarny tak jak powszechne demony, które regex prawdopodobnie dopasuje: httpd, nginx, mysqld, dataserver
  • Umieść go w zapisywalnym katalogu: /tmp/httpd, ./nginx
  • Upewnij się, że pasuje do regexu i otwiera dowolny port, aby został zenumerowany
  • Poczekaj na zaplanowany kolektor; otrzymasz automatyczne uprzywilejowane wywołanie -v

Uwaga dot. maskowania: To odpowiada MITRE ATT&CK T1036.005 (Match Legitimate Name or Location) w celu zwiększenia prawdopodobieństwa dopasowania i ukrycia.

Wielokrotnego użytku trik uprzywilejowanego przekaźnika I/O

  • Zbuduj swojego pomocnika tak, aby przy uprzywilejowanym wywołaniu (-v/--version) łączył się ze znanym punktem zbornym (np. abstrakcyjnym socketem UNIX na Linuksie jak @cve) i łączył stdio z /bin/sh -i. To unika artefaktów na dysku i działa w wielu środowiskach, gdzie ten sam plik binarny jest ponownie wywoływany z flagą.

Wykrywanie i wskazówki DFIR

Zapytania detekcyjne

  • Rzadkie (nieoczekiwane) potomki vmtoolsd lub get-versions.sh, takie jak /tmp/httpd, ./nginx, /tmp/mysqld
  • Wszelkie wykonywanie absolutnych ścieżek spoza systemowych przez skrypty odkrywające (szukaj spacji w ekspansjach ${COMMAND%%...})
  • ps -ef --forest do wizualizacji drzew przodków: vmtoolsd -> get-versions.sh ->

W Aria SDMP (oparte na poświadczeniach)

  • Sprawdź /tmp/VMware-SDMP-Scripts-{UUID}/ pod kątem przejściowych skryptów i artefaktów stdout/stderr pokazujących wykonanie ścieżek atakującego

Polityka/telemetria

  • Generuj alert, gdy uprzywilejowane kolektory wykonują się z prefiksów spoza systemowych: ^/(tmp|home|var/tmp|dev/shm)/
  • Monitorowanie integralności plików dla get-versions.sh i wtyczek VMware Tools

Środki zaradcze

  • Patch: Zastosuj aktualizacje Broadcom/VMware dla CVE-2025-41244 (Tools and Aria Operations SDMP)
  • Wyłącz lub ogranicz wykrywanie bez poświadczeń tam, gdzie jest to możliwe
  • Waliduj zaufane ścieżki: ogranicz wykonywanie do dozwolonych katalogów (/usr/sbin, /usr/bin, /sbin, /bin) i tylko do dokładnie znanych binariów
  • Unikaj permisywnych regexów z \S; preferuj zakotwiczone, wyraźne ścieżki absolutne i dokładne nazwy poleceń
  • Zrzuć przywileje dla pomocników odkrywających tam, gdzie to możliwe; użyj sandboxingu (seccomp/AppArmor) aby zmniejszyć skutki
  • Monitoruj i generuj alerty na vmtoolsd/get-versions.sh wykonujące ścieżki spoza systemowych

Uwagi dla obrońców i implementatorów

Bezpieczniejszy wzorzec dopasowania i wykonywania

bash
# 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ódła

tip

Ucz się i ćwicz Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Ucz się i ćwicz Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Wsparcie dla HackTricks