*本文中涉及到的相關(guān)漏洞已報(bào)送廠商并得到修復(fù),本文僅限技術(shù)研究與討論,嚴(yán)禁用于非法用途,否則產(chǎn)生的一切后果自行承擔(dān)。
寫在前面的話
在這篇文章中,我將跟大家討論一個(gè)我在Panda反病毒產(chǎn)品中發(fā)現(xiàn)的一個(gè)安全漏洞(CVE-2019-12042),這是一個(gè)本地提權(quán)漏洞,該漏洞將允許攻擊者在目標(biāo)設(shè)備上將非特權(quán)賬戶提權(quán)至SYSTEM。
受影響的產(chǎn)品包括Panda Dome(版本< 18.07.03)、Panda InternetSecurity、Panda Antivirus Pro、PandaGlobal Protection、Panda Gold Protection和舊版本的Panda Antivirus(版本 <= 15.0.4)。
目前,廠商已經(jīng)在v18.07.03版本中修復(fù)了該漏洞。
漏洞分析
存在漏洞的系統(tǒng)服務(wù)為AgentSvc.exe這個(gè)服務(wù)可以創(chuàng)建一個(gè)全局Section對(duì)象和一個(gè)對(duì)應(yīng)的全局事件,每當(dāng)一個(gè)進(jìn)程嘗試向共享內(nèi)存寫入數(shù)據(jù)并需要服務(wù)進(jìn)程去處理這些數(shù)據(jù)時(shí),它們便會(huì)發(fā)出信號(hào)。由于這個(gè)過程中的權(quán)限驗(yàn)證機(jī)制存在缺陷,因此該漏洞將影響那些允許“Everyone”和非特權(quán)用戶修改共享內(nèi)存和事件的對(duì)象。


逆向工程與漏洞利用
這個(gè)服務(wù)會(huì)創(chuàng)建一個(gè)線程,該線程會(huì)無限期等待內(nèi)存更改事件,并在收到事件信號(hào)時(shí)解析內(nèi)存中的內(nèi)容。當(dāng)共享內(nèi)存中的第二個(gè)“值”不為零時(shí),它會(huì)使用一個(gè)指針來調(diào)用如下所示的函數(shù),指針指向的地址為列表頭部的值:

