How To: Use Hash-Identifier to Determine Hash Types for Password Cracking

Use Hash-Identifier to Determine Hash Types for Password Cracking

Hashes are commonly used to store sensitive information like credentials to avoid storing them in plaintext. With tools like Hashcat, it's possible to crack these hashes, but only if we know the algorithm used to generate the hash. Using a tool called hash-identifier, we can easily fingerprint any hashes to discover the right Hashcat mode to use to retrieve a password.

Aside from cracking hashes, hash-identifier is also helpful for identifying which hashing algorithm is being used to provide a checksum value for a download. And it can be used to determine what program a hashed file or value may belong to, such as an SQL database or another vendor-specific format.

What Is a Hash & How Do We Crack It?

When passwords are lifted from a database or computer, they're usually stored as hashes so that hackers can't read any passwords in plaintext. A hashing function turns the readable passwords into jumbled up messes of letters and numbers that should not be able to be reverse-engineered.

But two or more of the same passwords using the same hashing function will have the same hash, so one could determine the hashes for an entire password list using that hashing function, then use that data to determine the matching password. And that's what a lot of password-cracking tools do.

While hashes are better than storing a password in plaintext, they can still be cracked if a good rule or password list is used with Hashcat or another cracking program. But you can't just point Hashcat at any hash and expect it to work. Imagine Hashcat as a drill with many different sized bits. For each type of hash we want to crack, we need to attach a different "bit" to Hashcat by setting it to the correct mode to attack the target hash.

If you work with hashes a lot, it might be easy to spot the difference between types of hashes that are commonly used.

At a glance, can you tell which of these two common hashes is which?

8743b52063cd84097a65d1633f5c74f5
b89eaac7e61417341b710b727768294d0e6a277b

Although you may have seen both before, it may not be immediately obvious which of these hashes is MD5 and which is SHA1. It can get even more confusing with similar hash types that have different mode numbers in Hashcat. In the case of the hashes above, it makes a big difference which is which.

When using Hashcat to crack this hash, we have to set the -m option to the correct mode. To crack an MD5 hash, we'd use the mode number 0 to get the hash.

~$ sudo hashcat -m 0 -a 0 8743b52063cd84097a65d1633f5c74f5 example.dict --force

hashcat (v4.0.1) starting...

OpenCL Platform #1: The pocl project
====================================
* Device #1: pthread-Intel(R) Core(TM)2 Duo CPU     E7500  @ 2.93GHz, 1024/3639 MB allocatable, 2MCU

8743b52063cd84097a65d1633f5c74f5:hashcat

Here, we found that the hash was made with the word "hashcat" by correctly identifying it as MD5 and using a good wordlist.

What Hashes Are Supported?

At present, a large amount of the hashes that Hashcat is capable of cracking can be identified. On the GitHub repository for hash-identifier, the list of the hashes supported is quite extensive.

Encryption formats supported:

ADLER-32
CRC-16
CRC-16-CCITT
CRC-32
CRC-32B
DES (Unix)
Domain Cached Credentials
FCS-16
GHash-32-3
GHash-32-5
GOST R 34.11-94
Haval-128
Haval-160
Haval-192 110080
Haval-224 114080
Haval-256
Lineage II C4
MD2
MD4
MD5
MD5 ($pass.$salt) - Joomla
MD5 (APR)
MD5 (Half)
MD5 (HMAC(Wordpress))
MD5 (Middle)
MD5 (phpBB3)
MD5 (Unix)
MD5 (Wordpress)
MySQL
MySQL 160bit - SHA-1(SHA-1($pass))
MySQL5 - SHA-1(SHA-1($pass))
NTLM
RAdmin v2.x
RipeMD-128
RipeMD-160
RipeMD-256
RipeMD-320
SAM - (LM_hash:NT_hash)
SHA-1
SHA-1 (Django)
SHA-1 (MaNGOS)
SHA-224
SHA-256
SHA-256 (Django)
SHA-384
SHA-384 (Django)
SHA-512
SNEFRU-128
SNEFRU-256
Tiger-128
Tiger-160
Tiger-192
XOR-32
Whirlpool

And more…

What You'll Need

To follow this guide, you'll need Python3 installed on your computer (it's cross-platform), so get that before continuing if you don't already have it. You'll also need Hashcat, which you can download by running apt install hashcat after updating your computer with apt update and apt upgrade.

