官术网_书友最值得收藏!

2.3.8 弧注入

第2.3.7節描述過,對IsPasswordOK()程序中漏洞的第一次利用,通過修改函數返回地址的方式改變了程序的控制流(在該例中,繞過了密碼保護邏輯)。這種技術稱為弧注入(arc injection,有時也稱為return-into-libc),它將控制轉移到已經存在于程序內存空間中的代碼中。弧注入的利用方式是在程序的控制流“圖”中插入一段新的“弧”(表示控制流轉移),而不是進行代碼注入。很多高明的攻擊者偏愛采用這種技術,包括在棧上安裝一個已有函數的地址以及相應的參數(如system()或exec(),這種方式可以用于執行命令或已經存在于本地系統上的其他程序)。當返回地址從棧中彈出時(在x86架構上通過ret或者iret指令實現),程序的控制就被“返回”到攻擊者指定的函數中。通過調用system()或exec()這樣的函數,攻擊者可以輕易地在受攻擊的機器上建立一個shell,它具有和被攻擊程序相同的權限。

更糟糕的是,攻擊者可以利用弧注入執行一個函數序列,每個函數都使用攻擊者提供的參數。這樣,攻擊者就可以安裝并運行類似于一個包含函數鏈的小程序的代碼,從而增大攻擊的危害性。

下面是一個有緩沖區溢出漏洞的程序。


01  #include <string.h>
02  
03  int get_buff(char *user_input, size_t size){
04    char buff[40];
05    memcpy(buff, user_input, size);
06    return 0;
07  }
08  
09  int main(void) {
10    /* ... */
11    get_buff(tainted_char_array, tainted_size);
12    /* ... */
13  }

user_input中的被污染數據由memcpy()函數復制到buff字符數組中。如果user_input比buff緩沖區大,那么就會發生緩沖區溢出。

有很多原因導致攻擊者選擇使用弧注入更甚于代碼注入。因為弧注入使用那些已經存在于目標系統內存中的代碼,攻擊者僅僅需要提供函數地址和參數就可以發起成功的攻擊。這種類型的攻擊留下的痕跡很小,因此可以用于代碼注入無法得逞的漏洞利用情形。因為利用代碼包含完整的已存在代碼,所以無法通過基于內存保護的方案來防止它,比如無法用將內存段(例如棧)屬性設置為不可執行的方式來保護程序。它也可以通過恢復原有幀來防止被檢測。

鏈式函數調用可以讓攻擊者擁有更大的攻擊力。例如,一個嚴肅對待安全問題的程序員,可能會遵循最小特權原則[Saltzer 1975],即在不需要某些特權的情況下主動去除那些權限。但是,通過鏈式多函數調用,一個利用程序可以重新獲得那些權限,例如,可以在調用system()之前調用setuid()。

主站蜘蛛池模板: 瑞金市| 托里县| 儋州市| 嫩江县| 海南省| 吴江市| 顺平县| 正定县| 江孜县| 淮阳县| 河间市| 武强县| 会东县| 金溪县| 沧州市| 茂名市| 呼玛县| 大悟县| 华阴市| 交口县| 黄龙县| 和林格尔县| 聂拉木县| 洪泽县| 天全县| 佳木斯市| 安陆市| 新闻| 青浦区| 化州市| 惠东县| 蓬安县| 札达县| 宣恩县| 洮南市| 安徽省| 洪洞县| 乌拉特后旗| 武义县| 肥乡县| 沈丘县|