列表元素的結(jié)構(gòu)如下所示:
typedefstruct StdList_Event
{
struct StdList_Event* Next;
struct StdList_Event* Previous;
struct c_string
{
union
{
char* pStr;
char str[16];
};
unsignedint Length;
unsigned intInStructureStringMaxLen;
}DipsatcherEventString;
如下圖所示,代碼期望在共享內(nèi)存中偏移量為2的位置有一個(gè)unicode字符串,它會(huì)使用這個(gè)字符串來初始化一個(gè)wstring對(duì)象,并將其轉(zhuǎn)換為ANSI字符串。除此之外,在第50行代碼,使用了”3sa342ZvSfB68aEq”來初始化一個(gè)字符串,并將它和攻擊者可控制的ANSI字符串以及一個(gè)指針(指向一個(gè)輸出字符串對(duì)象)傳遞給函數(shù)”DecodeAndDecryptData”。

該函數(shù)會(huì)對(duì)這個(gè)base64字符串進(jìn)行解碼,然后使用RC2和密鑰“3sa342ZvSfB68aEq”揭密出結(jié)果值。所以,我們向共享內(nèi)存中寫入的內(nèi)容必須是經(jīng)過RC2加密并且使用Base64編碼的值。

當(dāng)函數(shù)返回結(jié)果時(shí),解碼后的數(shù)據(jù)會(huì)被轉(zhuǎn)換為“wstring”對(duì)象,而do-while循環(huán)會(huì)根據(jù)分隔符“|”來提取子字符串,并將它們分別插入到列表中,最后將它們以參數(shù)進(jìn)行傳遞。

我們回到線程的主函數(shù),如下所示,代碼會(huì)遍歷列表,并將字符串傳遞給Dispatcher.dll中CDispatcher類的InsertEvent方法:

我們對(duì)Dispatcher.dll文件中的CDispatcher::InsertEvent方法進(jìn)行了分析,發(fā)現(xiàn)它會(huì)向一個(gè)CQueue隊(duì)列中插入事件字符串:

CDispatcher::Run方法會(huì)運(yùn)行一個(gè)單獨(dú)的線程來處理這個(gè)隊(duì)列中的元素:

CRegisterPlugin::ProcessEvent方法會(huì)解析攻擊者控制的字符串,查看錯(cuò)誤調(diào)試消息,我們會(huì)發(fā)現(xiàn)我們面對(duì)的是一個(gè)開源的JSON解析器:【json-parser】。https://github.com/udp/json-parser

既然我們已經(jīng)知道了這個(gè)服務(wù)需要我們傳入哪種數(shù)據(jù),但我們還需要知道數(shù)據(jù)的JSON屬性。CDispatcher::Initialize方法會(huì)調(diào)用CRegisterPlugins::LoadAllPlugins方法來從注冊(cè)表中讀取Panda的安裝路徑,然后訪問插件目錄,然后加載其中所有的DLL文件。
其中一個(gè)DLL名叫Plugin_Commands.dll,它的功能貌似是執(zhí)行命令行指令。

由于這些DLL都可以提供錯(cuò)誤調(diào)試消息,這樣我們就可以輕松定位目標(biāo)方法了。我們也迅速找到了Plugin_Commands.dll中的Run方法:

在這個(gè)函數(shù)中,我們從輸入數(shù)據(jù)中找到了目標(biāo)JSON屬性:

我們還可以從內(nèi)核調(diào)試器中攔截部分JSON消息:

至此,我想看看是否能夠執(zhí)行硬盤中的某些東西。通過對(duì)Run方法的反編譯結(jié)果進(jìn)行分析,我們發(fā)現(xiàn)了一個(gè)函數(shù)可以解析相關(guān)的屬性值,并判斷其是否指向的是URL或是磁盤中的文件。這里,我們就可以使用file://URI來執(zhí)行硬盤中的文件了。

在查找強(qiáng)制屬性時(shí),我們發(fā)現(xiàn)至少要提供這兩個(gè)值:ExeName和SourcePath:


但是,當(dāng)我們?cè)谠O(shè)置了這兩個(gè)值之后將事件”CmdLineExecute”加入隊(duì)列,我們的進(jìn)程并沒有創(chuàng)建成功。調(diào)試之后,我發(fā)現(xiàn)“ExeMD5”也是一個(gè)強(qiáng)制屬性,它應(yīng)該包含待運(yùn)行的可執(zhí)行程序的有效MD5哈希。
CheckMD5Match函數(shù)會(huì)動(dòng)態(tài)計(jì)算文件哈希,并與我們提供的JSON屬性進(jìn)行對(duì)比。

成功執(zhí)行后的進(jìn)程流:

測(cè)試如下JSON數(shù)據(jù)(RC2+Base64編碼),我們可以看到cmd.exe成功以SYSTEM權(quán)限運(yùn)行了:
{
"CmdLineExecute":
{
"ExeName":"cmd.exe",
"SourcePath":"file://C:\\Windows\\System32",
"ExeMD5":"fef8118edf7918d3c795d6ef03800519"
}
}

當(dāng)我們嘗試提供自己的可執(zhí)行程序時(shí),Panda會(huì)將其檢測(cè)為惡意軟件并刪除之,即使該文件不是惡意軟件。此時(shí),我們可以讓cmd.exe來啟動(dòng)我們的進(jìn)程,最終的JSON數(shù)據(jù)如下所示:
{
"CmdLineExecute":
{
"ExeName":"cmd.exe",
"Parameters": "/c startC:\\Users\\VM\\Desktop\\run_me_as_system.exe",
"SourcePath":"file://C:\\Windows\\System32",
"ExeMD5":"fef8118edf7918d3c795d6ef03800519" //MD5 hash of CMD.EXE
}
}
最后的漏洞利用代碼會(huì)在目標(biāo)磁盤中存放一個(gè)文件,并計(jì)算cmd.exe的MD5哈希,構(gòu)建JSON數(shù)據(jù),對(duì)其加密并編碼,最終將其寫入共享內(nèi)存。
還需要注意的是,這個(gè)PoC漏洞利用代碼可以在不需要任何重新編譯操作的情況下在所有的Windows版本中正常工作。

PoC代碼
漏洞利用代碼:【GitHub傳送門】https://github.com/SouhailHammou/Panda-Antivirus-LPE
轉(zhuǎn)載來自FreeBuf.COM