Pwnable 1 - File Descriptor
"Introduction to Linux file descriptor"

After sshing into ther server


#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");
setregid(getegid(), getegid());
system("/bin/cat flag");
exit(0);
}
printf("learn about Linux file IO\n");
return 0;
}
Let us analyze it, First check is argc, that is argument count, which must be greater than 2. That means while running the fd binary, we must provide an argument with it. Next
int fd = atoi( argv[1] ) - 0x1234;
So fd is initialized with the first argument - 0x1234
But what does atoi does.

Now, that clear and out of the way. Next
int len = 0;
len = read(fd, buf, 32);
A variable len is initialized. Then read function is used to read input to buffer of exactly 32 bytes. But whats fd doing here ? Lets look at the manual page of read

So basically fd says from which File Descriptor should the read function take input from
fd = 0 means Standard Input fd = 1 means Standard Output fd = 2 means Standard Error
Next,
if(!strcmp("LETMEWIN\n", buf)){
printf("good job :)\n");
setregid(getegid(), getegid());
system("/bin/cat flag");
exit(0);
}
Then strcmp compares the input stored at buf with “LETMEWIN\n”, So if we want to give input by standard input, we must set fd = 0,
For that,

0x1234 is hex form, converting it to decimal gives 4660.
And that gives the flag.