久久天天躁狠狠躁夜夜av,国产脚交足免费视频,亚洲小说乱欧美另类,五月天国产亚洲av麻豆

918搏天堂

?
產(chǎn)品咨詢:4000 258 365 | 申請產(chǎn)品演示 | 渠道合作 | English
內(nèi)容中心
按關鍵字查找
數(shù)據(jù)庫安全漏洞淺析之緩沖區(qū)溢出漏洞(2)
作者:918搏天堂 發(fā)布時間:2017-01-25

前文中我們對數(shù)據(jù)庫安全漏洞中最為常見的一種——緩沖區(qū)溢出漏洞進行了簡單的概念介紹。在靜態(tài)數(shù)據(jù)溢出、棧溢出和堆溢出三種類型中,棧溢出和堆溢出相對來說更復雜,且危害范圍較大,在前文概念介紹的基礎上,本文對windows下的棧結構進行更直觀的介紹,通過構造一段代碼示例,更清晰的演示棧結構下的緩沖區(qū)溢出漏洞原理。

下面我們將構造一段代碼,完成3個任務:

1.演示W(wǎng)IN下棧的結構

2.演示緩沖區(qū)溢出改變函數(shù)控制流程

3.演示緩沖區(qū)溢出覆蓋返回地址(劫持函數(shù))

下面的程序包含一個主函數(shù)main和另外一個子函數(shù)re_choose。re_choose函數(shù)用于把從main函數(shù)中取得的輸入字符串和存儲的字符串liusicheng做對比。如果輸入的字符串和存儲的字符串一致則返回0。如果不一致則可能返回1或者-1。同時還人為制造了一個緩沖區(qū)溢出點strcpy(buffer,input)。input有1024的空間,而buffer只有44的空間。只要input超過44則就會引發(fā)緩沖區(qū)溢出。main函數(shù)取re_choose返回值如果返回1或-1走if。如果返回0則走else。將用緩沖區(qū)溢出來讓返回1或者-1也走else。

#include <stdio.h>

#include <string.h>

#define ture_password "liusicheng"

int re_choose (char *input)

{

int result;

char buffer[44];

result = strcmp(input,ture_password);       

strcpy(buffer,input);                 //緩沖注入點

return result;

}

 void main()

{

int choose=0;        

char input[1024];

scanf("%s",input);

choose=re_choose(input);

if (choose == 1 || choose == -1)

{

printf("error\n");

else

{

printf("ture\n");

}

}

     

編譯出上面代碼的release版,放入IDA pro中得到反編譯代碼。下圖是MAIN函數(shù)的流程結構。清楚的看到main函數(shù)的整個控制流程和main函數(shù)的棧從建立到銷毀的全過程。棧主要用在函數(shù)調(diào)用上。進程調(diào)用的開始會調(diào)用大量系統(tǒng)函數(shù),其中大量函數(shù)的地址是固定不變的(只和操作系統(tǒng)版本有關系),這些固定的函數(shù)將成為以后用于跳轉的平臺 。本文先不涉及這些函數(shù)。直接跳到main函數(shù)開始介紹。棧的結構是4個字節(jié)為一層。如果超過4個字節(jié)。按照4個整數(shù)倍存儲。不足4個字節(jié)按照4個字節(jié)存儲。棧的主要操作只有2種push和POP。push是把寄存器的內(nèi)容壓入到棧中,pop是把棧中的內(nèi)容釋放掉。ebp是當前棧幀的棧底,esp是當前棧幀的棧頂。(注意由于棧是順序執(zhí)行的所以同一時間只有一個棧頂和一個棧底。但棧底一般不是整個系統(tǒng)棧的棧底,而只是當前這個棧幀的棧底)。棧的結構采用先進先出,后進后出的原則。所以當創(chuàng)建一個棧的時候會遵循如下步驟:

1把上一個棧幀的棧底的指針壓入當前棧保存起來(push ebp)。這一步其實是2步:第一步壓入返回地址,第二步壓入當上一個棧幀的ebp。

2把上一個棧幀的棧底移動到上一個棧幀的棧頂(mov ebp,esp)。從此這個棧的棧底就確定且不會發(fā)生任何改變。棧頂esp會一直發(fā)生變化。

3接著分配局部函數(shù)(sub esp,404h)。本程序中2個變量1個是4字節(jié)1個是1024字節(jié)。加一起正好是0x404個字節(jié)。需要棧頂上移0x404。注意棧的方向和內(nèi)存相反。數(shù)據(jù)進入內(nèi)存是從低地址向高地址寫,而棧則是從高地址向低地址寫。正是這種結構,給了后來數(shù)據(jù)改寫之前數(shù)據(jù)的機會。棧頂?shù)闹禃S著棧中數(shù)據(jù)隨時進行調(diào)整。 


          20170125-1.jpg
