Hack.lu 2013 CTF Write-Up: Robotic Superiority
Help us fight the evil robotic lieutenant Don Sim. He wants to spread robo propaganda to cover his actions on the Oktoberfest. But he needs good video footage for that. So he created an IRC bot that collects information about robots in movies. Robotic emancipation can NOT happen, you have to stop him! All we need is his private key. Our agents located the bot, here is all we know about it:
- Server:
irc://ctf.fluxfingers.net:1313
- Bot:
lib[1-5]
(load balancer)- Key:
/var/private/key.txt
- Hint: All available commands are listed with
help
. 3 connections allowed per ip.
The service allows users to store information about movies. We query lib7
to describe how it works. Basically we just:
- add a movie titled
c00kies@venice
- get its numeric id using the
search
command - add some robots to the previously entered movie
- retrieve all the information associated with the specified id.
After several tests, we identify the details
command to be vulnerable to SQL injections.
The DB appears to be MySQL. We notice that LOAD_FILE() is allowed. It looks like that reading the key file is going to be an easy job: we are so happy. Unfortunately, the bot does not print the output of the query, but only the number of rows in the result-set.
Retrieving the file contents can be easily done by standard blind SQL injection techniques like bisection. We are anyway interested in obtaining each character of the key file with a single query. To mount this attack, we must be able to generate an arbitrary number of rows in the result-set. In this way, we can perform a query that prints a number of records which is equal to the ASCII index of the character we want to obtain. For example, the following injection allows us the recover the first character of the key file:
In the code above we rely on the movie table that stores contiguous ids of the inserted movies. If the table name was not easy to guess, we could have used another method for building the row generator.
Life would have been easier with Postgres :)
So, the first character is 5
(ASCII index 53). To recover all the characters, we use the facilities provided by irssi in order to parametrize the previous query:
Once all the ASCII indices are retrieved, we can obtain the whole key by executing:
Flag: 58c63d3625b948b10a897371f0e656455a78e235db5690e2d1bbf23a1883d4ec