CHALLENGE DESCRIPTION:
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)
This is my writeup for an easy pwn challenge that has to do with file descriptors and the read() function. using the SSH creds given, we log onto the server and we list the files in the current directory to see an executable file, the source code to the executable as well as the flag, owned by root, which stops us from cheating. The challenge needs to be complete to read the flag. Let's see the files provided to complete the challenge. play the wargame here.
fd@pwnable:~$ ls
fd fd.c flag
Let's see more about the fd executable file....
fd@pwnable:~$ file fd
fd: setuid ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2,
for GNU/Linux 2.6.24 BuildID[sha1]=c5ecc1690866b3bb085d59e87aad26a1e386aaeb, not stripped
Turns out the challenge is a 32bit ELF file, dynamically linked, meaning that it has libc libraries it refers to when executing built-in C functions like printf() and system() functions and its not stripped, which makes it easy to reverse engineer if it ever comes to that. Let's open the fd.c file to see how the program is written to analyze the code.
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;
}
The goal is for the system("/bin/cat flag") to be executed to complete the challenge. For this to happen, we have to do some analysis on the code prior to this in order to see how we can achieve this. the source reveals a main() function which firstly checks if the command line arguments are two. if not it prints "pass argv[1] a number". If the arguments are two, it then goes forward to take the command line argument and passes it into the atoi() function which turns an ascii character to an integer. The next two lines show the 'len' variable contain zero. The next line pretty much shows the read() function at play. Looking into the manpages, we see the description of the function of the read() function
"The read() function shall attempt to read nbyte bytes from the file associated with the open file descriptor,
fildes, into the buffer pointed to by buf"
Linux File descriptors are as follows:
0: stdin
1: stdout
2: stderr
This indicates that if we can get the fd = 0, the program will take input from stdin, then we can go on and input 'LETMEWIN' since there is a strcmp() function
which compares the input places in buf with the string 'LETMEWIN'. The fd variable will take our command line argument and subtract it by 0x1234, which is 4660 in
ascii text. To exploit this, we simply execute the fd binary and insert 4660 as a command line argument and after input the 'LETMEWIN' string in order for the strcmp() function check
to evaluate to "True" (meaning the program must see that the string we put in and the string our input is compared to by the program evaluates to true so that the
system() function executes the "/bin/cat flag" gets executed for the flag to be captured.
fd@pwnable:~$ ./fd 4660
LETMEWIN
good job :)
mommy! I think I know what a file descriptor is!!
Challenge completed!
Flag: mommy! I think I know what a file descriptor is!!
No comments:
Post a Comment