If you want to generate some of your own hashes to try cracking, you can do so with the format echo -n PLAINTEXT | (HASHTYPE)sum. To create a SHA1 hash of the word "nullbyte, I would use the following command.

~$ echo -n nullbyte | sha1sum

32c0ced56f1fe08583bdb079d85a35a81995018c  -

Step 1: Download & Install Hash-Identifier

Installing the Python script is really easy. To start, open a terminal window and run the following command.

~$ git clone https://github.com/blackploit/hash-identifier.git

Cloning into 'hash-identifier'...
remote: Enumerating objects: 21, done.
remote: Total 21 (delta 0), reused 0 (delta 0), pack-reused 21
Unpacking objects: 100% (21/21), done.

Then, navigate to its directory with cd hash-identifier and list its contents with ls.

~$ cd hash-identifier
~/hash-identifier$ ls

hash-id.py  README.md  screenshots

You should see a file called hash-id.py, which you can run with the command below to start.

~/hash-identifier$ python3 hash-id.py

   #########################################################################
   #     __  __                     __           ______    _____           #
   #    /\ \/\ \                   /\ \         /\__  _\  /\  _ `\         #
   #    \ \ \_\ \     __      ____ \ \ \___     \/_/\ \/  \ \ \/\ \        #
   #     \ \  _  \  /'__`\   / ,__\ \ \  _ `\      \ \ \   \ \ \ \ \       #
   #      \ \ \ \ \/\ \_\ \_/\__, `\ \ \ \ \ \      \_\ \__ \ \ \_\ \      #
   #       \ \_\ \_\ \___ \_\/\____/  \ \_\ \_\     /\_____\ \ \____/      #
   #        \/_/\/_/\/__/\/_/\/___/    \/_/\/_/     \/_____/  \/___/  v1.2 #
   #                                                             By Zion3R #
   #                                                    www.Blackploit.com #
   #                                                   Root@Blackploit.com #
   #########################################################################
--------------------------------------------------
 HASH:

Step 2: Fingerprint Unknown Hashes

To try out hash-identifier, we'll be looking at trying to fingerprint the following five unknown hashes.

Hash 1: 7196759210defdc0
Hash 2: 1bbb234c81ef04a1c2f441253952a556276669d7fc9d1ee765bd4b18f796699d (256)
Hash 3: 32c0ced56f1fe08583bdb079d85a35a81995018c (1)
Hash 4: 753b27807b690ef889a259f3b219e024bf5c6c33c8d56116943d9285a0b55b2050981f29e6fafa660428c48d7db3c4bd2e8dd48f87c8e90bde5e0c82ed23be10 (512)
Hash 5: 5f804b61f8dcf70044ad8c1385e946a8 (md5)

To get started, let's enter the first into the waiting hash-identifier command prompt. As you can see, it yields a quick ID as a MySQL hash. This is the one we'll try to crack, so we'll return to it later.

HASH: 7196759210defdc0

Possible Hashs:
[+] MySQL
[+] MD5(Middle)

Least Possible Hashs:
[+] MD5(Half)

Our second hash, seen below, is identified as a SHA256 hash, with Haval256 being another possibility.

HASH: 1bbb234c81ef04a1c2f441253952a556276669d7fc9d1ee765bd4b18f796699d

Possible Hashs:
[+] SHA-256
[+] Haval-256

Least Possible Hashs:
[+] GOST R 34.11-94
[+] RipeMD-256
[+] SNEFRU-256
[+] SHA-256(HMAC)
[+] Haval-256(HMAC)
[+] RipeMD-256(HMAC)
[+] SNEFRU-256(HMAC)
[+] SHA-256(md5($pass))
[+] SHA-256(sha1($pass))

Our third hash is identified as SHA1:

HASH: 32c0ced56f1fe08583bdb079d85a35a81995018c

Possible Hashs:
[+] SHA-1
[+] MySQL5 - SHA-1(SHA-1($pass))

