日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

作者: threepwn 合天智匯

0x01 前言

和我一樣,有一些計算機專業的同學可能一直都在不停地碼代碼,卻很少關注程序是怎么執行的,也不會考慮到自己寫的代碼是否會存在棧溢出漏洞,借此機會我們一起走進棧溢出。

0x02 程序是怎么運行的

在了解棧溢出之前我們先了解一下程序執行過程

程序的執行過程可看作連續的函數調用。當一個函數執行完畢時,程序要回到call指令的下一條指令繼續執行,函數調用過程通常使用堆棧實現

#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {
   test1(1);  
   test2(2);
   test3(3); 
   return 0;
}
int test1(int test1){
int a = 6;
  printf("1");
  return 1;
}
int test2(int test2){ 
  printf("2"); 
  return 2;
}
int test3(int test3){ 
  printf("3"); 
  return 3;
}

編譯成32位可執行文件,放在ollydbg中就行調試,來詳細看一下執行過程

因為程序的執行可以看做一個一個函數的執行(main函數也一樣),因此我們挑選其中一個即可,在test1()函數設置斷點

棧溢出漏洞原理詳解與利用

 

F7單步調試第一步mov dword ptr ss:[esp],0x1,進行傳參,簡潔明了。

第二步call mian.00401559,進入test(),這里我們關注一下esp和棧頂值,將該指令的下一條指令的地址進行壓棧,既然有壓棧那么就會有出棧,這就與函數中的retn指令形成呼應。

棧溢出漏洞原理詳解與利用

 

第三步push ebp,就是把ebp的值進行壓棧,那么這個ebp是什么呢?有什么用呢?

EBP叫做擴展基址指針寄存器(extended base pointer) ,里面放一個指針,該指針指向系統棧最上面一個棧幀的底部,用于C運行庫訪問棧中的局部變量和參數。那么這一步的意義就是:保存舊棧幀中的幀基指針以便函數返回時恢復舊棧幀

棧溢出漏洞原理詳解與利用

 

第四步,mov ebp,esp,將esp的值放在ebp中,我們再來了解一下什么是esp?

ESP(Extended Stack Pointer)為擴展棧指針寄存器,是指針寄存器的一種,用于存放函數棧頂指針,指向棧的棧頂(下一個壓入棧的活動記錄的頂部),也就是它不停在變,剛才提到的ebp指向棧底,在函數內部執行過程中是不變。

那么我們再看一下這一步的作用

從第三步可以知道esp存儲的值是舊棧幀中的幀基指針,而esp值棧頂指針,隨時都在變,因此為了函數結束后能恢復,把esp值(外層函數棧底地址)保存在本函數棧底ebp中。簡而言之,將內部函數ebp的值作為地址,它存放外函數的ebp的值。這一步在末尾也存在逆向指令leave。

棧溢出漏洞原理詳解與利用

 

第五步是sub esp,0x28,開辟該函數的局部變量空間

緊接著第六步mov dword ptr ss:[ebp-0xC],0x6,給變量a一個大小是0xC的空間,并且賦值。

然后就是傳參字符1的ascii碼,調用printf函數,把返回值放到eax。

我們重點來看leave指令,可以發現ebp的值恢復了,esp的值也變了,相當于mov esp,ebp;pop ebp

棧溢出漏洞原理詳解與利用

 

最后執行retn指令,至此一個函數執行完畢,esp和eip的值都被改變,相當于pop eip,然后程序繼續執行。EIP是指令寄存器,存放當前指令的下一條指令的地址。CPU該執行哪條指令就是通過EIP來指示的

棧溢出漏洞原理詳解與利用

 

0x03 棧溢出

分析完這一過程,相信大家對函數是怎么執行的應該明朗了,那么我們言歸正傳,繼續聊一下棧溢出。首先我們先看一下什么是棧?

棧可以看作是一個漏斗,棧底地址大,棧頂地址小,然后在一個存儲單元中,按照由小到大進行存儲,它的目的是賦予程序一個方便的途徑來訪問特定函數的局部數據,并從函數調用者那邊傳遞信息。

棧溢出屬于緩沖區溢出,指的是程序向棧中某個變量中寫入的字節數超過了這個變量本身所申請的字節數,因而導致與其相鄰的棧中的變量的值被改變。

另外,我們也不難發現,發生棧溢出的基本前提是:程序必須向棧上寫入數據、寫入的數據大小沒有被良好地控制。引用一個例子來了解一下棧溢出

#include <stdio.h>
#include <string.h>
void success() { puts("You Hava already controlled it."); }
void vulnerable() {  
    char s[12];  
    gets(s); 
    puts(s); 
    return;
}
int main(int argc, char **argv) {
    vulnerable();
    return 0;
}

很顯然符合以上兩個條件,gets()成為突破口我們在主函數處下斷點,運行和調試

棧溢出漏洞原理詳解與利用

 

lea eax,dword ptr ss:[ebp-0x14] 這時開辟一個空間給變量,也即是s,如圖所示

棧溢出漏洞原理詳解與利用

 

我們想執行sucess()函數,要怎么辦呢?

執行完vulnerable()函數后,會還原ebp,改變esp的值(leave),然后retn,也就是pop eip,然后CPU根據eip指針指向的指令繼續運行。

我們能抓到的點就是控制eip,怎么控制?通過控制棧頂的值,那么棧頂的值是什么?棧頂的值是進入該函數時儲存的下一條指令的地址。這里提一點,進入函數,要保存兩個值:下一條命令的地址、EBP舊棧幀的幀基指針,只有這樣才能完全恢復。

此時我們可以構造payload,來控制我們要控制的地方,棧中存儲EBP值的存儲單元的上一個存儲單元,也就是圖中的存儲address的存儲單元

我們先試驗一下輸入0x14 *'A'+BBBB+0000,發生的變化

棧溢出漏洞原理詳解與利用

 

很好,按照我們的預想進行(Python -c 'print "A"* 0x18+p32(0x00401520)') 就可以達到棧溢出的效果

棧溢出漏洞原理詳解與利用

 

0x04 尾記

還沒有入門,只是個人的見解,如有錯誤,希望各位大佬指出。參考:
https://en.wikipedia.org/wiki/Stack_buffer_overflow
https://ctf-wiki.github.io/ctf-wiki/pwn/linux/stackoverflow/stackoverflow-basic-zh/

高級棧溢出技術—ROP實戰

http://hetianlab.com/expc.do?ce=a763263a-de03-4368-a917-76bfb39f8c96

(學習ROP概念及其思路,了解高級棧溢出時需要注意的事項,并掌握解決方法)

聲明:筆者初衷用于分享與普及網絡知識,若讀者因此作出任何危害網絡安全行為后果自負,與合天智匯及原作者無關!

分享到:
標簽:溢出
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定