查看單個文章
舊 2006-03-13, 06:22 AM   #11 (permalink)
psac
榮譽會員
 
psac 的頭像
榮譽勳章
UID - 3662
在線等級: 級別:30 | 在線時長:1048小時 | 升級還需:37小時級別:30 | 在線時長:1048小時 | 升級還需:37小時級別:30 | 在線時長:1048小時 | 升級還需:37小時級別:30 | 在線時長:1048小時 | 升級還需:37小時級別:30 | 在線時長:1048小時 | 升級還需:37小時
註冊日期: 2002-12-07
住址: 木柵市立動物園
文章: 17381
現金: 5253 金幣
資產: 33853 金幣
預設

第二十四章------關於UNIX/Linux 

簡單說明:
UNIX/Linux 無疑是比windows更歷史悠久更出色的OS。可惜缺少了一些「平易近人」,讓許多人望而卻步。這裡也不打算講些什麼,想學它的人不如從學習怎麼找相關資料開始吧,哈哈。不過還是建議初學者從WINDOWS入手比較好一些,而且按市佔有率看,也應該多接觸WINDOWS系統。當然抽空熟悉一下U系統也是不錯的選項,這裡簡單介紹大家一點資料。  

相關資料:
rootkit綜述 http://www.sixthroom.com/ailan/f ;... 3&RootID=332&ID=332
Linux 使用技巧33條 http://www.sixthroom.com/ailan/f ;... 3&RootID=335&ID=335
Linux組態與最佳化經驗談 http://www.sixthroom.com/ailan/f ;... 3&RootID=337&ID=337
Unix**初學者指導 http://www.sixthroom.com/ailan/f ;... 3&RootID=336&ID=336
入侵UNIX http://www.sixthroom.com/ailan/f ;... 3&RootID=339&ID=339 

相關網址:
藍森林 http://lslnet.com/linux/
Linux大本營 http://lydr.myrice.com/ ;
LINUX-AID技術支持中心 http://www.linuxaid.com.cn/
LINUX-NOW http://new.linuxnow.com/
台灣LINUX協會 http://www.linux.org.tw/
GNU的官方網站 http://www.gnu.org/
中國科學技術大學Linux使用者協會
http://lug.ustc.edu.cn/ 

第二十五章------溢位 

簡單說明:
溢位對我們這些小鳥們屬於比較進階的玩意了。所以在這裡也不準備多提,否則就違反了這篇文章寫給初學者的初衷了。
緩衝區溢位
緩衝區是記憶體中存放資料的地方。在程序試圖將資料放到電腦記憶體中的某一位置,但沒有足夠空間時會發生緩衝區溢位。
緩衝區是程序執行時電腦記憶體中的一個連續的塊,它儲存了給定檔案檔案類型的資料。問題隨著動態分配變數而出現。為了不用太多的記憶體,一個有動態分配變數的程序在程序執行時才決定給他們分配多少記憶體。如果程序在動態分配緩衝區放入太多的資料會有什麼現象?它溢位了,漏到了別的地方。一個緩衝區溢位套用程式使用這個溢位的資料將彙編語言程式碼放到電腦的記憶體中,通常是產生root權限的地方。單單的緩衝區溢位,並不會產生安全問題。只有將溢位送到能夠以root權限執行指令的區域才行。這樣,一個緩衝區利用程序將能執行的指令放在了有root權限的記憶體中,從而一旦執行這些指令,就是以root權限控制了電腦。總結一下上面的描述。緩衝區溢位指的是一種系統攻擊的手段,通過往程序的緩衝區寫超出其長度的內容,造成緩衝區的溢位,從而破壞程序的堆疊,使程序轉而執行其它指令,以達到攻擊的目的。據統計,通過緩衝區溢位進行的攻擊占所有系統攻擊總數的80%以上。造成緩衝區溢位的原因是程序中沒有仔細檢查用戶輸入的參數。例如下面程序: 

  example0.c
  -----------------------------------------------------------
  void function(char *str) {
  char buffer[16];
  
  strcpy(buffer,str);
  }
  ----------------------------------------------------------- 

上面的strcpy()將直接把str中的內容copy到buffer中。這樣只要str的長度大於16,就會造成buffer的溢位,使程序執行出現錯誤。存在象strcpy這樣的問題的標準函數還有strcat(),sprintf(),vsprintf(),gets(),scanf(),以及在循環內的 getc(),fgetc(),getchar()等。在C語言中,靜態變數是分配在資料段中的,動態變數是分配在堆疊段的。緩衝區溢位是利用堆疊段的溢位的。一個程序在記憶體中通常分為程序段,資料端和堆疊三部分。程序段裡放著程序的機器碼和只讀資料,這個段通常是只讀,對它的寫操作是非法的。資料段放的是程序中的靜態資料。動態資料則通過堆疊來存放。在記憶體中,它們的位置如下: 

  
  --------\  記憶體低端
  |程序段|
  |---------|
  |資料段|
  |---------|
  |堆疊|
  \---------記憶體高端 