注意:上圖中var_404= -404h、str1= -400h

  同樣棧撤銷的時候基本可以按照棧建立的逆操作進行。首先把棧底值覆蓋棧頂(mov esp,ebp)。接著棧中彈出當前ebp的值(pop ebp)。然后跳轉EIP中存儲的上個函數(shù)的返回地址(retn),回到前一個棧幀中(上一個函數(shù)中)刪除返回地址行(add esp 4)。到此棧被完全撤銷。至此一個棧從建立到撤銷的全部過程已經(jīng)完成。我們除了關心一個棧的創(chuàng)建和消亡,更關心的就是棧是如何傳遞返回值和參數(shù)的。下圖是re_choose的反匯編圖:清楚的解釋了,在棧中是如何傳參和返回值的。

20170125-3.png            

注上圖中 var_4= -4 、str1 = 8

main函數(shù)從 call sub_401000這句開始,創(chuàng)建子函數(shù)re_choose的棧幀,開始也是和main一樣的棧創(chuàng)建過程。直到執(zhí)行到 mov eax,[ebp+str1],這句就是大家最關心的傳參。在棧中固定不動的是棧底(ebp)。利用棧底為坐標向高位內(nèi)存移動8個字節(jié)取值。取到存在main中的input。放入eax寄存器中傳入re_choose用于計算。同樣的機制看后半段 從re_choose中 (mov eax,[ebp+var_4])取棧底向低地址偏移4個字節(jié)的內(nèi)容。存在eax中,main把eax值存入ebp-404(mov [ebp+var_404],eax)這個地址中用于后續(xù)的判斷。至此棧的基本結構基本操作已經(jīng)介紹完畢。棧緩沖區(qū)溢出的根源和棧的自身結構密切相關。正是由于棧中數(shù)據(jù)是先存入的在內(nèi)存高地址,后入的在內(nèi)存低地址。所以給了后入的機會,一旦超過棧原本分配的長度則會直接覆蓋原先存在內(nèi)存高地址中的數(shù)據(jù)或指令。從而帶來不可預知的結果。

至于函數(shù)的參數(shù)傳入的順序是從左到右還是從右到左(局部變量int a,b 是先壓a還是先壓b),函數(shù)返回時恢復棧平衡是讓母函數(shù)作還是子函數(shù)作。這部分和函數(shù)調(diào)用約定相關,主要的調(diào)用約定分為,_cdecl、_fastcall和_stdcall。一般VS默認采用 _stdcall和windows api保持一致。stdcall規(guī)則要求:參數(shù)從右向左壓。(int a,b 先壓b)。函數(shù)退出的時候自己清理棧中的參數(shù)。(圖中經(jīng)常會看到一個參數(shù)后面沒用直接被add esp 4了)

至此,通過上面緩沖區(qū)溢出漏洞的實例演示,你應該已經(jīng)了解了棧溢出的漏洞原理。后續(xù),我們將基于此實例,向大家介紹利用棧溢出漏洞的攻擊方式,以及隨之帶來的數(shù)據(jù)庫安全風險。通過這樣的實例演示,讓大家對此類漏洞原理產(chǎn)生深刻理解,并梳理出防護思路。


?
918搏天堂 ©2021 版權所有 京ICP備10053980號-1