CVE-2020-3153:Cisco AnyConnect Installer本地提权漏洞分析及利用

admin 2023-11-30 01:55:58 AnQuanKeInfo 来源:ZONE.CI 全球网 0 阅读模式

 

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.exeC:\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.exeC:\Users\ATGO\AppData\Local\Temp\Cisco\25869.tmp\anyconnect-win-4.6.03049-core-vpn-webdeploy-k9.exe

4、vpnagent.exeC:\Users\ATGO\AppData\Local\Temp\D378.tmp\vpndownloader.exe拷贝至C:\ProgramData\Cisco\Cisco AnyConnect Secure Mobility Client\Temp\Downloader\vpndownloader.exe

5、vpnagentNT 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 1part 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-launchCAC-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.exeC:\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.exeNT AUTHORITY\SYSTEM权限,使用漏洞利用代码发送的CAC-nc-install命令作为参数来启动vpndownloader.exe副本。

4、vpndownloader.exeC:\anyconnect\cstub.exe拷贝到C:\ProgramData\Cisco\cstub.exe(基于原始路径的4级路径遍历,该路径紧邻我们构造的恶意dbghelp.dll)。需要注意的是,我们使用的是AnyConnect的Program Files目录中的vpndownloader.exe程序。

5、cstub.exeNT 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 参考资料

weinxin
版权声明
本站原创文章转载请注明文章出处及链接,谢谢合作!
评论:0   参与:  0