Set-UID程序漏洞

實驗目的

本次實驗目的是深刻的瞭解SetUID程序,瞭解SetUID程序解決的問題。設計SetUID程序須要注意的地方。瞭解其潛在的安全問題。linux

實驗內容

Unix操做系統中,Set-UID是一個重要的安全機制。 Set-UID程序運行時,它被假設爲具備擁有者的權限。例如,若是該程序的全部者是root,那麼當任何人運行這個程序,該程序都能得到root的權限在執行過程當中Set-UID容許咱們作不少有趣的事情,但不幸的是,它也是許多很差的事情的罪魁禍首。所以,本實驗的目的有兩方面:程序員

(1)欣賞其好的一面:明白,爲何設置UID是必要的,它是如何實現的。shell

2)要注意其很差的一面,瞭解其潛在的安全問題。編程

實驗步驟安全

這是一個探索性的實驗,你的任務在Linux環境中和Set-UID機制玩遊戲,寫一份報告描述你的發現,你被要求在Linux中完成如下的實驗bash

1. 弄清楚爲何「passwd」,「chsh」,「su」,和「sudo」命令須要Set-UID機制,若是它們沒有這些機制的話,會發生什麼,若是你不熟悉這些程序,你能夠通話閱讀使用手冊來熟悉它,若是你拷貝這些命令到本身的目錄下,這些程序就不會是Set-UID程序,運行這些拷貝的程序,觀察將會發生什麼。 ide

圖1 拷貝程序到本身的目錄下函數

從上面能夠看出passwdsusudochsh被拷貝到lab1目錄下後,就再也不是setuid程序了。而這些程序在原目錄下是Set-UID程序。 學習

測試passwd chsh su sudo命令的做用測試

從上面能夠看出,passwd是用來修改當前用戶密碼的,chsh是用來修改默認的sh的,su是用來獲取管理員權限的,sudo是用來執行一個須要管理員權限的命令的。

運行lab1下的passwd chsh su sudo發現都失敗

運行lab1下的passwd chsh su sudo發現都失敗了。

思考1

Q:爲何要使用Set-UID程序?

A:由於passwd chsh su sudo都須要使得用戶能在普通權限下臨時具備root權限。從而能夠訪問和修改一些root權限下的文件,如shadow。可是,這個權限是受限的,有時還須要對用戶的身份進行驗證。

Q:SetUID的設計是必要的嗎?

A:設想一下,若是沒有SetUID程序。那麼普通用戶將沒有權限修改本身的密碼,沒有權限去運行不少程序。不能安裝軟件。全部,SetUID是一種相似於對用戶權限進行更精確粒度的控制。可是,用戶在編寫本身的SetUID程序時,須要很是的當心,否則可能會產生漏洞危害系統的安全。

 

二、linux環境下運行Set-UID 程序,同時描述而且解釋你的觀察結果

root方式登陸,拷貝/bin/zsh /tmp, 同時設置拷貝到tmp目錄下的zshset-uid root權限,而後以普通用戶登陸,運行/tmp/zsh。你會獲得root權限嗎?請描述你的結果。

