緩衝區溢出通常表現爲一個最爲常見的漏洞而存在於今天的各種軟件之中,黑客可以用惡意的輸入,從而更改程序的執行流程,由此入侵相應的進程、電腦、或整個域。如果進程運行於一個高度受信的賬戶之下,如管理員或本地系統賬戶,那麼黑客帶來的破壞將是極其嚴重,並有潛在廣泛傳播的危險。近幾年來爆發的一些"知名"病毒,如紅色代碼、衝擊波、震盪波等等,都源於C/C++代碼緩衝區溢出的結果。
從程序的角度來看,緩衝區溢出只是一個再簡單不過的編程錯誤--都是關於複製一個內存區域的內容到另一個內存區域,而目標內存區域容量太小無法容納。以下的代碼作了簡單的演示:
char* source = "A reasonably long string";
char dest[10];
::strcpy(dest, source);
在本例中,源字符串的長度爲25個字符(包括了空結束符),它對目標內存塊來說,無疑太大了,而目標內存塊聲明在堆棧上;當此代碼執行時,將會破壞掉原有堆棧,程序會因爲一個訪問違例而崩潰。如果此源內存塊由外部第三方提供,那麼就有可能存在一個漏洞,因爲它允許傳入函數的內存塊以一種特定的方式修改堆棧。
當在C/C++中調用一個函數時,調用函數的返回地址被存放在堆棧中,因此在被調用函數執行完畢時,執行流程能重新返回到原處。如果調用了一個可能包含潛在緩衝區溢出的函數,返回地址可能會被修改,而且執行流程將會跳到緩衝區數據中指定的地方。通過改變函數的返回地址,攻擊者可獲取進程中任意位置的代碼以執行,一般而言,主要可以兩種方式被利用:
·如果帶有漏洞的程序是已知、且容易訪問到的,攻擊者可查找某函數的地址,這通常會在所有進程實例的一處固定地址處被找到;並修改堆棧,等着此函數被調用。
·要執行的指令可作爲緩衝區的一部分傳遞到進程地址空間,攻擊者利用此來完成攻擊。