This is a writeup for the public CTF hosted by NotSoSecure for the celebration of SQLi Labs’s launch. It started 16:00 BST on Friday 25th October and ended 21:00 BST on Sunday 27th October. Three PizzaEaters’ members participated.
In the mail containing the instructions to start the CTF, the following URL was supplied:
This page requires an username and password, but there was no mention of it in the email.
We started with the classic attempt of injecting 1' or '1'='1
string for
both username and password. Having no luck, we started looking around a bit
closer.
We submitted the form empty, and noticed an HTTP 302 redirect with the following information:
We noticed the hex encoding and we decoded the string with this simple Python script:
The script basically takes those numbers 2 at a time and convert them to their respective ascii char. The output for it was ‘secret_register.html’.
Great! We now have a different page name to play with. Accessing it we were greeted with a registration form that we filled with some dummy values just to test.
After submitting our registration, we tried to login with our newly created user. At this point we found ourselves in a page with a crying figure lamenting that we were not Admin. :(
Looking at the requests that were made during the login phase, we noticed the following cookie being set:
This looks a lot like a base64 encoded value.
So, the page is setting a cookie containing the user’s email. And that is it, it seems.
At this point, nothing too interesting. Perhaps it was time to try the classic SQL Injection approach in the registration form, as doing it in the login form resulted on nothing.
We tried creating an user called !!' or name = 'admin
just to see what
would happen (after all, the name of the field in the form was ‘name’
so why not give it a shot?). We logged in with our new user and to our
surprise the following cookie was set:
Decoding that
Perfect! We just found the flaw. Now we need to figure out the password column
and the table name to retrieve the password of the admin
user. We assumed
the column would be called password
so we now only had to discover the table
name. We looked up for tables with password
-named columns with the following
SQL:
Turns out it was called users
. How predictable! Why didn’t we try users
before typing all that SQL?
Now we only needed to know the user’s password. So we injected the following:
Which gave us sqlilabRocKs!!
as the admin
password.
Logging in with our newly found credentials we get:
The first flag revealed that the server had a secret.txt
file, which we
tried to read using load_file()
in a SQLi only to find that we were unable to
do so. How foolish of us! Of course it wouldn’t be that easy.
After we put some thought on it, sigsegv (a team member) suggested trying to read
/etc/passwd
. We did it by injecting this:
Guess what we found? An user which had his password field set:
We ssh’d into ctf.notsosecure.com
using that username and password and it
worked. Now we only had to read /secret.txt
:
Oh snap! Why can’t we read it? ls -l
revealed it could only be read by
www-data
:
We couldn’t use sudo
or su
, we didn’t find any exploitable suid executable
(we didn’t search thoroughly actually) and we could not put a script into
/var/www
to dump the contents of the file.
“Damn”, we thought, “how the hell are we going to read that file?”.
Looking for more options, we went to apache’s configuration directory and then into it’s mods-enabled
folder:
“Mua-ha-ha!” Now everything seemed clear! Mod userdir lets us create a directory at the users home and access it via the webserver.
We then created the directory ~/public_html
and put a little PHP script to dump the
secret.txt
file:
We opened the URL http://ctf.notsosecure.com/~temp123/
and there it was, the flag.
We had finally reached the goal of our quest. It was a pleasant challenge!
Thanks to SQLi Labs and NotSoSecure for all the fun.
See you next time!