作者:0431實驗室
公眾號:https://mp.weixin.qq.com/s/UwJPjsIYAU-U__QWCYN1zQ
0x01.漏洞描述
在GUN Bash 5.0 補丁11 shell.c的diable_priv_mode()中發現一個問題,默認情況下,如果Bash運行時其有效UID不等于其實際UID,它將通過將其有效UID設置為其真實UID來放棄特權。但是,這樣仍存在安全問題。在Linux和其他支持“保存的UID”功能的系統上,保存的UID不會被刪除。攻擊者可以在bash中執行命令"enable -f"在執行時加載新的內置組件,該組件可以使調用setuid()的共享對象并且重新獲得特權。然而,UID為0運行的二進制文件不受影響。
0x02.漏洞影響版本
version : < Bash 5.0補丁11版本
0x03.漏洞原理
1.shell.c的disable_priv_mode()是造成漏洞的函數

這里可以看到euid和uid不相等時,直接將uid賦值給了euid,對于原來的uid沒有進行任何處理,也就造成了euid和uid可能不相等
2.利用腳本原理

這里了是利用腳本的核心,使用C語言編寫。
void __attribute__((constructor))語法:這種特殊的GCC語法與函數一起使用時,在程序啟動時即在main()函數之前執行相同的函數
void __attribute __((destructor))語法:這種特殊的GCC語法與函數一起使用時,在程序通過_exit終止之前(即在main()函數之后)執行相同的函數
說明: 構造函數和析構函數的工作方式是,共享庫文件包含特殊節(ELF上的.ctors和.dtors),這些節分別包含對標記有構造函數和析構函數屬性的函數的引用。在加載/卸載庫時,動態加載程序會檢查是否存在此類部分,如果存在,則調用其中引用的函數。
關于這些方面的幾點值得注意:
void __attribute__((constructor))在加載共享庫時運行,通常在程序啟動期間運行。void __attribute __((destructor))在共享庫卸載時運行,通常在程序退出時運行。- 這兩個括號可能是為了將它們與函數調用區分開。
__attribute__是GCC特定的語法;不是函數或宏
initLibrary(void):能夠使得動態鏈接庫在main函數之前運行

這里先進行gcc -c -fPIC 表示程序在編譯階段先編譯不進行鏈接,然后再通過-share 選項生成動態鏈接庫libpwn.so
最后使用,enable -f ./libpwn.so qwe加載新的內置組件,從libpwn.so中重新執行setuid(),這時的$euid已將變成了攻擊者的uid,然后攻擊者的euid被重新設置為新的uid,這時攻擊者uid沒有變化,但是euid已經變成了被攻擊者的uid的了,這時就可以修改查看被攻擊者的文件。
0x04.漏洞利用
1.新建兩個用戶

2.bash版本也符合

3.在attacked用戶的根目錄下有一個security.txt文件,文件的權限如下圖所示

4.用戶hacker無法讀取文件

5.用戶hacker,查看/bin/bash的權限,如下圖所示

在這里我們可以看到,/bin/bash的所有者和所屬組是attacked和bash的權限,這里關鍵的是用戶的s權限。這里介紹一下s權限 ,包含S_ISUID、S_ISGID兩個常量在內,叫做強制位權限,作用在于設置使文件在執行階段具有文件所有者的權限,相當于臨時擁有文件所有者的身份。這里hacker用戶所使用的bash是attacked權限的bash。
6.這里我們查看用戶的id




這里我們可以看到攻擊者和被攻擊者的uid,gid,group不一致,并且hacker的/bin/bash權限符合漏洞的要求
7.執行exp,更改攻擊者的有效id

這里可以看到成功執行EXP,攻擊者的所有id如下圖所示

hacker的euid已經變成了被攻擊者的uid,并且攻擊者的uid被保留了下來。
8.hacker用戶查看attacked用戶下的security.txt文件

這里我們已經能查看attacked用戶的security.txt文件
0x05.漏洞修復原理

這里我們可以看到使用了setresuid(),setresgid(),定義在 <unistd.h>頭文件中
setresgid:分別設置真實的,有效的和保存過的組標識號
int setresuid(uid_t ruid ,uid_t euid ,uid_t suid );
setresuid:分別設置真實的,有效的和保存過的用戶標號
int setresgid(gid_t rgid ,gid_t egid ,gid_t sgid );
setresuid:非特權進程可以將其實際UID,有效UID和已保存的設置用戶ID更改為以下之一:當前實際UID,當前有效UID或當前已保存的設置用戶ID,特權進程(在Linux上,具有CAP_SETUID功能)可以將其實際UID,有效UID和已保存的set-user-ID設置為任意值,如果參數之一等于-1,則相應的值不會更改。setresgid的原理和setresuid的類似。
0x06.參考
https://www.exploit-db.com/exploits/47726
本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.bjnorthway.com/1093/
暫無評論