CVE-2017-0261及利用樣本分析

Gcow安全團隊發表於2020-08-14

CVE-2017-0261及利用樣本分析

注意事項:
1.本篇文章由Gcow安全團隊複眼小組的ERFZE師傅原創,未經許可禁止轉載
2.本篇文章一共2313字,39張圖,預計用時20分鐘
3.文中提及的方法僅供參考學習,若用在實際情況而造成的損失,本團隊以及本公眾號概不負責
4.若本篇文章中存在說得有錯誤或者模糊的環節,希望各位看官可以在後臺留言或者評論指出,本小組不勝感激!

0x01 漏洞描述

  • 成因:開啟Office文件時,FLTLDR.EXE將被用於渲染包含該漏洞的嵌入式EPS檔案。該檔案是由PostScript語言編寫而成,可以被攻擊者透過"save-restore"操作利用,其本質為一UAF漏洞。 當使用者開啟包含格式錯誤的圖形影像的檔案時,或者當使用者將格式錯誤的圖形影像插入到 Office 檔案時,該漏洞可能會受到利用。
  • 影響版本:Microsoft Office 2010 Service Pack 2、Microsoft Office 2013 Service Pack 1、Microsoft Office 2016

  • POC:kcufId's Github(https://github.com/kcufId/eps-CVE-2017-0261)

0x02 POC分析

筆者在網上尋找許久,並未找到包含EPSIMP32.FLT的Office安裝包。幸而kcufId師傅提供了一LoadEps.exe用以載入EPS檔案,感謝kcufId師傅。

 

LoadEps.exe先是載入EPSIMP32.FLT

 

圖片1 載入EPSIMP32.FLT

 

之後呼叫ImportGr開始載入EPS檔案:

 

圖片2 ImportGr

 

於此處直接F7跟進,然後就可以成功斷在EPSIMP32.FLT內所設斷點。


 

在進入正題之前,先來鋪陳下Postscript物件結構。

// PostScript Object
struct PostScript object
{
    dword    type;
    dword    attr;
    dword    value1;
    dword    value2;    // if array, point to userdict where store the array object
}ps_obj;

其中不同type對應數值如下:

0x0           nulltype
0x3           integertype
0x5           realtype
0x8           booleantype
0x10          operatortype
0x20          marktype
0x40          savetype
0x300         nametype
0x500         stringtype
0x900         filetype
0x30000       arraytype          
0x0B0000     packedarraytype
0x70000     packedarraytype
0x110000      dicttype
0x210000      gstatetype

