pwnable.kr(1) - fd

Problem

Points: 1 pt

1
2
3
4
5
6
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 [email protected] -p2222 (pw:guest)

Link

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#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;

}

Prepare

Linux fd(file descriptor)

fd是一個索引值,指向Kernel為維護每一個Process所打開文件的紀錄表。
當程式打開一個現有文件或者創建一個新文件時,Kernel會向Process回傳一個fd
通常適用於UNIXLinux的作業系統。

一般UNIX的Process中應該均有3個標準的POSIX fd,對應於3個標準輸出入流。

integer name <unistd.h> const <stdio.h> file stream
0 Standard input STDIN_FILENO stdin
1 Standard output STDOUT_FILENO stdout
2 Standard error STDERR_FILENO strerr

C read

1
2
#include <unistd.h>  
ssize\_t read(int fd, void \*buf, size\_t count);
1
return length of data read in.

C atoi

1
2
#include <stdlib.h>  
int atoi(const char \*str);
1
if str is a string can be convert to int, return it. otherwise return 0.  

Thinking

L6 顯示輸入必須包含一個參數。
L10 會用atoi方法轉成數字並且減掉0x1234(4460)。
L12 從fd讀取32Byte資料進入buff。

重點:如何控制讀取的資料為LETMEWIN\n即可獲得flag。

Solution

以本題來講,開檔是一個不需要執行的動作。
read的function是用來從STDIN獲得資料的手段。

所以我們需要讓fd為0來對應STDIN_FILENO, 因此輸入的參數必須減去0x1234剛好為0,
即為0x1234本身。

接著進入L13手動輸入資料,為了對應密碼,輸入LETMEWIN即可。
於是獲得flag。

Reference

File Descriptor