And here I was thinking everybody knew SQL injections and that this challenge wouldn’t last an hour. And yet only one team was able to complete it before the end of the contest. o_O
In the description of the challenge, we are asked to access the admin account. So we connect to the application, register an account and login. We notice there are two pages:
1. Member list
2. Your profile
We can obviously update our firstname, lastname, phone number and description. One of the first things to test in the case of an injection is how the application reacts with quotes. In this case, everything seems OK, as they display correctly in all fields, appart from the phone number which mentions that it is not a valid number. Interesting. So what is a valid phone number for this application?
By fuzzing the field a little bit, you notice that it accepts up to 10 numbers, as well as some arithmetic operators, such as /,*,- and +. For example, if you enter your phone number as 2+2, it will show up as 4. Someone is not using the right regexp for this job! 😉
How can we exploit this? Well we imagine the request looks like something like this:
UPDATE users SET firstname='escaped(firstname)',lastname='escaped(lastname)',phone=valid(phone),userdescription='escaped(userdescription)' WHERE id = X;
All fields but the phone number are escaped correctly and the phone number must be max 10 numbers (and arithmetic operators). Well by combining the / and * operators we can create SQL comments, and we control what is found in the user description, which would allow us to end the SQL comment and enter arbitrary SQL code!
UPDATE users SET firstname='toto',lastname='toto',phone=123456/*,userdescription='toto*/ SQL CODE HERE --' WHERE id = X;
We can therefore inject arbitrary SQL code in an update statement. We know we have to access the admin account, so the flag is probably in his profile details somewhere. Maybe his name, but more probably in his description. What we can do with the injection is update our description to match the admin’s one. To do this, we can enter the following values in the phone and description fields (I won’t go into details as to how you can find the table name and columns, it is pretty straightforward guessing (the column names are the same as the form input fields) or through information_schema tables):
phone : 123456/* description : toto*/,userdescription = (select userdescription from users where id = 1)--
This will generate the following query:
UPDATE users SET firstname='toto',lastname='toto',phone=123456/*,userdescription='toto*/,userdescription = (select userdescription from users where id = 1)--' WHERE id = X;
Which if we remove the comments is :
UPDATE users SET firstname='toto',lastname='toto',phone=123456,userdescription = (select userdescription from users where id = 1)
We can now just reload our page and view the flag in our description!