Take the 2-minute tour ×
Information Security Stack Exchange is a question and answer site for Information security professionals. It's 100% free, no registration required.

How can I create a password, which when directly hashed (without any salt) with md5 will return a string containing the 8 characters "SALT ME!". The hope is that a naive developer browsing through his user database will see the "hash", realize the insecurity of his application, and eventually make the world a better place for everyone.

Md5 outputs 128 bits, which is 16 bytes. If I had a 16-byte message, getting the original plaintext password would be equivalent to a pre-image, which to my knowledge is practically impossible. However, I'm only looking for 8 specific bytes in my hash.

Is obtaining such a password feasible in day-timeframes on a typical computer? If so, how can I compute such a password?

share|improve this question
49  
My immediate thought is that if you're using MD5 as your password hashing algorithm, whether a salt is being used (or not) is not your biggest concern. –  Xander Apr 22 at 16:35
19  
-1 because the stated purpose of this is not only absurd, but won't even work. Also does not belong to on this site: The question is essentially asking about calculating specific hashes, and is better suited to StackOverflow or SuperUser. –  Superbest Apr 22 at 19:24
31  
or CodeGolf... –  Mooing Duck Apr 22 at 19:28
11  
Almost no admin goes thorugh the password database and reads all of them. Or the database should have been compromised and your "Salt me" should stand out from the rest ... All given examples below rely on Base64-representation of the hashes, while most MD5-hashes are represented as hexidecimals –  GroundZero Apr 22 at 21:02
8  
Total red herring. Salting won't save your backside if you don't mitigate against offline brute-force searches. Use scrypt or bcrypt or something similar, no ifs or buts. –  Chris Jester-Young Apr 22 at 23:02

3 Answers 3

up vote 218 down vote accepted