Least Possible Hashs:
[+] Tiger-160
[+] Haval-160
[+] RipeMD-160
[+] SHA-1(HMAC)
[+] Tiger-160(HMAC)
[+] RipeMD-160(HMAC)
[+] Haval-160(HMAC)
[+] SHA-1(MaNGOS)
[+] SHA-1(MaNGOS2)
[+] sha1($pass.$salt)
[+] sha1($salt.$pass)
[+] sha1($salt.md5($pass))
[+] sha1($salt.md5($pass).$salt)
[+] sha1($salt.sha1($pass))
[+] sha1($salt.sha1($salt.sha1($pass)))
[+] sha1($username.$pass)
[+] sha1($username.$pass.$salt)
[+] sha1(md5($pass))
[+] sha1(md5($pass).$salt)
[+] sha1(md5(sha1($pass)))
[+] sha1(sha1($pass))
[+] sha1(sha1($pass).$salt)
[+] sha1(sha1($pass).substr($pass,0,3))
[+] sha1(sha1($salt.$pass))
[+] sha1(sha1(sha1($pass)))
[+] sha1(strtolower($username).$pass)

And our fourth hash is identified as SHA512:

HASH: 753b27807b690ef889a259f3b219e024bf5c6c33c8d56116943d9285a0b55b2050981f29e6fafa660428c48d7db3c4bd2e8dd48f87c8e90bde5e0c82ed23be10

Possible Hashs:
[+] SHA-512
[+] Whirlpool

Least Possible Hashs:
[+] SHA-512(HMAC)
[+] Whirlpool(HMAC)

Finally, our last hash is identified as MD5:

HASH: 5f804b61f8dcf70044ad8c1385e946a8

Possible Hashs:
[+] MD5
[+] Domain Cached Credentials - MD4(MD4(($pass)).(strtolower($username)))

Least Possible Hashs:
[+] RAdmin v2.x
[+] NTLM
[+] MD4
[+] MD2
[+] MD5(HMAC)
[+] MD4(HMAC)
[+] MD2(HMAC)
[+] MD5(HMAC(Wordpress))
[+] Haval-128
[+] Haval-128(HMAC)
[+] RipeMD-128
[+] RipeMD-128(HMAC)
[+] SNEFRU-128
[+] SNEFRU-128(HMAC)
[+] Tiger-128
[+] Tiger-128(HMAC)
[+] md5($pass.$salt)
[+] md5($salt.$pass)
[+] md5($salt.$pass.$salt)
[+] md5($salt.$pass.$username)
[+] md5($salt.md5($pass))
[+] md5($salt.md5($pass))
[+] md5($salt.md5($pass.$salt))
[+] md5($salt.md5($pass.$salt))
[+] md5($salt.md5($salt.$pass))
[+] md5($salt.md5(md5($pass).$salt))
[+] md5($username.0.$pass)
[+] md5($username.LF.$pass)
[+] md5($username.md5($pass).$salt)
[+] md5(md5($pass))
[+] md5(md5($pass).$salt)
[+] md5(md5($pass).md5($salt))
[+] md5(md5($salt).$pass)
[+] md5(md5($salt).md5($pass))
[+] md5(md5($username.$pass).$salt)
[+] md5(md5(md5($pass)))
[+] md5(md5(md5(md5($pass))))
[+] md5(md5(md5(md5(md5($pass)))))
[+] md5(sha1($pass))
[+] md5(sha1(md5($pass)))
[+] md5(sha1(md5(sha1($pass))))
[+] md5(strtoupper(md5($pass)))

That was easy, but the next step is actually attacking these hashes by converting the identified hash type into a Hashcat mode number.

Step 3: Look Up Hashcat Hash Modes

To look up a hash mode, we can take a look at the exhaustive list of Hashcat supported hash types on the Hashcat examples page. An abbreviated list of some of the most popular hashes is below.

