English [Internetwache CTF 2016] [Web 50 – Mess Of Hash] Write Up

Description

Students have developed a new admin login technique. I doubt that it’s secure, but the hash isn’t crackable. I don’t know where the problem is…

Attachment: web50.zip

Service: https://mess-of-hash.ctf.internetwache.org/

Resolution

The content of the  zip file was containing only a piece of script, as shown below:


<php

$admin_user = "pr0_adm1n";
$admin_pw = clean_hash("0e408306536730731920197920342119");

function clean_hash($hash) {
 return preg_replace("/[^0-9a-f]/","",$hash);
}

function myhash($str) {
 return clean_hash(md5(md5($str) . "SALT"));
}

At first sight, the is no vulnerability in here. The hash is cleaned (actually, that’s not really useful, as the function is used only in myshash() which returns a hash, but… whatever :)) and the myhash() function double hash the password. A classic bufferoverflow is not an option.
But, hey, it’s a CTF, there must be a flaw 😉

A very cool thing with PHP is that you can do things quickly, as the language is very high level. For example, PHP can auto cast int in string ad things like that.
A very cool thing with PHP is that you as do things badly, as the langugae is very hish level. For example, PHP can misunderstand very easily variable casting 😉

What we are talking here is type juggling. As an example, the string “0” is equal to false. Internally, the string is casted as the int 0. And zero is also the boolean for false. It makes sense… in a way.
Ok, now, back to business. Did you noticed that the hash is composed of “0e” at the beginning, and only numbers after that? Did you see it coming? PHP can parse our string as a scientific notation number 😉
It means that when the password will be checked, it will be parsed by PHP as a number, and not a string. If we send a password which hash also looks like a scientific notation, maybe PHP will do the comparison “if <int> == <int>”!

So, we just need to find a hash which begin with ‘”0e” and that has only numbers after. A quick script will do the trick :


import hashlib

i = 0
while (1):
calc = hashlib.md5(str(hashlib.md5(str(i)).hexdigest()+'SALT')).hexdigest()
if calc[0:2] == '0e' and calc[2:].isdigit():
print 'FOUND IT '+str(i)
break
i=i+1

After some time, the script was proudly showing “FOUND IT 62778807”.
Now time to see if we’re correct! After entering our int in the login form, we loaded the page, and…

This is a real mess of hash!

Flag was IW{T4K3_C4REANDC0MP4R3}

For more information, you can check these links :

Enjoy

The lsd

Leave a Reply

Your email address will not be published. Required fields are marked *