openwall / john

John the Ripper jumbo - advanced offline password cracker, which supports hundreds of hash and cipher types, and runs on many operating systems, CPUs, GPUs, and even some FPGAs
https://www.openwall.com/john/
Other
10.2k stars 2.09k forks source link

Support binary input for HMAC formats #5081

Open ndmalc opened 2 years ago

ndmalc commented 2 years ago

Hello,

My goal is to crack an hmac-sha1 hash retrieved from a Tapestry t:formdata field. t:formdata is a java serialized class protected by an hmac-sha1 with the secret stored at the server side.

The format of a Tapestry t:formdata is as follow: base64(hmac-sha1(secret, gzip(serialized javaclass))):base64(gzip(serialized javaclass))

My problem is that as per documentation, the current hmac-sha1 format uses the following hash entry format: <string text>#<hmac-sha1 hash>

This is not working because Tapestry t:formdata uses gzip binary data as data for the hmac-sha1 algorithm. This data format does not seem to be supported by john based on my tests.

How to reproduce?

Tapestry t:formdata value Oh4hrAkZdvJoOhlWAOrZdOsQZ8M=:H4sIAAAAAAAAAOWXT2sUMRiH4+ra6oLUgooXsbLFP+AM7W4v60HasraWtRQW9SSSybyzjWaSNEm7u4KePOiX8AtUPXoUoQfx4lcQP4AXFS96MNmtqIg6GWkP42mGYZ75vTy/BCaP36FydxKdwnGsQOtwXgE20IgAc4ipSYRKA3cjFNIKNYTqBFhisgqBwRK0Uf2ZgAgFjEb2mkrBgRsdzFm+OcCqKwokVnB9bLmy2Xt2vIRQT3bPodN/TwyYENLFBlljWxaoTr+XydmFo5sXdz6q9uLM/cXaxydoGFVHUxmipBISlOl/17qQNXRlG91W2wazLpt8gyrBU/vC0uHS2ptaeL6E9rTQ6Lccg8Zbt/AGDhnmnbBtFOWdCz1p0IFVwYWiCSXdCXTCxYU/BswxQW7rhgYGxLgxZ/44ZoQ1BLORfYiJuUSBxcP5Jq9uVd4eefllMFSFCG6UYMs4hTV0D43kmWPWdw77NWJLaa9HKdWaCr71NK4nnx69/rfaLuesbZ7Zz/9UXHrt+d2Ti8c+7/yKrefeHK6uck5Xjt1vi06o0sZ1362iid8VbaBnEtfbkDvozznsUL5RHTrmq2V8lz2OMpxHoydWdIsjdqcAmCk/iX7Uf+JwOpfDjFTRHe4j1PT9BHogRbdX1sYSfvp8mKL723uHSj972YmiuytDiinzXHseTOH9Sfvn77t3PZjd95f5JN3McZL+9dxw88rSw1c3PjwY/Mx/Ba2k0FLLDwAA Secret key moreofyoulessofme

I wrote a python script to transform the t:formdata value to 'john format'

import base64
input_filename = "tapestry_hash.txt"
output_filename = "tapestry_hash_john.txt"
with open(input_filename) as f:
    cred = f.read().strip()

cred = cred.split(":")
with open(output_filename, "wb") as f:
    f.write(base64.b64decode(cred[1]))
    f.write(":".encode("utf-8"))
    f.write(base64.b64decode(cred[0]).hex().encode("utf-8"))

Here are the john test results:

#./john --format=hmac-sha1 tapestry_hash.txt 
Using default input encoding: UTF-8
No password hashes loaded (see FAQ)

Environment info

I tried it in the current latest version based on a compilation performed as of today.

Conclusion

Based on known documentation, I am not surprised that binary input does not work. Would there be a possibility to add binary input support for hamac-sha1 or the possibility to specify an encoded input format such as hexadecimal or base64? Proposed solutions are just suggestions but a solution in the end would be very welcomed.

Also, this is not useful form my use case but if a fix is made, maybe would it make sense to apply a similar one to all hmac-sha* formats?

Thanks.

magnumripper commented 2 years ago

Us supporting $HEX[cafe] format would be a fine way to fix this. Most other solutions would be format specific (well even that one would, but at least it would use shared code).

AlekseyCherepanov commented 2 years ago

If there are incompatible changes to hmac* formats, please also consider changing syntax to be $tag$digest$text or $tag$digest#text. Because arbitrary text at the beginning of ciphertext is a problem: it is not possible to tell format just checking tag at the beginning, for instance mscash can be loaded as hmac-md5. (Also leet format has such problem.)