以字串為例,闡述其儲存結構。對forall函式設定斷點,便可以進一步檢視其如何處理字串(如何定位forall函式,可參閱https://paper.seebug.org/368/)。

 

圖片3 字串儲存結構

 

1號圖片對應ps_obj,其value2項指向索引列表中所對應項(2號圖片);索引項指向一大小為0x30的結構,該結構0x24位置儲存一指向大小為0x28結構(5號圖片)的指標的指標,0x2C位置儲存字串大小(3號圖片);5號圖片中結構0x4位置儲存該結構於索引列表中對應項的地址(即4號圖片的0x01DB5E94),0x20位置指向字串最終儲存位置(6號圖片),0x24位置為實際所佔記憶體大小——字串大小+1。

 

大小為0x30結構:

+0x0  dword   
+0x4  dword
+0x8  dword
+0xc  dword
+0x10 dword
+0x14 dword
+0x18 dword
+0x1c dword
+0x20 dword
+0x24 dword   pp_struct      //指向大小為0x28結構的指標的指標
+0x28 dword 
+0x2c dword   size           //字串實際大小

大小為0x28結構(換作陣列,該結構大小為0x2C,且0x28位置指向陣列元素,每一元素都是ps_obj):

+0x0  dword
+0x4  dword                    //儲存該結構於索引列表中對應項的地址
+0x8  dword
+0xc  dword
+0x10 dword
+0x14 dword
+0x18 dword
+0x1c dword
+0x20 dword  ptr_object     //指向字串最終儲存位置
+0x24 dword  size              //實際所佔記憶體大小,字串實際大小+1

 

漏洞第一次觸發:

 

圖片4 第一次

 

首先是將VM狀態儲存在l62變數內,之後對於l63變數內每一字元呼叫l61——>>l59——>>l56處理過程;l62 restore恢復之前的狀態,如此一來,/l62 save def語句後面l63申請的記憶體空間會被釋放,從而成為懸掛指標。

 

圖片5 l95-l99

 

l95-l99變數決定了後續流程,其值均為0(即32位):

 

圖片6 exch_proc

 

漏洞第二次觸發,首先是申請0x27大小(實際會佔用0x28)的記憶體空間儲存l63

 

圖片7 l63

 

之後l62 restore恢復之前的狀態,導致l63申請的記憶體空間被釋放,從而成為懸掛指標;接下來執行l100,之前l63所佔用記憶體空間會用來儲存l102(即l136)字串的0x28結構(這就解釋了l63為何會申請0x27大小記憶體空間):

 

圖片8 l102

 

分別獲取該結構0x4、0x20、0x24位置的數值:

 

圖片9 獲取值

 

最後修改l136字串內容(圖中僅展示了部分修改之處):

 

圖片10 構造字串

 

這些修改內容是精心構造的,會於第三次觸發漏洞時用到。

 

漏洞第三次觸發,申請包含0x37個元素的陣列,之後在迴圈到第0x34個元素時執行l62 restore

 

圖片11 第三次觸發流程

 

執行完restore之後,陣列的0x30結構被l193字串內容覆蓋:

 

圖片12 覆蓋內容

 

如此一來,最後一次(0x36)forall過程所執行的物件便成為上圖中0x30結構,而獲取其第0x36個元素便會來到第二次漏洞觸發時所精心構造的字串處:

 

圖片13 獲取陣列元素

 

而其獲取到的陣列元素是一大小為4的陣列,該陣列首元素是一起始地址為0,大小為0x7FFFFFFF的字串:

 

圖片14 陣列元素內容

 

該陣列會儲存在l159變數中,其首元素——起始地址為0,大小為0x7FFFFFFF的字串會儲存在l201變數中,之後便可透過l201變數獲取任意地址的值。

 

獲取kernel32.dll基址:

 

圖片15 獲取基址-1

 

圖片16 獲取基址-2

 

如此一來,l314變數記憶體儲的便是EPSIMP32.FLT基址。

 

圖片17 獲取基址-3

 

注:search命令語法如下:

 

圖片18 search

 

查詢指定gadget:

 

圖片19 gadget-1

 

圖片20 gadget-2

 

構造file型別結構:

    l199 l201 get_dword                          
    /l487 exch def
    l487 l201 get_dword
    /l488 exch def
    l488 36 my_add l201 get_dword
    /l489 exch def
    l489 l201 get_dword
    /l490 exch def
    l490 32 my_add l201 get_dword
    /l491 exch def
    l199 l491 l201 put_data_to_array
    l199 12 my_sub 2304 l201 put_data_to_array

圖片21 構造file type

 

l492地址(l491+0x32)處寫入構造資料:

        l492 0 l201 put_data_to_array                 %% 0x00 0
        l492 4 my_add l375 l201 put_data_to_array     %% 0x04 Address of <5E C3>
        l492 8 my_add l373 l201 put_data_to_array     %% 0x08 Address of <94 00 00 00 00 5E C3> 
        l492 12 my_add l377 l201 put_data_to_array    %% 0x0C Address of <C2 0C 00>
        l492 16 my_add l370 l201 put_data_to_array    %% 0x10 Address of VirtualProtect()
        l492 20 my_add 0 l201 put_data_to_array       %% 0x14 0
        l492 24 my_add 0 l201 put_data_to_array       %% 0x18 0
        l492 28 my_add 0 l201 put_data_to_array       %% 0x1C 0
        l492 32 my_add l368 l201 put_data_to_array    %% 0x20 Address of Shellcode
        l492 36 my_add l368 l201 put_data_to_array    %% 0x24 Address of Shellcode——lpAddress
        l492 40 my_add l349 l201 put_data_to_array    %% 0x28 Size of Shellcode——dwSize
        l492 44 my_add 64 l201 put_data_to_array      %% 0x2C PAGE_EXECUTE_READWRITE——flNewProtect
        l492 48 my_add l493 l201 put_data_to_array    %% 0x30 lpflOldProtect

最後,執行closefile指令時跳轉至Shellcode:

 

圖片22 closefile

0x03 樣本分析

EPS利用指令碼位於\word\media目錄下,解壓之後即可看到。該漏洞利用樣本除Shellcode部分,其餘基本一致,故以Patchword組織某樣本為例進行分析。

檔名:Cyber_Secure_Pakistan.docx

MD5:DD89BBB916A2C909630EC78CBB0E13E5

 

跳轉到Shellcode,恢復堆疊:

 

圖片23 恢復堆疊

 

申請記憶體:

 

圖片24 VirtualAlloc

 

獲取函式呼叫地址:

 

圖片25 函式呼叫地址

 

除錯過程中,可能是因為環境問題導致CreateToolhelp32Snapshot函式呼叫地址未成功獲取:

 

圖片26 CreateToolhelp32Snapshot

 

手動填入地址並開啟Word以繼續分析。列舉程式,查詢WINWORD.exe:

 

圖片27 列舉程式

 

C:\ProgramData\Microsoft\DeviceSync目錄下建立一名為MSBuild.exe的程式:

 

圖片28 建立MSBuild.exe

 

寫入檔案內容,其內容儲存於EPS指令碼的payload_32變數內:

 

圖片29 WriteFile

 

圖片30 payload_32

 

建立vmtools.dll檔案:

 

圖片31 建立vmtools.dll

 

寫入檔案內容,其內容儲存於EPS指令碼的payload_32_f2變數內:

 

圖片32 WriteFile

 

圖片33 payload_32_f2

 

建立VMwareCplLauncher.exe檔案:

 

圖片34 建立VMwareCplLauncher.exe

 

其內容儲存於EPS指令碼的payload_32_f1變數內:

 

圖片35 payload_32_f1

 

該檔案是具有Vmware簽名的白檔案:

 

圖片36 Vmware簽名

 

注入如下內容到explorer.exe中:

 

圖片37 注入explorer.exe

 

其功能為建立VMwareCplLauncher.exe程式:

 

圖片38 建立VMwareCplLauncher.exe程式

 

之後流程於360此篇報告(https://www.freebuf.com/vuls/157694.html)有提及,本文暫不涉及其分析部分:

 

圖片39 流程

 

有興趣的讀者可以進一步閱讀該報告。

 

注:該漏洞的利用樣本基本相似,不同之處在於最後的MSBuild.exe載荷,其儲存於EPS指令碼的payload_32變數內,可直接dump出來,填補完DOS檔案頭之後便可以拖進IDA分析。

0x04 參閱連結

  • EPS Processing Zero-Days Exploited by Multiple Threat Actors(https://www.fireeye.com/blog/threat-research/2017/05/eps-processing-zero-days.html)
  • CVE-2015-2545 Word 利用樣本分析(https://paper.seebug.org/368/)
  • PostScript LANGUAGE REFERENCE(https://web.archive.org/web/20170218093716/https://www.adobe.com/products/postscript/pdfs/PLRM.pdf)
  • 摩訶草組織最新漏洞攻擊樣本分析及預警(https://www.freebuf.com/vuls/157694.html)

相關文章