0 day:详细分析macOS平台Shimo VPN多个权限提升漏洞
一、概述
Cisco Talos团队近日披露了Shimo VPN帮助工具(Helper Tool)的一系列漏洞。Shimo VPN是macOS平台上一个非常流行的VPN客户端,可以在一个应用程序中连接多个VPN帐户。这些特定的漏洞都存在于帮助工具之中,这是Shimo VPN中用来完成某些特权工作的一个功能。
根据我们的披露政策,在反复尝试与厂商进行沟通未果后,最终决定在官方未发布补丁的情况下披露漏洞详情。
二、Shimo VPN帮助程序服务特权提升漏洞(CVE-2018-4004)
CVE-2018-4004(TALOS-2018-0673)是一个特权提升漏洞,该漏洞位于Shimo VPN帮助程序服务中,具体而言是在其中的disconnectService函数。要成功利用该漏洞,需要对计算机进行本地访问,可能允许非root用户终止系统上的特权进程。
2.1 CVSSv3评分
7.1 – CVSS:3.0/AV:L/AC:L/PR:N/UI:N/S:C/C:N/I:N/A:H
2.2 CWE
CWE-19:输入验证不正确
2.3 漏洞详情
首次安装该应用程序时,帮助工具将以root身份安装,并且作为LaunchD守护程序。这就意味着,如果该程序被终止,将会立即重新启动。该服务的监听使用:
v3 = objc_msgSend(&OBJC_CLASS___NSXPCListener, "alloc");
v4 = objc_msgSend(v3, "initWithMachServiceName:", CFSTR("com.feingeist.shimo.helper"));
第二个参数注册作为服务传入的字符串,并提示它开始监听。这一过程,将会打开服务,以连接到使用Objective-C的XPC调用。该过程会执行类似于下列的代码段,从而将客户端连接到该服务a。
v8 = objc_msgSend(v7, "initWithMachServiceName:options:", CFSTR("com.feingeist.shimo.helper"), 4096LL); [1]
v11 = objc_msgSend(
&OBJC_CLASS___NSXPCInterface,
"interfaceWithProtocol:",
&OBJC_PROTOCOL___ShimoHelperToolProtocol); [2]
在[1]的位置,使用与上面相同的调用,options变量用于表示客户端正在连接,而不是正在监听中。在[2]中,传递了一个特殊的协议,它定义了客户端可用的所有功能。服务器必须定义相同的协议,才能使这些调用正常工作。我们查看协议时,发现了漏洞的存在。
该漏洞位于disconnectService:fromRemoteHost:withComPort:withPID:withReply:函数中,相关代码如下:
pid = arg_6; [3]
syslog(5, "Running disconnectService in helper.");
if ( pid 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]
在[3]的位置,传入的参数被分配给负责保存进程ID的变量。在[4]的位置,该检查用于验证应用程序是否正在运行,然后将该进程传递给kill函数,也就是[5]。这样一来,就允许非root用户传入任何所需的PID,并使得该进程终止。这样的操作会传递权限边界,从而产生权限提升漏洞。
2.4 漏洞利用概念证明
我们提供的可执行文件,将终止PID为101的应用程序,PID 101在正常启动时是一个root进程,理论上不应该被普通用户终止,由此说明该漏洞产生的影响。
2.5 时间线
2018年9月21日 向厂商披露
2018年9月22日 厂商确认漏洞,并给出主要开发人员的联系方式
2018年9月26日 将漏洞详情发送给主要开发人员
2018年10月8日 第一次跟进进展情况
2018年11月9日 第二次跟进进展情况
2018年12月4日 第三次跟进进展情况
2019年3月14日 公开披露前跟进进展情况
2019年3月15日 公开披露0day漏洞
三、Shimo VPN帮助程序服务特权提升漏洞(CVE-2018-4005)
CVE-2018-4005(TALOS-2018-0674)是一个可利用的权限提升漏洞,该漏洞位于Shimo VPN帮助程序服务中,具体而言是在其中的configureRoutingWithCommand函数。要成功利用该漏洞,需要对计算机进行本地访问,但可能允许攻击者将其权限升级为root。
9.3 – CVSS:3.0/AV:L/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
3.2 CWE
CWE-19:输入验证不正确
3.3 漏洞详情
首次安装该应用程序时,帮助工具将以root身份安装,并且作为LaunchD守护程序。这就意味着,如果该程序被终止,将会立即重新启动。该服务的监听使用:
v3 = objc_msgSend(&OBJC_CLASS___NSXPCListener, "alloc");
v4 = objc_msgSend(v3, "initWithMachServiceName:", CFSTR("com.feingeist.shimo.helper"));
第二个参数注册作为服务传入的字符串,并提示它开始监听。这一过程,将会打开服务,以连接到使用Objective-C的XPC调用。该过程会执行类似于下列的代码段,从而将客户端连接到该服务a。
v8 = objc_msgSend(v7, "initWithMachServiceName:options:", CFSTR("com.feingeist.shimo.helper"), 4096LL); [1]
v11 = objc_msgSend(
&OBJC_CLASS___NSXPCInterface,
"interfaceWithProtocol:",
&OBJC_PROTOCOL___ShimoHelperToolProtocol); [2]
在[1]的位置,使用与上面相同的调用,options变量用于表示客户端正在连接,而不是正在监听中。在[2]中,传递了一个特殊的协议,它定义了客户端可用的所有功能。服务器必须定义相同的协议,才能使这些调用正常工作。我们查看协议时,发现了漏洞的存在。
函数configureRoutingWithCommand:withReply:在所描述的协议中可用,并且容易受到特权提升的攻击。该函数将字符串作为参数,并在root环境中作为bash脚本执行。相关代码如下所示。
user_supplied_arg = objc_retain(arg_3, a2); [1]
v6 = objc_retain(v4, a2);
syslog(5, "Running configureRoutingWithCommand in helper.");
if ( user_supplied_arg )
{
user_data_to_write = user_supplied_arg;
v7 = objc_msgSend(self->tmpDirPath, "stringByAppendingPathComponent:", CFSTR("shimo_routing.sh")); [2]
path = objc_retainAutoreleasedReturnValue(v7);
v11 = objc_msgSend(v10, "fileExistsAtPath:", path_);
...
objc_msgSend(user_data_to_write, "writeToFile:atomically:encoding:error:", path, 1LL, 4LL, &error); [3]
v18 = objc_retain(error, "writeToFile:atomically:encoding:error:");
objc_release(error_);
...
v26 = objc_msgSend(&OBJC_CLASS___NSTask, "alloc");
v27 = objc_msgSend(v26, "init");
objc_msgSend(v27, "setLaunchPath:", path, v27);
(objc_msgSend)(v27, "setCurrentDirectoryPath:", self->tmpDirPath);
v28 = (objc_msgSend)(&OBJC_CLASS___NSPipe, "pipe");
v43 = objc_retainAutoreleasedReturnValue(v28);
objc_msgSend(v27, "setStandardOutput:", v43);
objc_msgSend(v27, "launch"); [4]
在[1]的位置,数据被传递到函数调用中,并存储以供以后使用。然后,在[2]的位置构造路径,指向名为shimo_routing.sh的文件。在[3]的位置,数据传递给函数,并用于写入前面所提到的文件。最后,在[4]的位置,这个新创建的脚本在root环境中启动,允许非特权用户具有root访问权限,并创建了一个权限提升的场景。
3.4 漏洞利用概念证明
提供的configureRouting可执行文件,可以执行位于/tmp/root.py的脚本。从该位置启动的附加示例脚本可以表明该问题的严重性。要正确进行漏洞利用验证,非特权用户需要将使用的root.py脚本移动到/tmp目录,并执行命令chmod +x /tmp/root.py,以确保该脚本是可以执行的。该脚本将尝试连接目标IP的root Shell,并将文件放置在根目录中,以展示该攻击可以成功执行。
3.5 时间线
2018年9月21日 向厂商披露
2018年9月22日 厂商确认漏洞,并给出主要开发人员的联系方式
2018年9月26日 将漏洞详情发送给主要开发人员
2018年10月8日 第一次跟进进展情况
2018年11月9日 第二次跟进进展情况
2018年12月4日 第三次跟进进展情况
2019年3月14日 公开披露前跟进进展情况
2019年3月15日 公开披露0day漏洞
四、Shimo VPN帮助程序服务特权提升漏洞(CVE-2018-4006)
CVE-2018-4006(TALOS-2018-0675)是一个可利用的权限提升漏洞,该漏洞位于Shimo VPN帮助程序服务中,具体而言是在其中的writeConfig函数。要成功利用该漏洞,需要对计算机进行本地访问,但可能允许攻击者将其权限升级为root。
4.1 CVSSv3评分
9.3 – CVSS:3.0/AV:L/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
4.2 CWE
CWE-19:输入验证不正确
4.3 漏洞详情
首次安装该应用程序时,帮助工具将以root身份安装,并且作为LaunchD守护程序。这就意味着,如果该程序被终止,将会立即重新启动。该服务的监听使用:
v3 = objc_msgSend(&OBJC_CLASS___NSXPCListener, "alloc");
v4 = objc_msgSend(v3, "initWithMachServiceName:", CFSTR("com.feingeist.shimo.helper"));
第二个参数注册作为服务传入的字符串,并提示它开始监听。这一过程,将会打开服务,以连接到使用Objective-C的XPC调用。该过程会执行类似于下列的代码段,从而将客户端连接到该服务a。
v8 = objc_msgSend(v7, "initWithMachServiceName:options:", CFSTR("com.feingeist.shimo.helper"), 4096LL); [1]
v11 = objc_msgSend(
&OBJC_CLASS___NSXPCInterface,
"interfaceWithProtocol:",
&OBJC_PROTOCOL___ShimoHelperToolProtocol); [2]
在[1]的位置,使用与上面相同的调用,options变量用于表示客户端正在连接,而不是正在监听中。在[2]中,传递了一个特殊的协议,它定义了客户端可用的所有功能。服务器必须定义相同的协议,才能使这些调用正常工作。我们查看协议时,发现了漏洞的存在。
存在漏洞的函数名称为writeConfig:atPath:withReply:,其代码如下所示:
data = arg_3
path = arg_4
syslog(5, "Running writeConfig in helper.");
v9 = objc_msgSend(arg_4, "stringByDeletingLastPathComponent"); [3]
v12 = objc_msgSend(v11, "fileExistsAtPath:", v27); [4]
if ( v12
||
objc_msgSend(v14, "createDirectoryAtPath:withIntermediateDirectories:attributes:error:", v27, 1LL, 0LL, &v30)
{
v21 = objc_msgSend(v20, "fileExistsAtPath:", v7);
if ( v21 )
{
objc_msgSend(v23, "removeItemAtPath:error:", v7, &v29); [5]
}
objc_msgSend(data, "writeToFile:atomically:encoding:error:", path, 1LL, 4LL, &error); [6]
在[3]的位置,传递了一个用于构造正确字符串的参数。然后,[4]将检查该参数是否作为文件存在。如果目录结构不存在,则尝试为其创建目录结构。在[5]的位置,如果传入文件存在,则会被删除。最后,在[6]的位置,传递给函数的数据被写入到提供的文件中。该漏洞允许非特权用户在特权位置写入特定的内容,该过程跨越了权限边界,导致了一个权限提升漏洞。
4.4 时间线
2018年9月21日 向厂商披露
2018年9月22日 厂商确认漏洞,并给出主要开发人员的联系方式
2018年9月26日 将漏洞详情发送给主要开发人员
2018年10月8日 第一次跟进进展情况
2018年11月9日 第二次跟进进展情况
2018年12月4日 第三次跟进进展情况
2019年3月14日 公开披露前跟进进展情况
2019年3月15日 公开披露0day漏洞
五、Shimo VPN帮助程序服务特权提升漏洞(CVE-2018-4007)
CVE-2018-4007(TALOS-2018-0676)是一个可利用的权限提升漏洞,该漏洞位于Shimo VPN帮助程序服务中,具体而言是在其中的deleteConfig函数。要成功利用该漏洞,需要对计算机进行本地访问,但可能允许攻击者删除系统上的任何受保护的文件。
5.1 CVSSv3评分
9.0 – CVSS:3.0/AV:L/AC:L/PR:N/UI:N/S:C/C:N/I:H/A:H
5.2 CWE
CWE-19:输入验证不正确
5.3 漏洞详情
首次安装该应用程序时,帮助工具将以root身份安装,并且作为LaunchD守护程序。这就意味着,如果该程序被终止,将会立即重新启动。该服务的监听使用:
v3 = objc_msgSend(&OBJC_CLASS___NSXPCListener, "alloc");
v4 = objc_msgSend(v3, "initWithMachServiceName:", CFSTR("com.feingeist.shimo.helper"));
第二个参数注册作为服务传入的字符串,并提示它开始监听。这一过程,将会打开服务,以连接到使用Objective-C的XPC调用。该过程会执行类似于下列的代码段,从而将客户端连接到该服务a。
v8 = objc_msgSend(v7, "initWithMachServiceName:options:", CFSTR("com.feingeist.shimo.helper"), 4096LL); [1]
v11 = objc_msgSend(
&OBJC_CLASS___NSXPCInterface,
"interfaceWithProtocol:",
&OBJC_PROTOCOL___ShimoHelperToolProtocol); [2]
在[1]的位置,使用与上面相同的调用,options变量用于表示客户端正在连接,而不是正在监听中。在[2]中,传递了一个特殊的协议,它定义了客户端可用的所有功能。服务器必须定义相同的协议,才能使这些调用正常工作。我们查看协议时,发现了漏洞的存在。
存在漏洞的函数名称是deleteConfigAtPath:withReply。该函数将脚本的路径位置作为参数,在未进行权限检查的前提下对其执行删除操作,具体代码如下所示:
v8 = objc_msgSend(v7, "fileExistsAtPath:", arg_3); [3]
if ( v8 )
{
objc_msgSend(v10, "removeItemAtPath:error:", arg_3, &error); [4]
}
在[3]的位置,将传入文件所在路径,并检查该文件是否存在。如果文件确实存在,将会在[4]的位置执行删除操作。该守护进程以root身份运行,可以删除系统上的任何文件,因此当非特权用户调用时,就会跨越权限边界,并产生一个权限提升的漏洞。
5.4 时间线
2018年9月21日 向厂商披露
2018年9月22日 厂商确认漏洞,并给出主要开发人员的联系方式
2018年9月26日 将漏洞详情发送给主要开发人员
2018年10月8日 第一次跟进进展情况
2018年11月9日 第二次跟进进展情况
2018年12月4日 第三次跟进进展情况
2019年3月14日 公开披露前跟进进展情况
2019年3月15日 公开披露0day漏洞
六、Shimo VPN帮助程序服务特权提升漏洞(CVE-2018-4008)
CVE-2018-4008(TALOS-2018-0677)是一个可利用的权限提升漏洞,该漏洞位于Shimo VPN帮助程序服务中,具体而言是在其中的RunVpncScript函数。要成功利用该漏洞,需要对计算机进行本地访问。该命令将在root环境下,接受用户提供的脚本参数并执行。
6.1 CVSSv3评分
9.3 – CVSS:3.0/AV:L/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
6.2 CWE
CWE-19:输入验证不正确
6.3 漏洞详情
首次安装该应用程序时,帮助工具将以root身份安装,并且作为LaunchD守护程序。这就意味着,如果该程序被终止,将会立即重新启动。该服务的监听使用:
v3 = objc_msgSend(&OBJC_CLASS___NSXPCListener, "alloc");
v4 = objc_msgSend(v3, "initWithMachServiceName:", CFSTR("com.feingeist.shimo.helper"));
第二个参数注册作为服务传入的字符串,并提示它开始监听。这一过程,将会打开服务,以连接到使用Objective-C的XPC调用。该过程会执行类似于下列的代码段,从而将客户端连接到该服务a。
v8 = objc_msgSend(v7, "initWithMachServiceName:options:", CFSTR("com.feingeist.shimo.helper"), 4096LL); [1]
v11 = objc_msgSend(
&OBJC_CLASS___NSXPCInterface,
"interfaceWithProtocol:",
&OBJC_PROTOCOL___ShimoHelperToolProtocol); [2]
在[1]的位置,使用与上面相同的调用,options变量用于表示客户端正在连接,而不是正在监听中。在[2]中,传递了一个特殊的协议,它定义了客户端可用的所有功能。服务器必须定义相同的协议,才能使这些调用正常工作。我们查看协议时,发现了漏洞的存在。
在提供的协议中,第一个函数名称为runVpncScript:withReason:withReply,相关代码如下所示:
v9 = objc_msgSend(arg_2, "UTF8String");
v11 = objc_msgSend(arg_4, "UTF8String");
syslog(5, "Running vpnc script '%s' in helper with reason '%s'.", v9, v11); [3]
LOBYTE(v9) = objc_msgSend(v13, "fileExistsAtPath:", v43);
if ( v9 )
{
(objc_msgSend)(v28, "setObject:forKeyedSubscript:", v42, CFSTR("reason"));
(objc_msgSend)(v20, "setEnvironment:", v28);
(objc_msgSend)(v20, "launch"); [4]
(objc_msgSend)(v20, "waitUntilExit");
v29 = v40;
if ( (objc_msgSend)(v20, "terminationStatus") )
{
v30 = objc_msgSend(
&OBJC_CLASS___NSError,
"errorWithShimoErrorCode:withMessage:",
72LL,
CFSTR("Could not run vpnc script."));
v31 = objc_retainAutoreleasedReturnValue(v30);
objc_release(v40);
v29 = v31;
在[3]的位置,展示了日志记录函数中使用了两个传入参数,根据日志表明,第一个参数是将要执行的脚本的位置。在[4]的位置,该脚本将被启动,并以root身份执行脚本中的任意内容。该过程中,没有对该文件的所有者或者路径执行验证检查,因此任何文件都可以传入,并且以root身份执行,从而导致存在一个权限提升的漏洞。
6.4 时间线
2018年9月21日 向厂商披露
2018年9月22日 厂商确认漏洞,并给出主要开发人员的联系方式
2018年9月26日 将漏洞详情发送给主要开发人员
2018年10月8日 第一次跟进进展情况
2018年11月9日 第二次跟进进展情况
2018年12月4日 第三次跟进进展情况
2019年3月14日 公开披露前跟进进展情况
2019年3月15日 公开披露0day漏洞
七、Shimo VPN帮助程序服务特权提升漏洞(CVE-2018-4009)
CVE-2018-4009(TALOS-2018-0678)是一个可利用的权限提升漏洞,该漏洞位于Shimo VPN帮助程序服务中,原因在于代码签名验证不正确。要成功利用该漏洞,需要对计算机进行本地访问,但可能允许攻击者将其权限升级为root。
7.1 CVSSv3评分
8.8 – CVSS:3.0/AV:L/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H
7.2 CWE
CWE-19:输入验证不正确
7.3 漏洞详情
首次安装该应用程序时,帮助工具将以root身份安装,并且作为LaunchD守护程序。这就意味着,如果该程序被终止,将会立即重新启动。该服务的监听使用:
v3 = objc_msgSend(&OBJC_CLASS___NSXPCListener, "alloc");
v4 = objc_msgSend(v3, "initWithMachServiceName:", CFSTR("com.feingeist.shimo.helper"));
第二个参数注册作为服务传入的字符串,并提示它开始监听。这一过程,将会打开服务,以连接到使用Objective-C的XPC调用。该过程会执行类似于下列的代码段,从而将客户端连接到该服务a。
v8 = objc_msgSend(v7, "initWithMachServiceName:options:", CFSTR("com.feingeist.shimo.helper"), 4096LL); [1]
v11 = objc_msgSend(
&OBJC_CLASS___NSXPCInterface,
"interfaceWithProtocol:",
&OBJC_PROTOCOL___ShimoHelperToolProtocol); [2]
在[1]的位置,使用与上面相同的调用,options变量用于表示客户端正在连接,而不是正在监听中。在[2]中,传递了一个特殊的协议,它定义了客户端可用的所有功能。服务器必须定义相同的协议,才能使这些调用正常工作。我们查看协议时,发现了漏洞的存在。
该漏洞存在于所有不同VPN服务的连接管理代码中。在这里,我们将仅以connectOpenVPNWithConfig:withManagementPort:withReply:为例进行漏洞说明。当首次安装Shimo应用程序时,它会捆绑多个VPN客户端,以实际对连接进行实例化,其中包括OpenConnect、OpenVPN和VPNC。所有这些可执行文件都容易受到该代码签名攻击。下面是connectOpenVPN命令的相关代码。
v20 = objc_msgSend(self->shimoBundle, "pathForAuxiliaryExecutable:", CFSTR("openvpn")); [3]
openvpn_path = objc_retainAutoreleasedReturnValue(v20);
...
(objc_msgSend)(
self,
"runServiceAtPath:withArguments:withComPort:waitUntilExit:withError:", [4]
openvpn_path,
arguments,
0LL,
1LL,
&v59);
上述的代码片段中,在[3]的位置,仅仅是获取OpenVPN可执行路径,并将其传递到一个辅助函数[4]中,该函数用于运行传递所需参数的服务。我们查看runServiceAtPath函数,可以明显发现这里存在漏洞。
if ( v13 = objc_msgSend(v11, "fileExistsAtPath:", v9), [5]
objc_release(v11),
v14 = v13 == 0,
v9 = v12,
v14) )
}
if ( -[ShimoHelperTool codeSignStateForExecutable:](self, "codeSignStateForExecutable:", v12) != 2 ) [6]
...
objc_msgSend(v16, "setLaunchPath:", v12);
objc_msgSend(v16, "setCurrentDirectoryPath:", self->tmpDirPath);
if ( v22 )
objc_msgSend(v16, "setArguments:", v22);
v37 = v16;
objc_msgSend(v16, "launch"); [7]
在[5]的位置,将验证传入的可执行文件是否实际存在。然后,在[6]的位置,将检查可执行文件是否经过正确的签名。随后,在[7]的位置,使用所需的参数启动程序。该代码的问题来源于位置[6]。如果我们查看函数codeSignStateForExecutable,它将会给我们提供更多有关该漏洞的信息。
v7 = 0LL;
v3 = objc_msgSend(&OBJC_CLASS___NSURL, "fileURLWithPath:", a3);
v4 = objc_retainAutoreleasedReturnValue(v3);
SecStaticCodeCreateWithPath(v4, 0LL, &v7);
v5 = 6;
if ( v7 )
{
switch ( SecStaticCodeCheckValidityWithErrors(v7, 6LL, 0LL, 0LL) + 67062 ) [8]
该函数首先验证文件是否存在于路径中。然后,在[8]的位置,它会调用Apple提供的安全API来检查可执行文件的代码签名。在该函数调用后,第二个函数将传递到代码签名验证的预期级别中。通过查看API,我们可以发现[6]与kSecCSBasicValidateOnly相关。这意味着,该检查只是验证代码是否经过正确签名,而并没有对签名的机构进行检查或验证。因此,可以在这里执行任何经过正确签名的二进制文件。创建一个自签名的证书,以通过该检查,这一过程是非常简单的。然后,攻击者就可以将任何应用程序放置在提供的可执行文件的位置,并在root环境中执行,从而产生权限提升漏洞。
7.4 漏洞利用概念证明
我们通过创建程序,并对该程序进行自行签名来证明漏洞,该程序包含在名为OpenVPN的报告中。
7.5 时间线
2018年9月21日 向厂商披露
2018年9月22日 厂商确认漏洞,并给出主要开发人员的联系方式
2018年9月26日 将漏洞详情发送给主要开发人员
2018年10月8日 第一次跟进进展情况
2018年11月9日 第二次跟进进展情况
2018年12月4日 第三次跟进进展情况
2019年3月14日 公开披露前跟进进展情况
2019年3月15日 公开披露0day漏洞
八、已知漏洞影响版本
Shimo VPN 4.1.5.1
当前官方暂未发布任何补丁、修复方案或缓解方案。
九、检测规则
以下Snort规则将尝试针对攻击进行检测。需要注意的是,可能会在未来某个日期发布其他规则,并且当前规则可能会发生更改,也有可能会加入其他的漏洞信息。有关最新的规则信息,请参阅Firepower管理中心或Snort.org。
Snort规则:47801 – 47804(https://snort.org/advisories/601)