Web100: "A1 Galaxy"
status: partially completed
This was the first challenge in the Web series, and completion would secure us 100 points. The challenge involved finding ways to test for possible passwords in multi-level authorisation pages. With the big help from @p____h, I've managed to pass first two authorisations, and extract
The first authorisation page asked for a
password only, and the input was not sanitized in any way whatsoever. This meant we could try with the simplest of SQL injections:
" or 1=1 or " on any of the fields (or both) and got out the username
admin1 when presented with the 2nd level authorisation form:
But the authorisation process was still able to determine that we cheated, so we'll need to actually extract the password, to be able to continue to level 3 authorisation. The
robots.txt file published at the web root gave a few hints:
And the /forgot_username_and_password.txt location let us know the length of the password:
So the password length is 22 characters long. If we had to brute-force for all the possible values in the character space of 52 possible
[a..Z] values (educated guess, but it could have been more than that), that would be 5222 values, and clearly too many to test on. But, since the input on level 1 wasn't sanitized at all, this wasn't too difficult and meant we could test for existence of a single character at a certain password position using
substr SQLite function (we've determined what database engine is running the backend based on commands it was accepting). So we could simply iterate through all 22 positions and test for these
(52/2)+1 or 27 values, as it could be further optimized to match lowercase values only, and later determine with a single injection, if the character tested was upper or lowercase. This would look something like this:
" or (1=1 and lower(substr(password,1,1)) == "c") or ".
If the login form would let us pass (and report an error it was hacked), that means we've determined the character for the
n-th position, leaving us only at most 27*22 values to try on (or 594 tests, which is obviously a lot better than 5222).
The first password was successfully extracted and turned out to be:
The second password (level 2 authorisation) was somewhat easier. While the input was sanitized, it was rather poorly so, and let us determine the string matching in its internal SQL query was based on the
LIKE operator. This was again determined by @p____h. I've run a script to iterate through all possible values in the 62-letter address space (
[0..9,a..Z]), using SQL injections ending the sought after password with
% (matches any value that starts with previous characters when
LIKE operator is used), for example:
The second password turned out to be really short:
But, we were only left with roughly 15 minutes to extract level 3 password, and no idea how to test against possible values yet. I've determined it must be a digits only password, and that it's most likely 12 digits long. This was due to the level 3 auth producing different error ("level 3 password mismatch", instead of "following errors occurred: wrong level 3 password 1, wrong level 3 password 2") when entering
0 or a non-integer value for these two input fields for password 3 (indicating the input matching defaults to
0 where type conversion fails), and when entering an integer value longer than 12 digits. In fact, I was able to narrow this down even further by establishing the value must be smaller than
444444444444 (blind test), but is bigger than
100000000000. This would still leave us with too many possible values to try and the time run out.
So the login info successfully extracted was:
Still, for having roughly 2 times half an hour of spare time (Global economic crisis weekends FTW! - shuffle letters to FTW to get my intended meaning), and @p____h in the meantime working on other challenges, I think we did fairly well. We'll try better next time. ;)