0x00 前言
Cisco AnyConnect有多種更新方式,包括內置的一種自動更新功能,在過去幾年中,這個功能已經被挖掘出多個權限提升漏洞。0x01 漏洞描述
CVE-2020-3153是Windows版Cisco AnyConnect Secure Mobility Client安裝組件中存在的一個漏洞,允許經過身份認證的本地攻擊者將用戶提供的文件以系統級別權限拷貝到系統級目錄中。該漏洞的根源在於程序沒有正確處理目錄路徑,攻擊者可以創建一個惡意文件並拷貝到某個系統目錄中,從而實現DLL預加載、DLL劫持以及相關攻擊效果。為了利用該漏洞,攻擊者需要具備目標Windows系統上的有效憑據。0x02 Cisco AnyConnect自動更新
根據Cisco官方文檔,AnyConnect可以通過多種方式更新,其中就包含自動更新功能:<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, 0x1a, 0x00, 0xfe, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02,
0x00, 0x01, 0x00, 0x3c,
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, 0x00, 0x76,
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,
0x00, 0x06, 0x00, 0x3c,
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權限運行。下面我們將分析如何結合這兩個問題來開發一個穩定的權限提升利用代碼。權限提升
vpndownloader相關「命令」
簡單逆向分析vpndownloader.exe後,我們可以找到如下「CAC」(全稱可能代表的是Cisco AnyConnect)命令:第一條命令似乎是用來移動(替換)客戶端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.exe2、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">
<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 參考資料
SerializingMe article part 1 and part 2Google Project Zero PoC for CVE-2015-6305