Kamran Saifullah
4 min readNov 21, 2021

--

Pwnable — FD — Challenge

WarGames are really good at getting hand-on experience. In this article we are going to solve pwnable 1st challenge named “fd”.

http://pwnable.kr/play.php

Once we are logged into the target machine using the provided credentials. We can find the code as well as the executable that is required to solve the challenge.

The code which is really important to be looked at is as below.

int fd = atoi( argv[1] ) - 0x1234;int len = 0;len = read(fd, buf, 32);if(!strcmp("LETMEWIN\n", buf))

At first, we got to check what ATOI function really does. We can head up and can use the manual command on Linux system to understand more about this function.

So, as per the information provided. ATOI converts a string to an integer. fair enough. The result of [atoi( argv[1] ) — 0x1234] is pushed onto fd variable which is then being compared with the string “LETMEIN”.

The second function to be looked upon is the “read” function.

So, the read function is pushing the provided input as an argument 1 into the variable buf which holds 32 bit value.

Now, what we can do is, we can convert the 0x1234 value to integer and it becomes 4660. On supplying the integer value, the terminal halts as it is looking for the string to be compared. So we need to provide the “LETMEWIN” in order grab the flag.

Getting Into More Details

So, I was curious to understand more, so i decided to break down the program as per my own understanding and start to analyze how we got to the solution.

After playing with ATOI function. I found that supplying it with a string it returns 0, while supplying an integer value, it returns an integer value but it converts that string value provided as an argument 1 to a sequence of characters this, the value provided — 0x1234 yeilds results.

The next step is to check what will be the returning value when the user supplied data is negated with 0x1234 HEX value.

So, it means that the actual result is 4660. If we supply it as an input, our answer should be 0.

As we can see, indeed out answer becomes 0 on supplying 4660 value as argument 1. After this we can observe the following.

int len = 0 // The length variable is set to integer 0

After this, read function is used to read the value from the terminal i.e. the user input which is then pushed into BUF variable.

len = read(fd, buf, 32)
https://pubs.opengroup.org/onlinepubs/009604599/functions/read.html

Finally, the program waits for us to provide it with the flag, “LETMEWIN” which is then stored in the BUF and is then compared using strcmp (String Compare Function).

So, we have the answers. The takeaways are as below.

1. The FD has to be 0 else if will throw error.

2. To have 0 stored in the FD, we have to pass it 4660 (0x1234) value.

3. FD (File Descriptor) has to be 0, only then read function can read the value from the terminal i.e. the user input.

4. The user input has to be LETMEWIN in order to read the flag saved in another file.

Once provided. We can finally grab our flag.

That’s all. We are done with the challenge. I hope you like it!

--

--

Kamran Saifullah

Malware/RE/Firmware Analysis, App Sec/Off Sec, VAPT, Phishing Simulations/SE | Risk Management, IS Governance, Audits, ISO 27001 LI