Hash-Mode   Hash-Name                   Example
0           MD5                         8743b52063cd84097a65d1633f5c74f5
10          md5($pass.$salt)            01dfae6e5d4d90d9892622325959afbe:7050461
20          md5($salt.$pass)            f0fda58630310a6dd91a7d8f0a4ceda2:4225637426
30          md5(utf16le($pass).$salt)   b31d032cfdcf47a399990a71e43c5d2a:144816
40          md5($salt.utf16le($pass))   d63d0e21fdc05f618d55ef306c54af82:13288442151473
50          HMAC-MD5 (key = $pass)      fc741db0a2968c39d9c2a5cc75b05370:1234
60          HMAC-MD5 (key = $salt)      bfd280436f45fa38eaacac3b00518f29:1234
100         SHA1                        b89eaac7e61417341b710b727768294d0e6a277b
110         sha1($pass.$salt)           2fc5a684737ce1bf7b3b239df432416e0dd07357:2014
120         sha1($salt.$pass)           cac35ec206d868b7d7cb0b55f31d9425b075082b:5363620024
130         sha1(utf16le($pass).$salt)  c57f6ac1b71f45a07dbd91a59fa47c23abcd87c2:631225
140         sha1($salt.utf16le($pass))  5db61e4cd8776c7969cfd62456da639a4c87683a:8763434884872
150         HMAC-SHA1 (key = $pass)     c898896f3f70f61bc3fb19bef222aa860e5ea717:1234
160         HMAC-SHA1 (key = $salt)     d89c92b4400b15c39e462a8caa939ab40c3aeeea:1234
200         MySQL323                    1EAFFED54F552AA5
300         MySQL4.1/MySQL5             fcf7c1b8749cf99d88e5f34271d636178fb5d130

Above, we can see two examples that might be a match for our first hash (7196759210defdc0) from the previous step. At a glance, the mode 200 "MySQL323" seems like the best match, but we can confirm it by running the example hash through hash-identifier.

HASH: 1EAFFED54F552AA5

Possible Hashs:
[+] MySQL
[+] MD5(Middle)

Least Possible Hashs:
[+] MD5(Half)

It's an exact match to our sample hash:

HASH: 7196759210defdc0

Possible Hashs:
[+] MySQL
[+] MD5(Middle)

Least Possible Hashs:
[+] MD5(Half)

If we run the other possibly-matching MySQL hash type, mode 300, we can see it doesn't match the fingerprint of our unknown sample.

HASH: fcf7c1b8749cf99d88e5f34271d636178fb5d130

Possible Hashs:
[+] SHA-1
[+] MySQL5 - SHA-1(SHA-1($pass))

Least Possible Hashs:
[+] Tiger-160
[+] Haval-160
[+] RipeMD-160
[+] SHA-1(HMAC)
[+] Tiger-160(HMAC)
[+] RipeMD-160(HMAC)
[+] Haval-160(HMAC)
[+] SHA-1(MaNGOS)
[+] SHA-1(MaNGOS2)
[+] sha1($pass.$salt)
[+] sha1($salt.$pass)
[+] sha1($salt.md5($pass))
[+] sha1($salt.md5($pass).$salt)
[+] sha1($salt.sha1($pass))
[+] sha1($salt.sha1($salt.sha1($pass)))
[+] sha1($username.$pass)
[+] sha1($username.$pass.$salt)
[+] sha1(md5($pass))
[+] sha1(md5($pass).$salt)
[+] sha1(md5(sha1($pass)))
[+] sha1(sha1($pass))
[+] sha1(sha1($pass).$salt)
[+] sha1(sha1($pass).substr($pass,0,3))
[+] sha1(sha1($salt.$pass))
[+] sha1(sha1(sha1($pass)))
[+] sha1(strtolower($username).$pass)

That proves that we've identified the correct Hashcat mode number, 200, to use in our Hashcat attack.

Step 4: Attack the Hash with Hashcat

Once we know the mode to use by identifying the hash, we can attack it using Hashcat. For it to work, we'll need to create a dictionary file with passwords on it, which Hashcat will then use to attack the hash. There are many available lists online like RockYou but, in this case, we'll be creating one called example.dict to put some password guesses in.

If you're still in the hash-identifier tool, hit Control-C on your keyboard first. Then, create and open a file in nano by typing the following.

~/hash-identifier$ nano example.dict

After adding some password guesses that include the word "hashcat" for this example, hit Control-X to exit, then Y, and confirm the filename. We can now use this file as our list of plaintext guesses, along with the mode we discovered, to crack the hash. The basic formula we will use will look like this:

sudo hashcat -m MODE_NUMBER -a 0 HASH_VALUE example.dict

When we run it with our hash of 7196759210defdc0 (the "HASH_VALUE") with our mode of 200 (the "MODE_NUMBER"), the results should look like below. If you have an older system like the example one I'm using, you may need to use the --force command with it.