(我是拷貝到了lab1

圖4 測試zsh是否能夠得到root權限

發現zsh是能得到root權限的,可見zsh是不安全的。接下來測試bash

圖5 測試bash是否安全

測試發現bash在一樣的狀況下,沒法獲取root權限。因而可知bash要比zsh更爲安全。

3. 從題目2能夠看出,/bin/bash有某種內在的保護機制能夠阻止Set-UID機制的濫用。爲了可以體驗這種內在的保護機制出現以前的情形,咱們打算使用另一種/bin/zsh。在一些linux的發行版中(好比RedoraUbuntu),/bin/sh其實是/bin/bash的符號連接。爲了使用zsh,咱們須要把/bin/sh連接到/bin/zsh

下面的指令將會把默認的shell指向zsh 

圖6 sh替換爲zsh

sh用符號鏈接到zsh

4. PATH環境變量

system(const char * cmd)系統調用函數被內嵌到一個程序中執行一個命令,system()調用/bin/sh來執行shell程序,而後shell程序區執行cmd命令。可是在一個Set-UID程序中system()函數調用shell是很是危險的,這是由於shell程序的行爲能夠被環境變量影響,好比PATH;而這些環境變量能夠在用戶的控制當中。經過控制這些變量,用心險惡的用戶就能夠控制Set-UID程序的行爲。

Q: 你可以設置這個Set-UID程序運行你本身的代碼而不是/bin/ls嗎?若是你能的話,你的代碼具備root權限嗎?描述並解釋你的觀察。

A能夠,基本思路是:經過修改PATH變量,是的system優先調用本身惡意製造的可執行程序ls

下面的Set-UID程序被用來執行/bin/ls命令;而後程序員能夠爲ls命令使用相對路徑,而不是絕對路徑。

7 a.c的源代碼

進行對a.c的攻擊

可見,在上述操做中,攻擊者能夠利用system查找程序時PATH的順序來攻擊。可見這樣的程序是存在漏洞的。

Q: 如今,修改/bin/sh使得其返回到/bin/bash,重複上面的攻擊,你仍然能夠得到root權限嗎?描述並解釋你的觀察。

A: 不能夠。bash有某種內在的保護機制能夠防止這種攻擊。

9 sh符號連接到bash

10 使用bash運行攻擊程序

使用bash重複上述的攻擊,發現bash沒有得到root權限,這說明攻擊失敗。可見bash有某種內在的保護機制使得針對SetUID的攻擊沒法生效。

Q: 你可以設置這個Set-UID程序運行你本身的代碼而不是/bin/ls嗎?若是你能的話,你的代碼具備root權限嗎?描述並解釋你的觀察。

A: 能夠具備root權限,我是這樣作的:首先把/bin/sh拷貝到/lab1目錄下面重命名爲ls將環境變量PATH設置爲當前目錄/tmp,運行編譯的程序system。就能夠得到root權限。首先確保/bin/目錄下的sh 符號連接到zsh,若是連接到bash,這種方式是獲取不到root權限的,緣由正如上面所敘述的那樣,/bin/bash有某種內在的保護機制能夠阻止Set-UID機制的濫用。

 

.sytem()execve()的不一樣

在你執行這個任務以前,確保/bin/sh指向zsh,事件背景:Bob在爲一家審計代理處工做,他正在調查一家公司是否存在詐騙行爲。爲了這個目的,他須要閱讀這家公司在Unix系統中的全部文件;另外一方面,爲了保護系統的可靠性,他不能修改任何一個文件。爲了達到這個目的,Vince——系統的超級用戶爲他寫了一個SET-ROOT-UID程序,而且給了Bob能夠執行它的權限。這個程序須要Bob在命令行中打出一個文件名,而後運行/bin/cat命令顯示這個文件。既然這個程序是以root權限運行的,它就能夠顯示Bob想看的任何一個文件。然而,既然這個程序沒有寫操做,Vince很確信Bob不能用這個程序修改任何文件。

作好準備,先把sh連接到zsh上,不然攻擊極可能失敗。

 

11 從新鏈接shzsh

編輯b.c,代碼以下:

12 編輯b.c的代碼

Qq = 0。這種方式,程序會使用system()調用命令行。這個命令安全碼?若是你是Bob,你能對系統的完整性妥協嗎?你能從新移動一個對你沒有寫權限的文件嗎?

A: 不安全。由於Bob能夠經過攻擊,刪改無權限訪問的一些文件。攻擊過程以下。

如今進行攻擊模擬:

13 編輯b.c的代碼

能夠看到,rootfile.dat不屬於Bob,可是Bob能成功利用漏洞將其刪除。

Q: 若是令q=1;在(a)中的攻擊還會有效嗎?請描述並解釋你的觀察。

A:無效,觀察以下。

14 編輯b.c的代碼,把q賦值爲1

重複上述攻擊。

15 execve進行攻擊

由此,可見system工做方式是,將後續的命令字符都傳遞給shell,交由shell來執行,這樣極可能被攻擊者利用shell的漏洞進行攻擊。

execve則是建立子進程,參數是傳遞給子進程的,所以能夠防止此類攻擊。

 

6. LD_PRELOAD環境變量

爲了保證Set-UID程序在LD_PRELOAD環境的操縱下是安全的,動態連接器會忽略環境變量,可是在某些條件下是例外的,在下面的任務中,咱們猜想這些特殊的條件究竟是什麼。

咱們創建一個動態連接庫。把下面的程序命名爲mylib.c。在函數庫libc中重載了sleep函數。

 

16 僞造sleep函數

用下面的命令編譯上面的程序

17 編譯上面的程序

編寫myprog.c

18 編寫myprog.c

編譯myprog.c

19 編譯myprog.c

在普通用戶下運行,myprog,發現連接到的是mylib

20 普通用戶下編譯普通用戶下執行

root下編譯myprog.out,並設置成SetUID程序。在普通用戶下執行。

 

21 root下編譯普通用戶下執行

發現是鏈接到真正的libc當中。

root下編譯myprog.out,並設置成SetUID程序。在root下執行。

21 root下編譯root下執行

發現,連接到的是mylib.c

在普通下編譯myprog.out,並設置成SetUID程序。在其餘用戶下執行。

21 普通用戶下編譯

在其餘用戶下運行

22 其餘普通用戶下運行

可見,只有用戶本身建立的程序本身去運行,纔會使用LD_PRELOAD環境變量,連接到本身的sleep函數,不然的話忽略LD_PRELOAD環境變量,不會連接到本身的sleep函數。

 

7. 消除和清理特權

爲了更加安全,Set-UID程序一般會調用setuid()系統調用函數永久的清除它們的root權限。然而有些時候,這樣作是遠遠不夠的。編譯接下來的這個程序,給這個程序設置root權限。在一個普通的用戶下,運行這個程序。

Q: 描述你所觀察到的狀況,/etc/zzz這個文件會被修改嗎?解釋你的觀察。

A: 會被修改。由於代碼中的fork函數會在建立子進程。子進程擁有父進程的數據、堆棧的拷貝。同時擁有的父進程的SetUID權限。在實際編程中,SetUID的程序每每會存在相似的漏洞,子進程能夠得到父進程的相關的權限,好比打開的文件,所以在設計SetUID程序時須要注意這些細節信息。防止被攻擊者利用。

 

23 編輯7.c的源代碼

 

24 運行後/etc/zzz文件內容

實驗總結

經過本次實驗,對SetUID產生了較爲初步的認識。同時,對以往編寫的代碼進行了思考。感受只有學習了信息安全,才能升入的把握程序內在的各類機制。從攻擊的角度能更加細緻的看待編程。由於只有懂得了程序正常工做的邏輯,才能從供給的角度對其進行破壞。所以更多的夯實基礎,纔是真正掌握信息安全的正確途徑。不可能一簇而就,沒有好的基礎就能學習好信息安全的知識。

相關文章
相關標籤/搜索