0x00 前言
Cisco AnyConnect有多种更新方式,包括内置的一种自动更新功能,在过去几年中,这个功能已经被挖掘出多个权限提升漏洞。
在本文中,我将与大家分享如何开发CVE-2020-3153的漏洞利用代码,这是Cisco AnyConnect在4.8.02042版前存在的一个路径遍历漏洞,最终可实现权限提升。
0x01 漏洞描述
CVE-2020-3153是Windows版Cisco AnyConnect Secure Mobility Client安装组件中存在的一个漏洞,允许经过身份认证的本地攻击者将用户提供的文件以系统级别权限拷贝到系统级目录中。该漏洞的根源在于程序没有正确处理目录路径,攻击者可以创建一个恶意文件并拷贝到某个系统目录中,从而实现DLL预加载、DLL劫持以及相关攻击效果。为了利用该漏洞,攻击者需要具备目标Windows系统上的有效凭据。
说明:
1、本文针对的是AnyConnect 4.5.02036到4.6.03049的自动更新功能,我并没有机会研究4.7.x或4.8.x版的更新,但如下文所示,这些版本(4.8.02042之前)同样受漏洞影响。
2、本文重点关注的是CVE-2020-3153漏洞利用代码的开发,在研究过程中发现的其他潜在漏洞仍需进一步分析。
3、CVE-2020-3153最早由Yorick Koster发现,之后我想根据SSD Secure Disclosure提供的信息开发一个可实际利用的代码。
0x02 Cisco AnyConnect自动更新
根据Cisco官方文档,AnyConnect可以通过多种方式更新,其中就包含自动更新功能:
当AnyConnect连接ASA时,AnyConnect Downloader会检查ASA上是否加载了新版软件或者配置。如果满足条件,Downloader就会将更新数据下载到客户端,然后建立VPN隧道。
我们可以通过如下XML标签,在客户端设置(VPN配置)文件中启用或禁用这个功能:
<AutoUpdate UserControllable="false">true</AutoUpdate>
AnyConnect由各种可执行文件及程序库所组成,但最主要的两个组件为:
-
vpnagent.exe
:Cisco AnyConnect Secure Mobility Agent,这是以Local System
账户运行的一个服务; -
vpnui.exe
:AnyConnect GUI,以当前登录的用户身份运行。
这两个可执行程序会通过进程间通信(IPC)机制彼此通信,使用的是TCP/62522
端口(只适用于回环网络接口)。我们可以使用Wireshark在回环接口嗅探,捕捉VPN服务与GUI之间的通信流量。由于内容未加密,因此我们可以猜测每条信息的主要功能(比如更新信息、下载新设置等)。
在自动更新过程中,从GUI发送到服务端的报文中包含如下一条消息:
虽然现在我们并不是特别清楚两者使用的二进制协议,但还是能够看到一些本地路径及文件名。比如,当前的用户名为ATGO
(下文中我们也将使用该用户)。此时如果使用Sysinternals的Process Monitor(ProcMon)工具,我们可以看到大量事件,但最为重要的是如下事件:
1、vpnui.exe
(以当前用户ATGO
权限运行)从ASA网关下载vpndownloader.exe
到C:\Users\ATGO\AppData\Local\Temp\D378.tmp\vpndownloader.exe
。
2、vpndownloader.exe
(步骤1下载的文件)以当前用户(ATGO
)权限运行(即由vpnui.exe
创建的进程),使用的命令为"C:\Users\ATGO\AppData\Local\Temp\D378.tmp\vpndownloader.exe" "-ipc gc"
。
3、vpndownloader.exe
从ASA网关下载anyconnect-win-4.6.03049-core-vpn-webdeploy-k9.exe
到C:\Users\ATGO\AppData\Local\Temp\Cisco\25869.tmp\anyconnect-win-4.6.03049-core-vpn-webdeploy-k9.exe
。
4、vpnagent.exe
将C:\Users\ATGO\AppData\Local\Temp\D378.tmp\vpndownloader.exe
拷贝至C:\ProgramData\Cisco\Cisco AnyConnect Secure Mobility Client\Temp\Downloader\vpndownloader.exe
。
5、vpnagent
以NT AUTHORITY\SYSTEM
权限,通过如下命令启动步骤4拷贝的vpndownloader.exe
:
"C:\ProgramData\Cisco\Cisco AnyConnect Secure Mobility Client\Temp\Downloader\vpndownloader.exe" "CAC-re-launch C:\Users\ATGO\AppData\Local\Temp\Cisco\25869.tmp\anyconnect-win-4.6.03049-core-vpn-webdeploy-k9.exe -"
6、anyconnect-win-4.6.03049-core-vpn-webdeploy-k9.exe
拷贝到C:\ProgramData\Cisco\Cisco AnyConnect Secure Mobility Client\Temp\Installer\23342.tmp\
,随后开始安装AnyConnect 4.6.03049。
以上步骤对应的流程图如下所示:
需要注意的是:
1、我观察到的这些事件来自于AnyConnect 4.5.02036到4.6.03049的升级过程。
2、从Wireshark的抓包结果中我们能看到所有路径(除了最后一个路径)。这意味着只有来自C:\Users\ATGO\AppData\Local\Temp
路径的文件名才会被GUI作为参数传递给agent端(Wireshark抓包结果中并没有引用到C:\ProgramData\Cisco\Cisco AnyConnect Secure Mobility Client\
路径)。
3、<xxx>.tmp
目录名采用随机值,在更新后会被清理。
4、用户不具备C:\ProgramData\Cisco\Cisco AnyConnect Secure Mobility Client\
路径下目录的写权限。
0x03 AnyConnect IPC协议
前文提到过,vpndownloader.exe
过去几年被曝存在多个漏洞。AnyConnect IPC协议已经被多个研究人员分析过,比如SerializingMe曾发表过几篇文章(part 1及part 2),网上也公开了滥用该协议的多个利用代码(比如Google Project Zero PoC for CVE-2015-6305)。
该协议使用TCP/62522
端口来发送一个Type-Length-Value(TLV)结构,前面Wireshark捕捉到的报文可解析出如下字段:
char packet[] = {
0x4f, 0x43, 0x53, 0x43, // Signature ("OCSC")
0x1a, 0x00, // Message header length
0xfe, 0x00, // Message body length
0xff, 0xff, 0xff, 0xff, // IPC response
0x00, 0x00, 0x00, 0x00, // Message user context
0x02, 0x00, 0x00, 0x00, // Request message identifier
0x00, 0x00, 0x00, 0x00, // Return IPC object
0x01, 0x02, // Message type
0x00, 0x01, // Index
0x00, 0x3c, // Length
//Value: C:\Users\ATGO\AppData\Local\Temp\D378.tmp\vpndownloader.exe
0x43, 0x3a, 0x5c, 0x55, 0x73, 0x65, 0x72, 0x73,
0x5c, 0x41, 0x54, 0x47, 0x4f, 0x5c, 0x41, 0x70,
0x70, 0x44, 0x61, 0x74, 0x61, 0x5c, 0x4c, 0x6f,
0x63, 0x61, 0x6c, 0x5c, 0x54, 0x65, 0x6d, 0x70,
0x5c, 0x44, 0x33, 0x37, 0x38, 0x2e, 0x74, 0x6d,
0x70, 0x5c, 0x76, 0x70, 0x6e, 0x64, 0x6f, 0x77,
0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x72, 0x2e,
0x65, 0x78, 0x65, 0x00,
0x00, 0x02, // Index
0x00, 0x76, // Length
//Value: "CAC-re-launch\tC:\Users\ATGO\AppData\Local\Temp\Cisco\25869.tmp\anyconnect-win-4.6.03049-core-vpn-webdeploy-k9.exe\t-"
0x22, 0x43, 0x41, 0x43, 0x2d, 0x72, 0x65, 0x2d,
0x6c, 0x61, 0x75, 0x6e, 0x63, 0x68, 0x09, 0x43,
0x3a, 0x5c, 0x55, 0x73, 0x65, 0x72, 0x73, 0x5c,
0x41, 0x54, 0x47, 0x4f, 0x5c, 0x41, 0x70, 0x70,
0x44, 0x61, 0x74, 0x61, 0x5c, 0x4c, 0x6f, 0x63,
0x61, 0x6c, 0x5c, 0x54, 0x65, 0x6d, 0x70, 0x5c,
0x43, 0x69, 0x73, 0x63, 0x6f, 0x5c, 0x32, 0x35,
0x38, 0x36, 0x39, 0x2e, 0x74, 0x6d, 0x70, 0x5c,
0x61, 0x6e, 0x79, 0x63, 0x6f, 0x6e, 0x6e, 0x65,
0x63, 0x74, 0x2d, 0x77, 0x69, 0x6e, 0x2d, 0x34,
0x2e, 0x36, 0x2e, 0x30, 0x33, 0x30, 0x34, 0x39,
0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2d, 0x76, 0x70,
0x6e, 0x2d, 0x77, 0x65, 0x62, 0x64, 0x65, 0x70,
0x6c, 0x6f, 0x79, 0x2d, 0x6b, 0x39, 0x2e, 0x65,
0x78, 0x65, 0x09, 0x2d, 0x22, 0x00,
0x80, 0x05, 0x00, 0x00, // Use installed false
0x00, 0x06, // Index
0x00, 0x3c, // Length
//Value: C:\Users\ATGO\AppData\Local\Temp\D378.tmp\vpndownloader.exe
0x43, 0x3a, 0x5c, 0x55, 0x73, 0x65, 0x72, 0x73,
0x5c, 0x41, 0x54, 0x47, 0x4f, 0x5c, 0x41, 0x70,
0x70, 0x44, 0x61, 0x74, 0x61, 0x5c, 0x4c, 0x6f,
0x63, 0x61, 0x6c, 0x5c, 0x54, 0x65, 0x6d, 0x70,
0x5c, 0x44, 0x33, 0x37, 0x38, 0x2e, 0x74, 0x6d,
0x70, 0x5c, 0x76, 0x70, 0x6e, 0x64, 0x6f, 0x77,
0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x72, 0x2e,
0x65, 0x78, 0x65, 0x00
};
需要注意的是,这个协议并没有经过加密,并且发送方没有经过身份认证(没有消息签名机制)。因此,本地非特权用户可以通过回环接口来写入和发送任意IPC消息。
因此,如果将发送的TLV消息中的anyconnect-win-4.6.03049-core-vpn-webdeploy-k9.exe
改为cmd.exe
,然后在ProcMon中观察,我们可以看到cmd.exe
文件会被拷贝到C:\ProgramData\Cisco\Cisco AnyConnect Secure Mobility Client\Temp\Installer\xxxxx.tmp\
。然而cmd.exe
并没有被执行,在Windows Event Viewer中我们能看到如下错误消息:
由于该程序没有经过Cisco (Cisco Systems, Inc.)签名,因此会出现这种行为。
0x04 路径遍历
在原始的漏洞公告中,作者提到如下信息:
当(用户提供的)可执行文件被拷贝到临时目录时,就会存在目录遍历漏洞。
vpndownloader.exe
会从源文件名中提取目标文件名,并且会搜索源路径中最后出现的反斜杠符(\
),将该符号右侧的路径当成文件名,然后作为目标文件名使用。AnyConnect并没有考虑到Windows API同样可以接受正斜杠符(/
)作为目录分隔符。因此,vpndownloader.exe
可以在其临时目录之外创建文件。
根据ProcMon中观察到的事件(参考前文的“Cisco AnyConnect自动更新”),我们可知IPC消息中存在所有路径(除了C:\ProgramData\Cisco\Cisco AnyConnect Secure Mobility Client\Temp\Installer\xxxxx.tmp\
),因此我认为该漏洞存在于vpndownloader.exe
对参数的解析方式中:
"CAC-re-launch C:\Users\ATGO\AppData\Local\Temp\Cisco\25869.tmp\anyconnect-[...]-k9.exe -"
事实上,我们可以将C:\Users\ATGO\AppData\Local\Temp\Cisco\25869.tmp\anyconnect-[...]-k9.exe
替换为C:\myOwnPath\nope\nope\nope\nope\../../../../anyconnect.exe
,然后anyconnect.exe
文件(其实际路径为C:\myOwnPath\anyconnect.exe
)会被移动到C:\ProgramData\Cisco\
(而不是C:\ProgramData\Cisco\Cisco AnyConnect Secure Mobility Client\Temp\Installer\xxxxx.tmp\
),因为vpndownloader
会将对应的文件名解析为../../../../anyconnect.exe
,从而实现4级的目录遍历效果。
在这个阶段,由于文件移动操作使用高权限来完成(因为该步骤中vpndownloader
程序由vpnagent
启动),因此我们可以写入驱动器上的任意文件。此外,如果被移动的目标为经过Cisco签名的一个二进制文件,那么该文件还会由vpnagent
服务以NT AUTHORITY\SYSTEM
权限运行。下面我们将分析如何结合这两个问题来开发一个稳定的权限提升利用代码。
0x05 权限提升
vpndownloader相关“命令”
简单逆向分析vpndownloader.exe
后,我们可以找到如下“CAC”(全称可能代表的是Cisco AnyConnect
)命令:
CAC-move
CAC-vcredist-install
CAC-re-launch
CAC-nc-install
第一条命令似乎是用来移动(替换)客户端XML设置文件(VPN配置文件)。根据下一条命令的名称,该命令可能是用来安装Visual C++ Redistributable软件包。我发现至少CAC-re-launch
、CAC-nc-install
以及CAC-vcredist-install
这些命令存在路径遍历问题。
我选择使用CAC-NC-install
命令,因为该命令利用起来比较可靠。
通过DLL劫持利用漏洞
根据漏洞发现者的安全公告以及SSD安全公告,cstub.exe
(主机扫描工具)是经过Cisco签名的一个程序,而且也存在DLL劫持漏洞:cstub.exe
会搜寻名为dbghelp.dll
的一个DLL。
因此我修改了利用代码,将合法的(经过签名的)cstub.exe
移动到某个目录,而普通用户能将恶意dbghelp.dll
释放到该目录(DLL植入攻击)。
标准用户并不具备C:\ProgramData\Cisco\Cisco AnyConnect Secure Mobility Client
及其子目录的写权限,然而具备C:\ProgramData\Cisco\
目录的写权限。
为了简化代码,我将cstub.exe
的路径硬编码为C:\anyconnect\cstub.exe
。因此,为了成功利用该代码,C:\anyconnect\
目录中必须存在cstub.exe
,且C:\ProgramData\Cisco\
目录中需存在dbghelp.dll
。
伪造的dbghelp.dll
会运行一个高权限命令提示符,我直接复用了Google Project Zero PoC for CVE-2015-6305中提供的代码。
利用代码运行后会执行如下操作:
1、使用CAC-nc-install
命令以及如下字符串发送(非预期的)IPC消息:
C:\anyconnect\nope\nope\nope\nope\../../../../cstub.exe
2、vpnagent.exe
从C:\Program Files (x86)\Cisco\Cisco AnyConnect Secure Mobility Client\vpndownloader.exe
(我们在IPC消息中指定了该路径)路径中将vpndownloader.exe
拷贝到C:\ProgramData\Cisco\Cisco AnyConnect Secure Mobility Client\Temp\Downloader\vpndC:\ProgramData\Cisco\Cisco AnyConnect Secure Mobility Client\Temp\Downloader\vpndownloader.exe
。
3、vpnagent.exe
以NT AUTHORITY\SYSTEM
权限,使用漏洞利用代码发送的CAC-nc-install
命令作为参数来启动vpndownloader.exe
副本。
4、vpndownloader.exe
将C:\anyconnect\cstub.exe
拷贝到C:\ProgramData\Cisco\cstub.exe
(基于原始路径的4级路径遍历,该路径紧邻我们构造的恶意dbghelp.dll
)。需要注意的是,我们使用的是AnyConnect的Program Files
目录中的vpndownloader.exe
程序。
5、cstub.exe
以NT AUTHORITY\SYSTEM
执行,加载恶意的dbghelp.dll
(DLL劫持)。
6、dbghelp.dll
中的代码以本地系统账户身份执行,导致普通用户桌面上下文中生成一个高权限的命令提示符。
整个攻击路程图如下所示:
执行前的效果如下:
执行后的效果如下:
ipc参数
开发好的PoC可以在AnyConnect 4.5.02036以及4.6.03049版本上运行,然而无法适用于AnyConnect 4.7.x以及4.8.x版(4.8.02042之前的版本)。
使用ProcMon来分析,我们可以看到cstub.exe
程序并没有拷贝到C:\ProgramData\Cisco\
目录中,并且Windows Event Viewer中能看到如下错误日志:
分析4.6.03049及4.7.04056版vpndownloader.exe
的区别后,我们找到了如下不同点(红色部分为4.7.x
新增的改动):
根据这些信息,结合前面的错误消息,我们知道需要修改CAC-nc-install
命令,添加一个-ipc=
参数。此时我并不清楚目标预期的值,但猜测这是一个整数值(因为我们能看到“Downloader IPC port number not present”错误消息)。
根据发现该漏洞的研究人员提供的原始公告,程序预期的值的确为整数值。作者在利用代码中使用的值为65222
(IPC使用的TCP端口,原始开发者认为该参数会作为一种回调机制来使用),目前我们可以使用任意数值。随后,我研究了一下4.8.x版本中的CAC-move
命令(用来移动客户端XML设置文件),发现了-ipc=1844
这个特征字符串。在所有测试案例中,我们可以在回环接口上捕捉4.7.x/4.8.x的自动更新消息,从中提取该参数。
因此,我们可以在CAC-nc-install
命令后添加-ipc=1337
或者其他端口值,使利用代码适用于AnyConnect 4.7.x以及4.8.x(4.8.02042前的版本)。
需要注意的是,老版本的AnyConnect并不支持-ipc
参数。因此我在利用代码中首先会检查当前安装的AnyConnect版本,然后再写入恶意IPC消息。
0x06 适用于CVE-2020-3153的MSBuild启动程序
我还为C#版利用代码开发了一个MSBuild启动程序,以应对应用程序白名单机制,也能修改vpndownloader.exe
或者cstub.exe
的路径,不需要重新编译C#代码。
我们只要稍微修改C#源码,就能集成到XML格式的工程文件中:
1、类必须继承Task
并实现ITask
接口(public class Program : Task, ITask
)。
2、程序的主函数必须为public override bool Execute()
(并且返回boolean
值)。
3、必须在导入列表中添加Microsoft.Build.Framework
以及Microsoft.Build.Utilities
。
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- MSBuild launcher for CVE-2020-3153 -->
<!-- Usage: C:\Windows\Microsoft.Net\Framework64\v4.0.30319\MSBuild.exe c:\path\to\CVE-2020-3153.xml -->
<Target Name="CVE-2020-3153-Build">
<Program />
</Target>
<UsingTask
TaskName="Program"
TaskFactory="CodeTaskFactory"
AssemblyFile="C:\Windows\Microsoft.Net\Framework64\v4.0.30319\Microsoft.Build.Tasks.v4.0.dll" >
<ParameterGroup/>
<Task>
<Code Type="Class" Language="cs">
<![CDATA[
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
// C# program here
]]>
</Code>
</Task>
</UsingTask>
</Project>
进一步研究后,我发现vpndownloader.exe
也是Cisco签名的文件,并且该程序也存在相同的DLL劫持漏洞。
因此我修改了利用代码,将cstub.exe
替换为vpndownloader
,并且将dbghelp.dll
以Base64形式存放在代码中。
0x07 参考资料
- Cisco documentation
- Original advisory
- SSD Advisory
- Cisco Security Advisory
- SerializingMe article part 1 and part 2
- Google Project Zero PoC for CVE-2015-6305
发表评论
您还未登录,请先登录。
登录