Challenge #2: Magic Hashes!
This is a demo module, sign up for the course here!
Magic Hashes are a fun way to exploit PHP's string type juggling even further.
PHP treats any strings which start with 0e
followed by all numeric digits as scientific notation floats.
For example, if you have a string like 0e123
, PHP will treat it as the float 0 * 10^123
, which is 0
.
This behaviour can be exploited by finding a string which, when hashed with something like MD5, produces a string value
which follows the same pattern. PHP will then treat the hashed value as 0.0
, which also equates to false
.
and if the application is using loose comparisons, the vulnerable may be able to bypass authorisation checks.
You can see some examples of Magic Hashes here.
Although very rare, if an application is using loose comparisons to compare password hashes,
and a user provides a password that produces a vulnerable hash (i.e. something 0e[0-9]*
),
then an attacker may be able to log in by simply providing a value like 0
as the password!
That said, this is incredibly unlikely to happen in practice, but it's not impossible...
A more realistic scenario is where a hash is being used as a signature to verify the integrity of a message, which is compared with a loose comparison, and the attacker can control both raw message and the hash (signature). The attacker may then be able to craft a message which will produce a vulnerable hash, allowing them to bypass the signature check.
Your Challenge
Abuse Magic Hashes to bypass the URL signature check and gain access to the protected resource for the admin user.
Note, you don't need to do any major brute-forcing or time-consuming calculations to solve this challenge. A little bit of guess-work and some research should be enough to find the answer fairly quickly, and remember, there is no shame in checking the hints.
Objectives
- Modify the URL to access the protected admin user page.
- Provide a signature which abuses Magic Hashes to type juggle the signature check.
- Identify the correct expiry date to trigger type juggling.
Hint #1
Have you done your research?
Hint #2
Alright, there are a few components you need to manipulate here, luckily two of them are trivial:
username
: You're trying to access theadmin
user.expiry
: This type juggling relies on0 == 0e[0-9]*
.
Once you've set those two URL parameters, it's just a matter of finding the correct expiry timestamp.
To get you started, I can tell you the expiry timestamp you're looking for is a short increment from one you've got already.
Hint #3
The signature is generated using this code:
hash_hmac("md5", "{$username}|{$expiry}", "")
Knowing that, and the fact the expiry is after the one we've been given, we can figure out the correct expiry timestamp using something like this:
for ($i = 1539805970; $i <= 1539806000; $i++) {
$hash = hash_hmac("md5", "admin|{$i}", "");
if ($hash == 0) {
return "{$i} => {$hash}";
}
}
Solution
The username you need is admin
, and the signature needs to be 0
to trigger
the required type juggling. With this, we can brute-force the calculations (from Hint #3) to find the expiry
timestamp of 1539805986
gives us the hash 0e772967136366835494939987377058
.
Combing all three of these together gives us this URL:
https://demo.practicallaravelsecurity.dev/type-juggling/two?expiry=1539805986&username=admin&signature=0
For this challenge, I used the example code from this Example Exploit, which makes a really nice demo. Also, if you did your research, it would've given you all the values you needed, without needing to calculate anything.