The output of MD5 is binary: a sequence of 128 bits, commonly encoded as 16 bytes (technically, 16 octets, but let's use the common convention of bytes being octets).

Humans don't read bits or bytes. They read characters. There are numerous code pages which tell how to encode characters as bytes, and, similarly, to decode bytes into characters. For almost all of them (because of ASCII), the low-value bytes (0 to 31) are "control characters", hence not really representable as characters. So nobody really reads MD5 output directly. If someone is "reading" the hash values, then these values are most probably encoded into characters using one of the few common conventions for that. The two most prevalent conventions are hexadecimal and Base64.

With hexadecimal, there are only digits, and letters 'a' to 'f' (traditionally lowercase for hash values). You won't get "SALT ME!" in an hexadecimal output...

With Base64, encoding uses all 26 unaccentuated latin letters (both lowercase and uppercase), digits, and the '+' and '/' signs. You could thus hope for "SaltMe" or "SALTME". Now that is doable, because each character in Base64 encodes 6 bits, so a 6-letter output corresponds to 36 bits only. Looking for a password which yields either "SaltMe" or "SALTME" will be done in (on average) 235 tries, i.e. within a few minutes or hours with some decently optimized code.

Note, though, that someone who actually spends some time to read Base64-encoded hash values probably has some, let's say, "social issues", and as such might not react the way you hope.

And it is done: When hashing with MD5 then Base64-encoding the result:

  • infjfieq yields: SALTMEnBrODYbFY0c/tf+Q==
  • lakvqagi yields: SaltMe+neeRdUB6h99kOFQ==
share|improve this answer
198  
Nothing relaxes me after a long day at work like having a glass of wine and reading through some base64 encoded hash values. –  Abe Miessler Apr 22 at 17:01
16  
I'd have to up vote this, even if you didn't find two inputs that yield SALTME as the first 6 characters; doing that merits more than a +1, but alas, that's all I can give. Fantastic answer friend! –  Michael Perrenoud Apr 22 at 18:03
21  
NoMD5 is only five letters; we can go to six and get NoMD5+, which looks better. And, indeed, pmcrsihh yields NoMD5+pyhpe6Xxa3x93iGQ==. –  Tom Leek Apr 22 at 18:45
15  
Brutally... I took an MD5 implementation from here, then went through many 8-letter passwords until the proper output was obtained. About 2^23 tries per second and per core on my 3.1 GHz server (I estimate that I could do 2^24 with some SSE2-aware code -- I had done that at one time for SHA-1). –  Tom Leek Apr 22 at 19:13
21  
When I saw SALTMEnBrODYbFY0c/tf+Q== The first thing that came to mind was.... Don't Salt Me Bro! LOL –  mezoid Apr 22 at 23:35

Purely in theory...

There are rainbow table sets with pre-computed hashes. You could search it for a hash value that contains the suitable byte values (EDIT: would require some brute-forcing of pre-generating full hashes and probing making it much harder to do - see bonsaiviking's comment to the answer), if one such exists (e.g. one that contains 0xBADBAD). If one exists, then from the rainbow table itself you can get back the plaintext from which that hash was derived (and if you use that password, then it is, by definition, is insecure as anyone who gets the database can reverse it, and so not advised).

In practice, however....

There are many assumptions in this approach.

  • In reasonable size orgs, developers typically do not have access to production database except for perhaps individual troubleshooting cases.
  • You're assuming that MD5 is stored/displayed in some human-readable format; yet it is just a byte array of 16 bytes, and would really depend on software that developer/IT-person would be using to visualize it. In Visual Studio, for example, debugger would display byte array typically by its number value, e.g. 87,45,34,67,...
  • You're assuming that unsalted MD5 is being used, but could be some other hashing function, for which hash would, obviously, be different and thus fail your requirement.
  • And as others already suggested, you don't know how it is stored as some additional transformations may've been applied to it (like Base64, for example) that would make it look different.

But primarily the biggest assumption is that someone is looking through the database of thousands/tenthousands/millions/tenmillions/etc of users and would spot the odd value out of a bunch of hashes, and even then out of a part of a hash.

share|improve this answer
6  
Rainbow tables don't store all the hashes, so you can't just "search through them". They are a specific compression format for finding plaintext for particular whole input hashes, so you'd have to keep generating "satisfactory" hashes until you got one with a "real" plaintext. –  bonsaiviking Apr 22 at 17:15
    
@bonsaiviking You're right - I didn't even realize that. Makes that a whole lot harder... –  LB2 Apr 22 at 17:32
    
"developers typically do not have access to production database except for perhaps individual troubleshooting cases" I think this is the only sane answer to the question. I would think it highly unlikely that obtaining the end-result will be seen and even then it will probably not change someones mind. –  Niels Bom Apr 24 at 13:43
1  
"Pass2112127" hashes to "badbad3aad02eeb05be660c5bb30efe5". –  tobyink Apr 24 at 22:13
1  
"Pwd9383247" hashes to "bad7ca3eb9307233f790a9d4a4a0bbad" which has "bad" at the beginning and end. –  tobyink Apr 24 at 22:23

8 bytes is 64 bit, which is beyond bruteforce. I don't know of any preimage attacks on md5, so you're probably out of luck.

Also, some websites escape or restrict your charset as an (ineffective) measure against SQLI

share|improve this answer
1  
Since it is beyond brute force, do you use 64-bit hashes per chance? –  Kevin Li Apr 22 at 17:21
29  
It's beyond brute force, except for the answer above in which it was brute forced. –  corsiKa Apr 22 at 19:18
8  
@corsiKa The accepted answer brute-forced "SaltMe" or "SALTME", not the requested "SALT ME!" The difference between 6 and 8 characters is extremely significant here. –  Mike Scott Apr 22 at 19:38
4  
He was able to do it in under an hour on a single machine, including setting up the app. Adding a character would make it take around 2 days, which is very reasonable. Considering there weren't many optimizations made (answerer estimated he could make it roughly 10x faster with good optimizations) and that someone with the setup to just throw something like that together probably has a couple machines to parallelize it on, it appears a password could be brute forced in a week or two. Certainly feasible for something OP only needs once. –  corsiKa Apr 22 at 19:51
9  
Except he bruteforced 6 6-bit chars, 2^36, which is far less than even "SALTME" in 8-bit which would be 2^48 –  miniBill Apr 23 at 6:30

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.