Talos Vulnerability Report


Shimo VPN Helper Tool disconnectService denial-of-service vulnerability

April 15, 2019
CVE Number



An exploitable privilege escalation vulnerability exists in the Shimo VPN helper service in the disconnectService functionality. A non-root user is able to kill any privileged process on the system. An attacker would need local access to the machine for a successful exploit.

Tested Versions

Shimo VPN

Product URLs


CVSSv3 Score

7.1 - CVSS:3.0/AV:L/AC:L/PR:N/UI:N/S:C/C:N/I:N/A:H


CWE-19: Improper Input Validation


Shimo VPN is a VPN client for Mac OSX used connect to and to manage multiple VPN accounts in one place. The application uses what is defined as a "Helper Tool" to perform some of the privileged work on its behalf. The helper tool is installed as root when the application is first installed and is a LaunchD daemon, meaning it will be restarted if it is killed. The service listens using:

v3 = objc_msgSend(&OBJC_CLASS___NSXPCListener, "alloc");
v4 = objc_msgSend(v3, "initWithMachServiceName:", CFSTR("com.feingeist.shimo.helper"));

The second argument registers the string passed in as a service and tells it to begin listening. This opens the service up to be connected to using Objective-C XPC calls. A similar section of code needs to be executed to connect a client to this service a.

 v8 = objc_msgSend(v7, "initWithMachServiceName:options:", CFSTR("com.feingeist.shimo.helper"), 4096LL); [1]
  v11 = objc_msgSend(
          &OBJC_PROTOCOL___ShimoHelperToolProtocol);                                                      [2]

At [1], the same call as the one above is used, except this time, the options variable is used to signify that the client is connecting rather than listening. At [2], a special protocol is passed in that defines all the functions available to the client. The server must have the same protocol defined in order for these calls to work. We can begin to see the vulnerabilities arise when we look at the protocol.

This vulnerability is present inside of the disconnectService:fromRemoteHost:withComPort:withPID:withReply: function, with the relevant code shown below.

  pid = arg_6;                                                        [3]
  syslog(5, "Running disconnectService in helper.");
  if ( pid <= 0 )                                                     
    v17 = CFSTR("Invalid process identifier");
    goto LABEL_14;
  if ( v8 > 6 )
    goto LABEL_17;
  v10 = 90LL;
  if ( !_bittest64(&v10, v8) )
    if ( v8 )
      if ( v8 == 2 )
        if ( CSProcessRunning(pid) )                                   [4]
          if ( !-[ShimoHelperTool killProcessWithID:withSignal:](self, "killProcessWithID:withSignal:", pid,    15LL) )                                                       [5]

At location [3], a passed in argument is assigned to a variable responsible for holding a process id. Location [4], shows a check to verify the application is running and then the process is passed into a kill function, [5]. This allows a non-root user to pass in any desired PID and have that process killed. This passes a privilege boundary creating a privilege escalation vulnerability.

Exploit Proof of Concept

The provided executable will kill the application with PID 101, which on a normal boot will be a root process that should not be able to be killed by a normal user, showing the effects of the vulnerability.


2018-09-21 - Vendor Disclosure
2018-09-22 - Vendor acknowledged and gave main developer contact
2018-09-26 - Reports sent to main developer
2018-10-08 - First follow up
2018-11-09 - 2nd follow up
2018-12-04 - 3rd follow up
2019-03-14 - Final follow up for public disclosure
2019-04-15 - Zero day/Public Release


Discovered by Tyler Bohan of Cisco Talos.