FD Writeup (Pwnable.kr)


About Pwnable.kr

pwnable.kr is a free, non-commercial wargame site that hosts hands-on binary-exploitation challenges you solve by SSH’ing into remote challenge accounts, analyzing provided binaries/source, and exploiting them to read flag files. It’s ideal for learning and practicing low-level hacking techniques (buffer overflows, format strings, heap/stack bugs) with community writeups and a ranking system.


Overview

FD is an easy binary exploitation challenge from “pwnable.kr”. As the title implies, the exploitation has something to do with file descriptors, which is part of Linux file IO.



Accessing the binary

We can access the challenge by connecting via SSH:

┌──(root㉿kali)-[/home/kali]
└─# ssh fd@pwnable.kr -p2222
[password: guest]

Looking inside the current directory, we have 3 files. There’s “fd” 32-bit binary, “fd.c” source code and “flag”. The goal is to find a bug in the binary/source code and exploit it, which gives us the flag.

fd@ubuntu:~$ ls -la
total 48
drwxr-x--- 5 root fd 4096 Apr 1 2025 .
drwxr-xr-x 118 root root 4096 Jun 1 12:05 ..
d--------- 2 root root 4096 Jun 12 2014 .bash_history
-r-xr-sr-x 1 root fd_pwn 15148 Mar 26 2025 fd
-rw-r--r-- 1 root root 452 Mar 26 2025 fd.c
-r--r----- 1 root fd_pwn 50 Apr 1 2025 flag
---------- 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
fd@ubuntu:~$ file fd
fd: setgid ELF 32-bit LSB pie executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, BuildID[sha1]=156ca9c174df927ecd7833a27d18d0dd5e413656, for GNU/Linux 3.2.0, not stripped

I ran the binary first to see it in action. It required an integer as argument.

fd@ubuntu:~$ ./fd
pass argv[1] a number
fd@ubuntu:~$ ./fd 25
learn about Linux file IO


Analyzing the source code

We can start by analyzing the source code. It looks like this:

For the sake of learning, we’re going to split the code into smaller parts and understand what each one does. There are couple things that we need to understand for solving this challenge.


First few lines are just importing necessary libraries and declaring a character buffer with the size of 32 bytes. Let’s dive into the “main” function.

1st part:

if(argc<2){
printf("pass argv[1] a number\n");
return 0;
}

Checks if the user passed additional argument. Otherwise exits the program.


2nd part:

int fd = atoi( argv[1] ) - 0x1234;
int len = 0;
len = read(fd, buf, 32);

This is the key part. It takes the value from user-supplied argument, converts it from ASCII to an integer, subtracts 0x1234, and stores the result in “fd” variable. This variable is then used as a parameter in “read” function, which reads 32 bytes of data into the “buf” buffer.

The “read” function is also referred to as “system call”, which is a special function, which asks the Linux kernel for some type of action (kernel sits between software and hardware). Reading data from the user, in this example. If you’re confused, don’t worry, we will return to this topic later.


3rd part:

if(!strcmp("LETMEWIN\n", buf)){
printf("good job :)\n");
setregid(getegid(), getegid());
system("/bin/cat flag");
exit(0);
}

Compares the data in the “buf” buffer to “LETMEWIN” string. If this condition succeeds, flag is printed for us.


4th part:

printf("learn about Linux file IO\n");
return 0;
}

If the condition above doesn’t succeed, it prints this message and exits the program. And that’s all.


Upon close inspection, the user-controlled file descriptor seems like an obvious weakness. Also, anytime you take input from users, you better make sure to validate and sanitize that input before letting it through your application.

Not even mentioning the fact that you should never allow users to have direct control over sensitive parts of your software, at least not without proper authentication. But we’re working with file descriptors here, we’ll look at how they work in just a moment.


Suggested literature

I found a great introduction to File IO (covering much more that is covered in this challenge) by University of Chicago on this link: https://www.classes.cs.uchicago.edu/archive/2017/winter/51081-1/LabFAQ/lab2/fileio.html. If you’re deeply interested or just tired of using ChatGPT all the time, you can give this one a shot.


Exploiting the file descriptor & reading the flag

To understand file descriptors, I used Google and ChatGPT for my research. TLDR; file descriptor is a small integer value that kernel returns after opening a file. This number then represents the file throughout the program.

Additionally, there’s a convention that file descriptor “0” represents standard input, “1” standard output and “2” standard error.

That means that if we use FD “0” with system calls like “read”, it will ask user to input data via standard input (from keyboard) and store it in the buffer.

Our plan is simple. Make the “fd” variable to be equal to “0” and then provide the winning string “LETMEWIN” via standard input.

int fd = atoi( argv[1] ) - 0x1234;
int len = 0;
len = read(fd, buf, 32);


First off, we have to convert the offset “0x1234” from hex to decimal. That gives us number 4660.

Passing this number as argument should set the file descriptor to “0” and the program should ask us for an input. When it does, we enter string “LETMEWIN”, what prints out the flag for us.

entered correct offset and string to get the flag

And that’s the challenge. If you got all the way here, well done!


Summary & final thoughts

FD is an easy and beginner-friendly binary exploitation challenge from “pwnable.kr”. It’s main theme are file descriptors. After successful exploitation, we understand what file descriptors are, how they work and why they are important to our programs.

This challenge serves as very simple introduction to basic Linux file IO and binary exploitation concepts. I’d recommend it to any new hacker, who is interested in the mystical world of reverse engineering and binary exploitation.

Comments

Popular posts from this blog

Hospital Writeup (HackTheBox Medium Machine)

Bucket Writeup (HackTheBox Medium Machine)

Mr Robot Writeup (Vulnhub Intermediate Machine)