歡迎來到興華永恒!加入收藏設為首頁
您當前所在位置:首頁 > 技術專欄 > 專業發布
技術專欄

針對CVE-2015-2545漏洞研究分析(上篇)



1. 概述

這是一種MSOffice漏洞,允許通過使用特殊的 Encapsulated PostScript (EPS)圖形文件任意執行代碼。這種漏洞于2015年3月被發現,漏洞未修補情況持續了4個月。之后,微軟發布了修復補丁(MS15-099),解決了這一安全問題。

漏洞發布時間:2015-09-08    
漏洞更新時間:2015-09-08
影響系統

Microsoft Office 2007 SP3
Microsoft Office 2010 SP2
Microsoft Office 2013 SP1
Microsoft Office 2013 RT SP1
Microsoft Office for Mac 2011
Microsoft Office for Mac 2016
Microsoft Office Compatibility Pack SP3

漏洞信息
Microsoft Office是一款微軟發布的辦公處理應用套件。
Microsoft Office處理EPS文件存在內存破壞,允許攻擊者構建惡意文件,誘使應用解析,可使應用程序崩潰或執行任意代碼。
用戶可參考如下廠商提供的安全補丁以修復該漏洞:https://technet.microsoft.com/library/security/ms15-099

2. 樣本來源

通過`推特`搜索`cve-2015-2545`得到相關信息,篩選信息得到其哈希值`哈希值:375e51a989525cfec8296faaffdefa35`,之后Google搜索其哈希值,在`https://www.hybrid-analysis.com/`得到樣本。

3. 分析

3.1 漏洞成因以及利用

當EPS在處理`字典類型(dict)`的`copy操作`時,將會接受拷貝方的`鍵值對`,并且將自身空間數據全部刪除,然后再重新分配一個空間進行數據拷貝(正常情況下字典拷貝時只對要拷貝的元素進行操作,而不影響其它元素)。而EPS在處理`forall操作`時,當處理類型為`字典(dict)`時,`forall`逐個處理字典(dict)中的每個`鍵值對`,`forall`會獲得`當前鍵值對`的`內容`以及一個`ptrNext指針`,并指向下一個要處理的鍵值對,并將鍵(key)和值(value)的內容放到`操作棧`中,然后進行`forall的處理過程(proc)`,處理完后`仍保留ptrNext指針`以此來處理下一個鍵值對。如果在`forall`處理過程中有字典的`拷貝(copy)`操作,copy操作會將`鍵值對`條目`全部刪除`,而forall的ptrNext指針仍`存在`,這時`ptrNext`就變成一個`野指針`,只要精心構造指針指向的數據,就可以達到利用效果。該樣本利用方式為通過該野指針構造出一個起始地址為0x0,大小為0x7fffffff的`string對象`,這樣就可以在該空間內作`任意`的`讀寫`操作以及后期的`ROP,Shellcode`的利用操作。

3.2 測試環境

1. Microsoft Windows [版本 6.1.7601] 旗艦版sp1 簡體中文 x86
2. Windows Debugger Version 6.12.0002.633 X86
3. IDA6.8.150423 (32-bit)
4. OllyDbg 1.0
5. Notepad++
6. Microsoft Office Word 2007(12.0.6612.1000) SP3 MSO(12.0.6607.10000)

3.3 調試方向

此樣本從3個方面來進行調試分析,第一個調試方向:定位簡單可以得到信息的位置`ROP`,第二個方向則為重點方向:產生`野指針的位置`,第三個方向:`Rop`+`Shellocde`,共3個方向進行調試分析。

3.4 調試分析-CreateFile入手[第一個方向]

1.通過Windbg打開樣本,直接運行,可以發現樣本在臨時目錄文件夾下進行創建文件操作,創建文件順序:plugin.dll > igfxe.exe,之后,直接想到的是在`ZwCreateFile`下斷點【此斷點位置不太好,因為word在打開的時候不斷的跑CreateFile,但通過追溯可以找到自己想要的內容】。

1491891625736921.png

圖1

2.回溯找到`ROP`,`圖2`call則為`rop`call,測試方式,自己在相應call下斷點,單步跟蹤即可,關于rop,換??臻g的操作以及后面的shellcode這里先不詳細分析,自己可以單步跟蹤即可。

1491891678660295.png

圖1

1491891731885110.png

圖2

3.5 調試分析-野指針產生過程[第二個方向]

3.5.1 簡易例子解釋UAF

此過程比較復雜,需要了解“PostScript”語法,可以下載<<PLRM2.pdf>>來學習;大家還要了解下關于`UAF`的簡單的知識,何為`UAF`?就是字面意思“釋放后重新使用“,例子如下:

#include<stdio.h>

    #include<stdlib.h>

    #include<malloc.h>

     

    void *pfunc1()

    {

        printf("testn");

    }

     

    typedef struct Object1_struct{

        int flag;

        void (*pfunc1)();

        char message[4];

    }OBJECT1;

     

    typedef struct Object2_struct{

        int flag;

        int flag2;

        char *welcome;

    }OBJECT2;

     

    int main()

    {

        int i;

        OBJECT1 *pObject1;

        OBJECT2 *pObject2;

        pObject1 = (OBJECT1 *)malloc(sizeof(OBJECT1));//init struct

        pObject1->flag = 1;

        //pObject1->pfunc1();

        //pObject1->message = "this is first create!";

         

        free(pObject1);

        /*forget pObject1 = NULL*/

        for(i=0;i<1000;i++)

        {

            pObject2 = (OBJECT2 *)malloc(sizeof(OBJECT2));//heap spray

            pObject2->flag=2;

            pObject2->flag2=4;

            pObject2->welcome = "AAAA";

        }

        /*fill pointer*/

     

        if(pObject1 != NULL)

            pObject1->pfunc1();

        return 0;

    }

