今天聽說了一個網站pwnable.kr。很適合初學者,就試着做了一道題目。
第一道題目,按照網頁上給的鏈接,使用putty鏈接工具聯入。
輸入ls命令查看文件內容。
很開心的看到了flag文件,於是直接打開,果然不出所料,我是沒有權限打開的。然後查看了一下fd.c的代碼。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char buf[32];
int main(int argc, char* argv[], char* envp[]){
if(argc<2){
printf("pass argv[1] a number\n");
return 0;
}
int fd = atoi( argv[1] ) - 0x1234;
int len = 0;
len = read(fd, buf, 32);
if(!strcmp("LETMEWIN\n", buf)){
printf("good job :)\n");
system("/bin/cat flag");
exit(0);
}
printf("learn about Linux file IO\n");
return 0;
}
很簡單的代碼。其實就是驗證BUF裏面是否是“LETMEWIN”;然後buf是從fd指向的文件讀出來的。
可是fd又是什麼呢,明顯是個int。這又怎麼指向文件呢。
原來在Linux下面,文件有一個文件符號表。每一個符號表裏面都會給本進程打開的文件建立索引。所謂的int fd。其實就是一個文件的索引編號。
下面要解決的問題就是,怎麼樣保證讓fd所指向的文件內容爲LETMEWIN。觀察上面的代碼我們可以發現這段代碼之前並沒有任何打開文件,所以我們可以讓下一個文件爲0 。也就是說構造第一個參數爲0x1234十進制的4660。然後接着按回車的時候回神奇地發現系統在等待,趁機把LETMEWIN輸進去,果然成功拿到flag。至於原理嗎?還是沒有搞太清楚,估計是索引發現文件不存在的時候就會默認讓新建一個文件。感興趣的話可以到Linux上跑一跑試一試。
通過這個題目,可以對Linux的文件系統有個初步瞭解,就像遊戲中問得一樣——:“Mommy! what is a file descriptor in Linux?”