Discussion:
[john-users] Cracking MD5 with long, known prefix
Mark E. Haase
2017-12-14 15:39:10 UTC
Permalink
Hey all,

I have a cookie created by the Code Igniter web framework[1] that looks
like this (wrapped for readability):

a:4:{s:10:"session_id";s:32:"8a70dfc8e6433b28ff7cf138b6d1d2
a5";s:10:"ip_addr
ess";s:12:"XX.XXX.XX.20";s:10:"user_agent";s:120:"Mozilla/5.0
(Macintosh; In
tel Mac OS X 10_13_1) AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/62.0.320
2.94 Safari/537.36";s:13:"last_activity";i:1512923530;}
a680075dd6b96d4f44beb
9a9731ed722

The cookie contains a serialized PHP object with an MD5 hash appended to
it. The hash is computed as follows:

$hash = md5($obj . $key)

Where `$obj` is the serialized object and `$key` is a secret. This hash is
verified before unserializing the object. I want to try cracking `$key`,
but I am not sure if this is even possible with John The Ripper. I tried
both mask attack and hybrid mask. The former doesn't produce an error but
silently fails to recover the key. The latter produces this error about
exceeding the maximum length for MD5 (wrapped for readability):

$ john --mask='a:4:{s:10:"session_id";s:32:"
8a70dfc8e6433b28ff7cf138b6d1d2a5
";s:10:"ip_address";s:12:"XX.XXX.XX.20";s:10:"user_agent";
s:120:"Mozilla/5.0
(Macintosh; Intel Mac OS X 10_13_1) AppleWebKit/537.36 (KHTML, like
Gecko) C
hrome/62.0.3202.94 Safari/537.36";s:13:"last_
activity";i:1512923530;}?w'
-w=/usr/share/dict/rockyou.txt --max-length=191 --format=Raw-MD5 hashes
Can't set max length larger than 55 for Raw-MD5 format

My research indicates that 55 is a hard limit for MD5 that cannot be
changed at runtime, and that this limit was chosen for performance reasons.
Is it possible to compile John with a long limit (expecting a major drop in
performance) or is this simply not possible at all?

Cheers,
Mark


1. https://codeigniter.com/
Solar Designer
2017-12-14 15:50:08 UTC
Permalink
Post by Mark E. Haase
Can't set max length larger than 55 for Raw-MD5 format
My research indicates that 55 is a hard limit for MD5 that cannot be
changed at runtime, and that this limit was chosen for performance reasons.
Yes. But with current bleeding-jumbo you can get up to 110 with
--format=dynamic='md5($p)'. Perhaps we should document this somewhere.

I'm afraid there's no easy way to go beyond 110 with our current code.

Apparently, latest hashcat can go up to 256, so you may try that.

Jim, since in this case the prefix is constant, can it possibly be
provided as such in the dynamic format specification (I guess yes),
and would that possibly not be counted against the 110 characters
limit (I guess no)?

Alexander
jfoug
2017-12-14 17:28:34 UTC
Permalink
Post by Solar Designer
Post by Mark E. Haase
Can't set max length larger than 55 for Raw-MD5 format
My research indicates that 55 is a hard limit for MD5 that cannot be
changed at runtime, and that this limit was chosen for performance reasons.
Yes. But with current bleeding-jumbo you can get up to 110 with
--format=dynamic='md5($p)'. Perhaps we should document this somewhere.
I'm afraid there's no easy way to go beyond 110 with our current code.
Apparently, latest hashcat can go up to 256, so you may try that.
Jim, since in this case the prefix is constant, can it possibly be
provided as such in the dynamic format specification (I guess yes),
and would that possibly not be counted against the 110 characters
limit (I guess no)?
Mark,

I think you are viewing this incorrectly. What you have is a salted
hash.  You should be searching ONLY for the password part of the hash,
not the salt.

What you have is this:

```
md5($s.$p)
```

In your case, $s is the salt, and it is the serialized php object.

NOW, there will likely be severe limitations to this search, in that the
serialized object is probably going to be large (> 256 bytes), so this
would make usage in current john pretty hard to do for all items.  BUT
it could be made to work for some of these serialized objects that are a
little shorter.

Can you post any examples (along with the password that cracks them) for
testing?
Mark E. Haase
2017-12-29 19:47:55 UTC
Permalink
At Jim's suggestion, I experimented with treating the prefix as a salt
instead of a mask. Here is an example cookie that is "signed" with the key
"CDEF".

$ fold -w 70 cookie
a:5:{s:10:"session_id";s:32:"fb4344763818ee3b3db81a939e08c1f0";s:10:"i
p_address";s:12:"XX.XXX.XX.20";s:10:"user_agent";s:0:"";s:13:"last_act
ivity";i:1514573995;s:9:"user_data";s:0:"";}167400e41d785fab9dcdcf10eb
e7a83a

This cookie is 184 characters long (excluding the hash appended to the
end), which exceeds the Raw-MD5 maximum mask length (55 bytes) as well as
the dynamic format maximum length (Solar Designer says its 110 bytes). But
could it work if I treated it like a salt instead of a mask?

$ fold -w 70 hashes
cookie:$dynamic_1017$167400e41d785fab9dcdcf10ebe7a83a$HEX$613a353a7b73
3a31303a2273657373696f6e5f6964223b733a33323a22666234333434373633383138
6565336233646238316139333965303863316630223b733a31303a2269705f61646472
657373223b733a31323a2258582e5858582e58582e3230223b733a31303a2275736572
5f6167656e74223b733a303a22223b733a31333a226c6173745f616374697669747922
3b693a313531343537333939353b733a393a22757365725f64617461223b733a303a22
223b7d

The format md5($s.$p) is known as dynamic_4, but it doesn't allow a salt
that is this long. I noticed that there is another similar format called
"dynamic_1017: md5($s.$p) (long salt)", so I switched to that format. Also
note that my "salt" contains colons in it, so I hex encoded it.

Here's my John session:

$ john --pot=my.pot --mask='?u?u?u?u' --format=dynamic_1017 hashes
Using default input encoding: UTF-8
Loaded 1 password hash (dynamic_1017 [md5($s.$p) (long salt) 128/128
AVX 4x3])
Warning: no OpenMP support for this hash type, consider --fork=8
Press 'q' or Ctrl-C to abort, almost any other key for status
CDEF (cookie)
1g 0:00:00:00 DONE (2017-12-29 14:34) 8.333g/s 3094Kp/s 3094Kc/s
3094KC/s CJAF..QROF
Use the "--show" option to display all of the cracked passwords reliably
Session completed

Wow, it worked! Thanks Jim and Solar Designer for the advice. I've omitted
a lot of details here for the sake of brevity, but I think I might write up
a blog post if anybody is interested.

Cheers,
Mark
Post by Solar Designer
Post by Mark E. Haase
Can't set max length larger than 55 for Raw-MD5 format
My research indicates that 55 is a hard limit for MD5 that cannot be
changed at runtime, and that this limit was chosen for performance reasons.
Yes. But with current bleeding-jumbo you can get up to 110 with
--format=dynamic='md5($p)'. Perhaps we should document this somewhere.
I'm afraid there's no easy way to go beyond 110 with our current code.
Apparently, latest hashcat can go up to 256, so you may try that.
Jim, since in this case the prefix is constant, can it possibly be
provided as such in the dynamic format specification (I guess yes),
and would that possibly not be counted against the 110 characters
limit (I guess no)?
Mark,
I think you are viewing this incorrectly. What you have is a salted hash.
You should be searching ONLY for the password part of the hash, not the
salt.
```
md5($s.$p)
```
In your case, $s is the salt, and it is the serialized php object.
NOW, there will likely be severe limitations to this search, in that the
serialized object is probably going to be large (> 256 bytes), so this
would make usage in current john pretty hard to do for all items. BUT it
could be made to work for some of these serialized objects that are a
little shorter.
Can you post any examples (along with the password that cracks them) for
testing?
Loading...