3.5.2 優化PostScript

了解上面的知識之后我們需要定位漏洞出現的位置,我們知道此漏洞出現的位置是在forall操作里面發生的,這個時候可以看下word文件中鑲嵌的iamge1.eps文件,從文件可以看出代碼都被擠壓成一起了,很不方便觀看這些代碼,只能手動對關鍵代碼更改`[圖2]`所示

1491892229562806.png

圖1

1491892260864882.png

圖2

3.5.3 定位EPS樣本文件關鍵位置

從代碼上我們直觀發現的是`<00000000ff030000030000000000000000000000444444440005000000000000000000>`這一串東西,具體是什么我們現在先不需要考慮,然后我們可以看到forall操作{}里好多其他代碼,其中就包含了copy的操作,這個位置就是導致漏洞產生的地方,那我們怎么去定位呢?動態調試,?;厮莸姆绞竭@個有點坑,大概你跟一天也跟不到吧,因為里面操作特別多,要知道這里面每個操作都是一個函數,所以回溯的方法不太可取,這個時候就需要用到IDA,直接使用IDA打開漏洞模塊,打開之后我們應該想到,既然是操作,那么應該跟函數一樣有帶字符串的名字,那么我們是不是可以通過IDA–>shitf+f12【字符串窗口】–>查找forall這個函數呢?我們用`alt+t`查找下,果然,有了我們想要的東西`圖1`,我們跟進去,發現有個地方在引用`圖2`,我們繼續跟進去,直接定位到了`forall函數“圖3`,同理可得,我們可以定位到`copy`的函數與其他關鍵函數,然后動態調試跟蹤即可。

1491892699603586.png

圖1

2017-03-27_151229.png

圖2

2017-03-27_151248.png

圖3

3.5.4 關鍵函數斷點位置

首先我們在關鍵幾個位置下斷點,通過IDA得到偏移地址,直接Windbg or OD 定位相應位置即可,這里我用的是Windbg下斷點,下面列出的斷點是我調試了很多次所記錄下的斷點,大部分的斷點我都給下了主要為了了解下代碼流程方便觀看,其實剛剛開始調試只需要在forall一處下斷點即可,先了解其結構在觀察其做法,我們先斷第一個`forall`的位置

<`EPSIMP32!RegisterPercentCallback+0x4526`>

     0 e 6822bcc6     0001 (0001)  0:**** EPSIMP32!RegisterPercentCallback+0x4664 ".printf "forall_value_key_pNext""     1 e 6823cbe4     0001 (0001)  0:**** EPSIMP32!RegisterPercentCallback+0x15582 ".printf "dict1_dict2_Copy""     2 e 6823a4f0     0001 (0001)  0:**** EPSIMP32!RegisterPercentCallback+0x12e8e ".printf "dict1_dict2_copy_2""     3 e 6821a0e8     0001 (0001)  0:**** EPSIMP32+0x1a0e8 ".printf "_copy_delete ""     4 e 6823cd89     0001 (0001)  0:**** EPSIMP32!RegisterPercentCallback+0x15727 ".printf"copy_memcpy ""     5 e 6823ca58     0001 (0001)  0:**** EPSIMP32!RegisterPercentCallback+0x153f6 ".printf"_exch_fun_""     6 e 6823d592     0001 (0001)  0:**** EPSIMP32!RegisterPercentCallback+0x15f30 ".printf"_put_fun_""     7 e 6823d73c     0001 (0001)  0:**** EPSIMP32!RegisterPercentCallback+0x160da ".printf"_PutInterVal_fun_""     8 e 68230313     0001 (0001)  0:**** EPSIMP32!RegisterPercentCallback+0x8cb1 ".printf"_BytesavailabelFun_""     9 e 6823d8f5     0001 (0001)  0:**** EPSIMP32!RegisterPercentCallback+0x16293 ".printf"_StringFun_""    10 e 682312e6     0001 (0001)  0:**** EPSIMP32!RegisterPercentCallback+0x9c84 ".printf"_ShowFun_""    11 e 6823d830     0001 (0001)  0:**** EPSIMP32!RegisterPercentCallback+0x161ce ".printf"memcpy_putinterval_""    12 e 6820cff5     0001 (0001)  0:**** EPSIMP32+0xcff5 ".printf"memcpy_put_bitshift_and_add_""


3.5.5 關于forall操作函數

我們通過ida可以觀察forall是個`條件分支的語句`,通過查詢《PLRM2.PDF》得到關于forall的解釋,大約有4種情況,不過可以看出“array proc”與“packedarray proc”是一樣的類型都是數組類型,其它兩種類型分別是字典類型與字符串類型,驗證方式直接在image.eps文件中添加實驗代碼即可驗證。

2017-03-27_155149.png

圖1

1491893017468516.png

圖2





在線咨詢 周一至周五
09:00-18:00
老师让我脱她乳罩摸她乳视频