Binary Exploitation [pwnable.kr] - (Level 1) FD

#Challange Description

Name FD
Points 7
Solves 12586 times
Category Exploitation
Description Mommy! what is a file descriptor in Linux?

Once you connect to the remote server you will see fd binary and fd.c file in the current directory.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// fd.c
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;
}

#Hint

Try to run the file with various parameters and observer the results, reading the code it is clear that it takes
one command-line parameter which is then conversed into integer and subtracted with a strange
number. Why is it so? the result of subtraction is then used as an fd parameter to read data
into the buffer and the buffer is compared with a string and if the string matches we have
the flag. Sweet!

But wait, from where is the read function reading the data from? From what I know read functions
the first parameter is a file descriptor, and file description is the value you get when you open a
file. In the code no file is opened, however, the file descriptor is calculated indirectly(by subtracting
from cmd-line value 0x1234) and used as fd parameter to read, what going on?

File Descriptor (fd) is a unique identifier return by Linux Kernel when you make an open system call.
This identifier is used later to do other operations like read, write, seek, etc. You must a have heard
Unix philosophy that Everything is a file in *nix. That’s right everything is a file, you open a
network socket you get a fd in return, you can do read/write on that. Then later the fd can be used to release the resource by doing a close system call or they are close by the kernel when the process dies/killed.

#Solution

Ok good, but what’s the mystery of read call without open? we don’t have any fd opened! right?

Wrong, but when kernel launches a new process by default it attached three file descriptor by default with every process, which is are stdin(fd=0), stdout=(fd=1) and strerr(fd=2). So any process will have atleast three open file descriptor, and this number increases in sequence for each open request.

So, there you have it, if you provide the value of fd=0 for read call you will halt for input from cmd terminal. The input number should be such that subtraction(by 0x1234) results in zero. Now all you have to do is type those sweet letters in proper order.

#Conclusion

All thought it was a very simple challenge but its good for people getting started with CTF’s and Linux exploitation.

Comments

Your browser is out-of-date!

Update your browser to view this website correctly.&npsb;Update my browser now

×