SQL injection with raw MD5 hashes
cvk.posterous.com
cvk.posterous.com
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.
It's not just SQL, either; I've used it to get XSS out of corrupted AES decryptions as well.
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.
Have I mentioned today how you shouldn't be building crypto code? DON'T DATE ROBOTS.
How would you go about such a thing? My initial thought is to simply permute over the controllable bytes and see what comes out, looking for specific characters that get you what you need, e.g. a quote to break out of an HTML attribute, but I think I might be missing an easier path.
It's really not rocket science.
The interesting thing about this report is how fast you can brute-force calculate this in order to find a magic byte sequence.
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
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:
To get an idea of what can be exposed if you don't salt, and thus use predictable hashes, have a look here: http://www.google.com/#q=inurl:c4ca4238a0b923820dcc509a6f758...
md5(1) = c4ca4238...
Also concatenating "foo" to the end of /every/ password is not salting your hash. You need to have a suitably random string for it be considered salt. Also you want to have a different random string for every password in your database.
[+1 to tptacek for constantly saying don't write crypto code :-p]
While this was a clever challenge, in general you should sanitize all of your input using filters.
Input sanitisation has been solved thousands of times by people smarter than you. Do not reinvent the wheel (poorly).
You should escape output.
In this case there isn't anything wrong with the input, and you can't say that any byte of MD5 is wrong or dangerous.
It's just data that is used improperly.
Binary data in SQL queries is especially tricky, because strings may be expected to be in specific character encoding (e.g. UTF-8), so you either need to use prepared statements and pass argument explicitly as binary, or use string-safe escaping (e.g. hex).
Sorry, if your own personal experience suggests that most software is rigorous with SQL and input validation, I think I have to assert a broader and more accurate perspective on the issue. It feels statistically improbable to me that we're just missing all the "good" software.
It just rubs me the wrong way when people claim "if you do things right, you'll never run into this problem anyways". Two possible interpretations: either "do things right" is too broad to mean anything (no-true-Scotsman-style) or "do things right" involves a piece of advice like "used parameterized queries" which doesn't actually work reliably in the real world.
We have absolutely found SQL injection in Rails code before. I've also had engagements on very modern financial codebases where the developers were able to expound at length on how impossible it would be for them to have injection --- providing entirely sane design rules to back it up --- that ended up losing their entire app to pre-auth SQLI. There's always some tiny corner of the app --- a custom query builder, a hand-hacked pagination system, a sort column generator, a table selector parameter, that one stored procedure that does dynamic SQL and doesn't know what U+2032 is --- that manages to slip up.
Can you describe a case or point to example code using a parameterized query that is vulnerable to SQL injection? I've seen a stored procedure that built raw queries and pass them to sp_executesql (T-SQL) that provided a vector for SQL injection. However I am struggling to think of a case where a parameterized query could allow for SQL injection.
Simplest example: User.find_by_sql("SELECT * from users where name = ? LIMIT #{ limit }", name)
Other examples: sort order (ASC/DESC), table selection, join columns, GROUP BY argument.
If you think I'm arguing against parameterized queries: of course not. Use them. But know their limitations.
instead of '||'[1-9]
one could have searched for
'!=' or '<>' thus opening up the search space