~/hash-identifier$ sudo hashcat -m 200 -a 0 7196759210defdc0 example.dict --force

hashcat (v5.1.0) starting...

OpenCL Platform #1: The pocl project
====================================
* Device #1: pthread-Intel(R) Core(TM)2 Duo CPU     E7500  @ 2.93GHz, 1024/3639 MB allocatable, 2MCU

/usr/share/hashcat/OpenCL/m00200_a0-optimized.cl: Pure OpenCL kernel not found, falling back to optimized OpenCL kernel
Hashes: 1 digests; 1 unique digests, 1 unique salts
Bitmaps: 16 bits, 65536 entries, 0x0000ffff mask, 262144 bytes, 5/13 rotates
Rules: 1

Applicable optimizers:
* Optimized-Kernel
* Zero-Byte
* Not-Iterated
* Single-Hash
* Single-Salt

Password length minimum: 0
Password length maximum: 31

Watchdog: Hardware monitoring interface not found on your system.
Watchdog: Temperature abort trigger disabled.
Watchdog: Temperature retain trigger disabled.

* Device #1: build_opts '-I /usr/share/hashcat/OpenCL -D VENDOR_ID=64 -D CUDA_ARCH=0 -D AMD_ROCM=0 -D VECT_SIZE=4 -D DEVICE_TYPE=2 -D DGST_R0=0 -D DGST_R1=1 -D DGST_R2=2 -D DGST_R3=3 -D DGST_ELEM=4 -D KERN_TYPE=200 -D _unroll'
* Device #1: Kernel m00200_a0-optimized.44d10a8c.kernel not found in cache! Building may take a while...
Dictionary cache hit:
* Filename..: example.dict
* Passwords.: 17
* Bytes.....: 76
* Keyspace..: 17

- Device #1: autotuned kernel-accel to 1024
- Device #1: autotuned kernel-loops to 1
[s]tatus [p]ause [r]esume [b]ypass [c]heckpoint [q]uit => The wordlist or mask that you are using is too small.
This means that hashcat cannot use the full parallel power of your device(s).
Unless you supply more work, your cracking speed will drop.
For tips on supplying more work, see: https://hashcat.net/faq/morework

Approaching final keyspace - workload adjusted.

7196759210defdc0:hashcat

Session..........: hashcat
Status...........: Cracked
Hash.Type........: MySQL323
Hash.Target......: 7196759210defdc0
Time.Started.....: Mon Dec  9 17:00:25 2019 (0 secs)
Time.Estimated...: Mon Dec  9 17:00:25 2019 (0 secs)
Guess.Base.......: File (example.dict)
Guess.Queue......: 1/1 (100.00%)
Speed.Dev.#1.....:        0 H/s (0.03ms)
Recovered........: 1/1 (100.00%) Digests, 1/1 (100.00%) Salts
Progress.........: 17/17 (100.00%)
Rejected.........: 0/17 (0.00%)
Restore.Point....: 0/17 (0.00%)
Candidates.#1....: wow -> again
HWMon.Dev.#1.....: N/A

Started: Mon Dec  9 17:00:17 2019
Stopped: Mon Dec  9 17:00:27 2019

There we go! We get the output of 7196759210defdc0:hashcat, meaning we found the value of the MySQL323 hash to be the word "hashcat" by comparing it through all the words in the example.dict file.

Hash-Identifier Makes Fingerprinting Hashes Easy

Whenever you're dealing with an unknown type of hash, the first step to making it useful is identifying it correctly. While hash-identifier isn't a perfect tool, it's an easy way of spotting most hashes and distinguishing between several types of common and similar-looking hashes that have a different mode in Hashcat. Even if hash-identifier isn't sure what kind of hash you're dealing with, comparing the response of example hashes from the Hashcat website can help you verify that you've found the right hash.

I hope you enjoyed this guide to fingerprinting unknown hashes! If you have any questions about this tutorial on hash cracking and identification or you have a comment, ask below or feel free to reach me on Twitter @KodyKinzie.

Start your White-Hat Hacker journey with Null Byte's Beginner's Guide to Mastering Linux eBook.

Buy Now for $29.99 >

Cover image by Kody/Null Byte

Never Miss a Hacking or Security Guide

Get new Null Byte guides every week.

1 Comment

Share Your Thoughts

  • Hot
  • Latest