目錄導航
- 打開題目審題
- 找到突破口
- 相關c語言知識
- 源代碼分析
- 找到FLAG
打開題目審題

Mommy! what is a file descriptor in Linux?
* try to play the wargame your self but if you are ABSOLUTE beginner, follow this tutorial link:
https://youtu.be/971eZhMHQQw
ssh fd@pwnable.kr -p2222 (pw:guest)
Linux中的檔案描述符是什么,如果你是完全的初學者,可以去youtube鏈接看視頻,
解釋下 SSH:
ssh fd@pwnable.kr -p2222 (pw:guest)
SSH 是Linux系統的登錄工具,現廣泛用于服務器登錄和各種加密通信,其實在這里就是一個終端連接工具,
所以,打開CMD

輸入命令回車,輸入密碼:guest ,即可登錄服務器,
登錄上就可以開始找flag了,
找到突破口
照例先 ls -la
fd@pwnable:~$ ls -la
total 40
drwxr-x--- 5 root fd 4096 Oct 26 2016 .
drwxr-xr-x 115 root root 4096 Dec 22 2020 ..
d--------- 2 root root 4096 Jun 12 2014 .bash_history
-r-sr-x--- 1 fd_pwn fd 7322 Jun 11 2014 fd
-rw-r--r-- 1 root root 418 Jun 11 2014 fd.c
-r--r----- 1 fd_pwn root 50 Jun 11 2014 flag
-rw------- 1 root root 128 Oct 26 2016 .gdb_history
dr-xr-xr-x 2 root root 4096 Dec 19 2016 .irssi
drwxr-xr-x 2 root root 4096 Oct 23 2016 .pwntools-cache
發現flag檔案,嘗試查看(肯定看不了
fd@pwnable:~$ cat flag
cat: flag: Permission denied
fd@pwnable:~$
果然不能看,
看下別的,檔案flag肯定是最后的答案,所以需要看看其他檔案找尋突破口,
還有一個c語言源檔案fd.c和可執行檔案fd,
那沒什么說的,看看fd.c,
fd@pwnable:~$ cat 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;
}
找到重點 system("/bin/cat flag");
看到原始碼大概已經明白了,我們沒有查看檔案的權限,但是fd有,所以只要分析如何讓代碼執行system("/bin/cat flag");即可,
相關c語言知識
int main( int argc , char * argv[ ] ,char * envp[ ])
main函式的引數串列保存了輸入引數的資訊:
第一個引數argc記錄了輸入引數的個數,且argc是包括程式本身在內的引數個數,如本題目,直接./fd運行,該引數實際上是1,而不是0,
第二個引數是字串陣列的,字串陣列的每個單元是char*型別的,指向一個c風格字串,arg[ ]指向的陣列中至少有一個字符指標,即arg[0].他通常指向程式中的可執行檔案的檔案名,
第三個引數是用來取得系統的環境變數,如:在DOS下,有一個PATH變數,當你在DOS提示符下輸入一個命令的時候,DOS會首先在當前目錄下找這個命令的執行檔案,如果找不到,則到PATH定義的路徑下去找,找到則執行,找不到回傳Bad command or file name ,在DOS命令提示符下鍵入set可查看系統的環境變數,
int atoi(const char * str)
**函式說明:**C 庫函式 int atoi(const char *str) 把引數 str 所指向的字串轉換為一個整數(型別為 int 型),
ssize_t read(int fd, void * buf, size_t count);
函式說明:read()會把引數fd 所指的檔案傳送count 個位元組到buf 指標所指的記憶體中. 若引數count 為0, 則read()不會有作用并回傳0. 回傳值為實際讀取到的位元組數, 如果回傳0, 表示已到達檔案尾或是無可讀取的資料,此外檔案讀寫位置會隨讀取到的位元組移動,
fd所指檔案指的是什么
每一個行程在行程控制塊中都保存著一分檔案描述符表,檔案描述符就是這個表的索引,檔案描述符表中每個表項都有一個指向已打開檔案的指標,
fd: 為打開檔案的檔案描述符,而每個行程都有一張檔案描述符表,fd檔案描述符就是這張表的索引,
Linux下 檔案描述符(fd)與 檔案指標(FILE*) 想了解更多可以看該鏈接,
簡言之,在linux中,值為0、1、2的fd,分別代表標準輸入、標準輸出、標準錯誤輸出,
源代碼分析
char buf[32];
int main(int argc, char* argv[], char* envp[]){
// 輸入引數不能少于2 接一個引數就可以
if(argc<2){
printf("pass argv[1] a number\n");
return 0;
}
// 將 argv[1] - 0x1234 賦值給fd
int fd = atoi( argv[1] ) - 0x1234;
int len = 0;
// 讀取32位元組到buf中,那么fd 必須為標準輸入 即為0
len = read(fd, buf, 32);
// buf 中32位元組一定是 LETMEWIN 這樣就能得到flag
if(!strcmp("LETMEWIN\n", buf)){
printf("good job :)\n");
system("/bin/cat flag");
exit(0);
}
printf("learn about Linux file IO\n");
return 0;
}
代碼看完了,想必如何做出來也都心里有數了,
引數一定要滿足 fd=0 那么 引數 argv[1] = 0x1234 = 4660,

最后在輸入“LETMEWIN” 即可,
找到FLAG
執行可執行檔案fd,./fd 4660 回車,
fd@pwnable:~$ ./fd 4660
此時開始執行len = read(fd, buf, 32); 輸入“LETMEWIN” 回車即可得到flag,
fd@pwnable:~$ ./fd 4660
LETMEWIN
good job :)
mommy! I think I know what a file descriptor is!!
flag:mommy! I think I know what a file descriptor is!!

輸入驗證即可,
參考:
https://www.cnblogs.com/ftl1012/p/ssh.html
https://blog.csdn.net/qq_40657299/article/details/78332875
http://c.biancheng.net/cpp/html/239.html
https://blog.csdn.net/qq_31967569/article/details/81145309
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/350831.html
標籤:其他
上一篇:全域敏感度,區域敏感度和平滑敏感度到底有什么區別?【差分隱私】
下一篇:結業賽部分題解
