早些時間瞭解了競爭條件這個有趣的現象,底層原理不細講,可以看看網上pwn college的搬運 這裡還是簡單描述下
眾所周知,CPU從邏輯上是逐條指令執行的,但是當多個程序執行的時候,就會讓他們的指令交叉進行操作,如果兩個程序對同一檔案進行操作時,就有可能導致兩個程式對其讀取時的環境與對其操作時的環境不同,這裡舉一個漏洞程式作為示範,大家可以自己去編譯一下:
#include <assert.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
void intro(void)
{
printf("HaHa there's no input!\n");
printf("But i'll print Flag when num is 2!\n");
}
void check_input(char *filename)
{
int i;
FILE *f = fopen(filename, "r");
assert(f != NULL);
fscanf(f, "%d", &i);
fclose(f);
if(i != 0)
{
printf("Nah the file changed.I wont run anymore\n");
exit(0);
}
printf("check done!\n");
return;
}
int do_action(char *filename)
{
int i;
FILE *f = fopen(filename, "r");
assert(f != NULL);
fscanf(f, "%d", &i);
fclose(f);
printf("I wrote a %d to file just now!\n", i);
printf("Try 2 let me do it again(and again)!\n");
return i;
}
int main(void)
{
int i;
char *filename = "num";
intro();
check_input(filename);
do
{
sleep(1);
i = do_action(filename);
}while(i != 2);
printf("flag{FuLaGe}");
return 0;
}
(這裡為了簡單起見用了迴圈和sleep,其實正常示例程式應該去掉的,程式的邏輯也做了簡化,遇到錯誤居然不退出而是爆出flag嗎這種時候就需要去寫一個過濾輸出,忽略標準錯誤輸出等處理,而且可能很久不出結果,所以這裡就簡化了一下邏輯.另外這題其實會跟自己競爭的,單純兩個執行這個程式的死迴圈應該也會爆flag)
程式很正常的開啟了一個檔案並檢查裡面的內容,再寫入一個0,並且在非預期的時候退出,然而它忘了剛才寫了什麼再次開啟並告訴你剛才寫了什麼,並且在奇怪的時候輸出flag誒剛才明明不是這樣的啊.程式沒有輸入點,但是與檔案有互動(有點像之前做過的一道license,那道題利用檔案的內容進行溢位)但是這裡看得出來程式似乎沒有溢位點.誒!我有一計
while :; do echo "1" > num; done
很輕易的就爆出flag啦