棧溢出:
棧溢出是緩衝區溢出的一種,分配的內存空間是有限的,如果輸入超長的字符串必然會導致溢出。緩衝區溢出中最危險的是堆棧溢出,因爲入侵者可以利用堆棧溢出,在函數返回時改變返回程序的地址,讓其跳轉到任意地址,帶來的危害一種是程序崩潰導致拒絕服務,另外一種就是跳轉並且執行一段惡意代碼比如得到系統權限。
原理:
先看一段代碼:
char dest[10];
scanf("%s",dest);
這兩行代碼聲明瞭一個局部變量,然後用scanf函數讀入字符串,但是這個程序沒有限制字符串長度的地方。如果用戶輸入的字符串長度大於十個字符,那麼就會產生棧溢出。
而函數的局部變量是存儲在棧中的,這種錯誤就是棧溢出。
利用:
還是剛纔的那一段代碼:
char dest[10];
scanf("%s",dest);
編譯之後用ida打開,應該是一個普通棧應該有的結構:
-0000000C dest db ? ;
-0000000b db ? ;
-0000000a db ? ;
-00000009 db ? ;
-00000008 db ? ;
-00000007 db ? ;
-00000006 db ? ;
-00000005 db ? ;
-00000004 db ? ;
-00000003 db ? ;
-00000002 db ? ;
-00000001 db ? ;
+00000000 s db 4 dup(?)
+00000004 r db 4 dup(?)
+00000008
+00000008 ; end of stack variables
dest就是剛纔scanf讀入字符串的存放位置。下面的“s”代表ebp寄存器(擴展基址指針寄存器,其內存放一個指針,該指針指向系統棧最上面一個棧幀的底部。)的位置,“r”代表的就是函數的返回位置。
如果我輸入的字符串過長,比如“aaaaaaaaaaaa”+“bbbb”+“cccc”,那麼現在棧中的數據會是這樣:
-0000000C dest db 'a' ;
-0000000b db 'a' ;
-0000000a db 'a' ;
-00000009 db 'a' ;
-00000008 db 'a' ;
-00000007 db 'a' ;
-00000006 db 'a' ;
-00000005 db 'a' ;
-00000004 db 'a' ;
-00000003 db 'a' ;
-00000002 db 'a' ;
-00000001 db 'a' ;
+00000000 s db 4 dup("bbbb")
+00000004 r db 4 dup("cccc")
+00000008
+00000008 ; end of stack variables
可以看到原來應該是函數返回地址的地方被覆蓋了,現在函數返回的時候eip指針值變成了“cccc”如果這裏不是“cccc”而是精心計算好的地址,那麼就會控制eip(執行接口程序)然後系統就會被黑客任意跳轉,並以此爲跳板進而控制電腦。