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

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()。

主站蜘蛛池模板: 道孚县| 化州市| 诸暨市| 墨脱县| 海晏县| 吴旗县| 清水河县| 香港 | 大新县| 三穗县| 辽阳县| 榆社县| 绵竹市| 洪江市| 桦川县| 裕民县| 祥云县| 津市市| 邵东县| 同仁县| 平果县| 固安县| 定边县| 法库县| 内江市| 山阳县| 定兴县| 江津市| 大洼县| 鄢陵县| 郧西县| 囊谦县| 南雄市| 神农架林区| 凉城县| 三都| 台南县| 嵊州市| 荆州市| 苍山县| 利川市|