在上一篇文章中,詳細介紹瞭如何使用vs2015實現緩衝區溢出攻擊,接下來,將以一個實例來演示如何繞過if判定,執行業務邏輯代碼。
代碼設計
模擬攻擊的代碼很簡單,如下:
1. #include <stdio.h>
2. #include <string.h>
3. int main()
4. {
5. char in[10];
6. printf("\nEnter Serial Number\n");
7. scanf("%s", in);
8. if(!strncmp(in, "S123N456", 8))
9. {
10. printf("Serial Number is correct\n"); // 緩衝區溢出,即使輸入錯誤的系列號,也
11. // 執行該語句
12.
13. }
14. return 0;
15. }
思考分析
要進行緩衝區溢出攻擊,可以下面兩方面考慮:
1. 直接覆蓋strncmp函數的返回地址。
2. 覆蓋main函數的返回地址。
然而strncmp函數的地址相對於在in的地址空間在低位,所以覆蓋strncmp的返回地址不可行,只能使用2方法,即只需要定位到main的返回地址的位置即可。
操作過程
對main中return中設置斷點,執行到下圖位置
在內存中搜索esp的位置,爲0x0068fd20,距離in的初始位置爲16bytes,故可以考慮輸入16字節,覆蓋返回地址,達到緩衝區溢出攻擊目的。
由於每條彙編指令的地址是32bit的,而我們輸入的字符是1byte=8bit,需要4個字符,而每個字符我們用ascll碼只能表示到127,即7f(16進制),所以7f的地址無法用輸入字符表示,緩衝區攻擊存在一定的運氣與偶然性。
經過N多次調試,總算找到printf(“Serial Number is correct\n”)
的入口地址可用輸入字符表示,地址如下:
留意到push地址爲 0x0119170f
在輸入字符中,則輸入以下字符:
後面的字符是通過control+字母輸入的,能夠表示低於27的ascll碼。
在返回main函數返回時,可以觀察到
其中覆蓋的地址爲0x0052fe58,爲esp棧頂指針地址,而對應的值爲0x0119170f,這個剛好是printf的入口地址,輸出內容如下:
可見,此時緩衝區攻擊成功。