Note: I started completing pwnable.kr problems when I had little/no knowledge about binary exploitation, and thus learned how to complete each task as it was presented. These writeups are for the under experienced hackers that are still learning how to go about dealing with a hacky problem you don’t understand. I hope you get something from the journey I took to become a better hacker in these problems. The minimum required knowledge for these writeups is basic terminal commands like ls, cd, and rm. Lets get started.
We are first introduced to this problem with a SECURED SHELL and a problem hint. Hint: “Mommy! what is a file descriptor in Linux?”
Using simple logic, it is easy to tell we need to go to this SSH and we need to do something there. We can connect to the SSH by simply copying the command into our terminal as using the password.
Once here we can see we have three files, one being source code, one assumed to be the program the source code is for, and the last being our flag–the thing we want. We can use ls -l to see our file PERMISSIONS.
Sadly, we don’t have access to the flag, so we can’t just ‘cat’ the flag to see what’s inside. Hacker instincts tell me, we are going to somehow use the fd program to see whats inside the flag. Before looking at the source code of a program I like to just run the program as see what happens
After two attempts, its clear that this program expects something to come in with it in the command
line. This thing is a number that comes in through ARGV. This program also gives us another hit that we need to learn about linux input/output system for files. What the hell does that mean? I’ll come back to it…
Seeing that running it had no affect, its time to jump in and see what the source code looks like. We can do that with the ‘cat’ command.
Now its starting getting a little harder. There are many things we don’t understand in this code. Most of them are method calls that we don’t know. Let’s find out what they mean. From our earlier find, we know that argv is used with argc. argc is the ARGument Count. So really, the program is checking if we input less than 2 commandments. The first is always the name of the program, in this case its ‘fd’, and the second is going to be that cheeky number we pass in.
Next it takes whatever cheeky number we put in and does some strange method call on it. Luckily, we have open documentation to all the methods in this program through the terminal ‘man’ command. So we can run ‘man’ on all the commands we don’t understand, which in my case was atoi(),read(), and strcmp().
After some quick skimming atoi() stands for ASCII to Integer–it takes a string and coverts it to a number based on the ASCII chart which can be found with the command ASCII. strcmp() simply compares a buffer and a value and returns 0 if they are equal. The read() command takes in three things: a file descriptor (sounds familiar), a buffer (somewhere to store date, like a variable), and how much data to read. It’s time to look back at out original hint about file descriptors. I’m assuming its going to be important for this challenge, so lets really understand it.
Going to the wiki article File Descriptor we can see that the file descriptor is going to be a number that describes how we get input.
It’s using things called stdin(Standard In), stdout(Standard Out), and stderr(Standard Error). Google searching these things, and really condensing the info we get, we know that these are just ways a program interacts with the machine. It gets input from the user through stdin, and it gives output in stdout. stdin = 0, stdout =1, and stderr = 2.
With this new found knowledge lets look at this source one more time.
Notice the source code takes in a number, that is subtracted by hex 1234, then put in the variable fd and used in the read command. From what we know about the read command, the first argument should be the file descriptor and determine how the read gets input. WAIT A SECOND! That means if we can somehow get the read() to read from stdin, we would be type in the text ‘LETMEWIN’ that is tested at the end of the program.
The strcmp() will read out 0, and we will have the flag displayed for us. Only one last step, convert the hex into decimal. We can do this by opening python in our terminal by typing ‘python’ and then typing ‘0x1234’ which should output the result 4660.
Last step, run the program with input 4660, by directly passing it into the program and then entering ‘LETMEWIN’ to pass the final check.
Flag: ‘mommy! I think I know what a file descriptor is!!’