Summary: binary MD5 hashes are, in fact, binary, and any given MD5 hash has a 1/16 chance of containing a given SQL metacharacter. The CTF challenge here required the calculation of a hash containing a whole 4-character injection string; this is harder, but not Hard.<p>You should know that the exact same problem applies (moreso, in fact) to encrypted strings. Developer laziness insulates most apps from raw MD5 digests (most devs use the hex digest function, which returns human readable [and safe] output). But the exact same "iterate 1 bit at a time until you hit a jackpot block" trick works with almost every application that uses AES.<p>It's not just SQL, either; I've used it to get XSS out of corrupted AES decryptions as well.<p>And, of course, the same trick works in the opposite direction. If you encrypt a string with a quoting domain (say, where the character ';' needs to be quoted '\;' to preserve an encoded tuple), attackers can pad inputs to get the quote and the metacharacter to span blocks, then use block corruption to kill the quote but not the metacharacter.<p>Have I mentioned today how you shouldn't be building crypto code? DON'T DATE ROBOTS.
In all my years of dealing with ugly and insecure PHP code, never have I seen anyone using raw md5's in PHP<p>Sounds like a fabricated situation just for the game to me, versus something trying to resemble real life situations. Not saying its not possible, but the type of coders that would make a SQL injection oversight with something like that would also not care to provide a non-default raw_output value to the function for the heck of it
I am more impressed by whoever came up with the challenge, although setting the second parameter of md5 to 'true' made it obvious what the solution to the puzzle was (nobody would ever have binary output on irl).<p>The French team came up with the solution quicker as they worked out that any '=' would work - their keyspace search was thus an order of magnitude quicker:<p><a href="http://blog.nibbles.fr/2039" rel="nofollow">http://blog.nibbles.fr/2039</a>
This might be only tangentially related, and I'm sure nearly everyone on HN knows this, but salting MD5's is probably the easiest way to significantly increase their security. By changing md5($var) to md5($var . "foo") this type of attack could be prevented, assuming that the crackers don't have access to the source code [in this challenge, they did].<p>To get an idea of what can be exposed if you don't salt, and thus use predictable hashes, have a look here: <a href="http://www.google.com/#q=inurl:c4ca4238a0b923820dcc509a6f75849b" rel="nofollow">http://www.google.com/#q=inurl:c4ca4238a0b923820dcc509a6f758...</a><p>md5(1) = c4ca4238...
PHP contains filters for a reason. They are there to protect you.<p>While this was a clever challenge, in general you should sanitize all of your input using filters.
This is all quite clever, but any wary developer makes sure to use either properly sanitized inputs, or better still, prepared SQL statements (as f.e. available through PHP's PDO method), so this trickery, no matter how clever, is really not a big issue.
I know there was already a shorter solution but<p>instead of '||'[1-9]<p>one could have searched for<p>'!=' or '<>' thus opening up the search space