After you login with creds given for this challenge.

ssh fd@pwnable.kr -p2222 (pw:guest)

There is some list of files

fd@pwnable:~$ ls -la
total 40
drwxr-x---   5 root   fd   4096 Oct 26  2016 .
drwxr-xr-x 116 root   root 4096 Nov 11 14:52 ..
d---------   2 root   root 4096 Jun 12  2014 .bash_history
-r-sr-x---   1 fd_pwn fd   7322 Jun 11  2014 fd
-rw-r--r--   1 root   root  418 Jun 11  2014 fd.c
-r--r-----   1 fd_pwn root   50 Jun 11  2014 flag
-rw-------   1 root   root  128 Oct 26  2016 .gdb_history
dr-xr-xr-x   2 root   root 4096 Dec 19  2016 .irssi
drwxr-xr-x   2 root   root 4096 Oct 23  2016 .pwntools-cache

After look at the source code

    #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;
    
    }

i try to enter some random value as a argument for program.

fd@pwnable:~$ ./fd 1
learn about Linux file IO

lets take a look at the source code again for understand the flow

    char buf[32];

allocate the 32 bytes size for the buf array

then jump into the main part of the challenge.

    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);
        }

atoi is the funtion used to convert the string value to integers.

value of the 0x1234

Python 3.8.10 (default, Nov 26 2021, 20:14:08) 
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> 0x1234
4660

so the value of the 0x1234 is 4660

for our understanding let assume

fd = userinput - 4660

initiate the len variable with 0 len = 0

    len = read(fd, buf, 32);

read() - read from a file descriptor

fd needs to be 0, 1 or 2

then we can enter the input for the buf

it will compare the value with “LETMEWIN” then it will print the flag.

fd@pwnable:~$ ./fd 4660
LETMEWIN
good job :)
mommy! I think I know what a file descriptor is!!
fd@pwnable:~$ 

finally we got our flag!