Mind Reader Challenge — Google CTF
This is writeup for Google CTF challenge: “Mind Reader”.
When we first visit https://mindreader.web.ctfcompetition.com/ we are greeted with the following page:
This at first reminded me of the challenge that I did when doing Easy CTF 2017. So for the first attempt to understand this, I put /etc/passwd as my string. As expected, this application was vulnerable to Local File Inclusion. This way you could read the internal files. For /etc/passwd following response was shown:
To make sure this was not any false positive or something that could act as Red herring, I tested with couple other internal files. After I confirmed that this vulnerability existed the next goal was finding the flag.
Finding vulnerability in this was not as hard as finding the flag. While discussing with my colleague, Abhi Kafle, we noticed that a possible hint was usually the title. Sometimes title could act as a giveaway for the challenge. Considering that, we focused on the idea that the title read mind reader. Mind = memory so now we had to find some files relating to memory. This is where we started to dump out different file names that we could look for.
One of them was finding the /proc file and seeing if we can read process id or anything related to that. This did not work and the application kept throwing 403 error. Another wall that we hit was that we did not know how this app was made. Knowing what this app was made of (source code) could help us to find the flag for the challenge.
For the file type, my wild guess at first was PHP because it is easy to make vulnerable app in php with commands like file_get_contents() or system(). Anyways, looking for “/var/www/html/index.php” or “/var/www/index.php” returned 404 error. Another idea that came in mind was that this could potentially be a python file. This was a wild guess because some apps like YouTube by Google are written in python. While discussing with another colleague, we found that there was main.py that existed.
Following was the source code of the application:
Interestingly, turns out the 403 was due to the regex code “re.search()” in line 24. So we definitely know now that we need someway to read proc file. Another thing that was weird in the application was the code in line 6: assert = os.environ[‘FLAG’]. Because it had the Flag parameter it definitely caught my attention. Environ is an environment file and as I thought, it had to do with /proc because you can read process id information from that. Looking up /proc/environ or /proc/<pid>/environ gave quite some information needed. However, none of these info could directly work because proc was not allowed. While looking for equivalent information relating to proc, I noticed a stackexchange answer that stated the following:
So basically if we could get /dev/fd it could also have relation to /proc/self/fd because they are linked. Well, /dev/fd did not work because it is a directory. But because this is symlinked could we do /dev/fd/../environ?
Why are we doing /dev/fd/../environ?
I actually took some time to find about this before I executed the command. We know that /dev/fd = /proc/self/fd but /dev/fd is a directory with lists of process. Interesting.
When I browsed to /proc/self/ in my own linux os I noticed that it had an environ file which is what we exactly needed. So basically when we type /dev/fd/../environ, it is sending a command equivalent to /proc/self/fd/../environ which prints the environ file at /proc/self/environ. When this file is printed, we get the flag:
The flag is: CTF{ee02d9243ed6dfcf83b8d520af8502e1}