堆疊是記憶體中的一個連續的塊。一個叫堆疊游標的暫存器(SP)指向堆疊的推疊頂端。堆疊的底部是一個固定位址。堆疊有一個特點就是,後進先出。也就是說,後放入的資料第一個取出。它支持兩個操作,PUSH和POP。PUSH是將資料放到棧的頂端,POP是將推疊頂端的資料取出。在進階語言中,程序函數使用和函數中的臨時變數都用到堆疊。參數的傳送和返回值是也用到了堆疊。通常對局部變數的引用是通過指出它們對SP的偏移量來實現的。另外還有一個基址游標(FP,在 Intel晶片中是BP),許多編譯器實際上是用它來引用本地機變數和參數的。通常,參數的相對FP的偏移是正的,局部變數是負的。當程序中發生函數使用時,電腦做如下操作:首先把參數壓入堆疊;然後儲存指令暫存器(IP)中的內容,做為返回位址(RET);第三個放入堆疊的是基址暫存器(FP);然後把現用的棧游標(SP)拷貝到FP,做為新的基位址;最後為本地機變數留出一定空間,把SP減去適當的數值。 

  下面舉個例子:
  example1.c:
  ------------------------------------------------------------
  void function(int a, int b, int c) {
  char buffer1[5];
  char buffer2[10];
  }
  
  void main() {
  function(1,2,3);
  }
  ----------------------------------------------------------- 

為了理解程序是怎樣使用函數function()的,使用-S選項,在Linux下,用gcc進行編譯,產生彙編程式碼輸出: 

  $ gcc -S -o example1.s example1.c 

  看看輸出文件中使用函數的那部分: 

  pushl $3
  pushl $2
  pushl $1
  call function 

  這就將3個參數壓到堆疊裡了,並使用function()。指令call會將指令游標IP壓入堆疊。在返回時,RET要用到這個儲存的IP。在函數中,第一要做的事是進行一些必要的處理。每個函數都必須有這些程序: 

  
  pushl %ebp
  movl %esp,%ebp
  subl $20,%esp 

這幾條指令將EBP,基址游標放入堆疊。然後將當前SP拷貝到EBP。然後,為本地機變數分配空間,並將它們的大小從SP裡減掉。由於記憶體分配是以字為服務機構的,因此,這裡的buffer1用了8字元(2個字,一個字4字元)。Buffer2用了12字元(3個字)。所以這裡將ESP減了20。這樣,現在,堆疊看起來應該是這樣的。 


  低端記憶體高端記憶體
  buffer2 buffer1 sfp ret a b c
  < ------ [ ][ ][ ][ ][ ][ ][ ]
  推疊頂端棧底
  
  緩衝區溢位就是在一個緩衝區裡寫入過多的資料。那怎樣利用呢,看
一下下面程序:
  
  
  example2.c
  -----------------------------------------------------------
  void function(char *str) {
  char buffer[16];
  
  strcpy(buffer,str);
  }
  
  void main() {
  char large_string[256];
  int i;
  
  for( i = 0; i < 255; i++)
  large_string = 'A';
  
  function(large_string);
  }
  ------------------------------------------------------------ 

這個程序是一個傳統的緩衝區溢位編碼錯誤。函數將一個字元串不經過邊界檢查,拷貝到另一記憶體區域。當使用函數function()時,堆疊如下:
  
  低記憶體端buffer sfp ret *str高記憶體端
  < ------ [ ][ ][ ][ ]
  推疊頂端棧底 

很明顯,程序執行的結果是"Segmentation fault (core dumped)"或類似的出現錯誤資訊。因為從buffer開始的256個字元都將被*str的內容'A'覆蓋,包括sfp, ret,甚至*str。'A'的十六進值為0x41,所以函數的返回位址變成了0x41414141, 這超出了程序的位址空間,所以出現段錯誤。可見,緩衝區溢位允許我們改變一個函數的返回位址。通過這種方式,可以改變程序的執行順序。 

由於是簡單介紹給大家熟悉一下,所以在這裡不指出軟體了,如果大家有需要的話,可以在附錄中找到。 

相關資料:
緩衝區溢位及其攻擊 http://www.sixthroom.com/ailan/f ;... 3&RootID=312&ID=312
緩衝區溢位原理分析 http://www.sixthroom.com/ailan/f ;... 3&RootID=313&ID=313
更多資料請到 www.sixthroom.com 
__________________
http://bbsimg.qianlong.com/upload/01/08/29/68/1082968_1136014649812.gif
psac 目前離線  
送花文章: 3, 收花文章: 1631 篇, 收花: 3205 次