Breaking Hashes

In this article we will look at how we can crack a hash using hashid and hashcat. For this we use a proven procedure with the help of a word list. We will program our own little hash cracker in Golang and also use the proven tool hashcat. If you do not know what a hash and a hash function is, I recommend a quick look at the Wikipedia: https://en.wikipedia.org/wiki/Hash_function

Preparation

For the whole demonstration I will use a Docker Container with Ubuntu version 20.10. You can find on docker hub here. You can start the container as follows and directly enter bash interactively:

docker run -it --rm -v ${PWD}:/temp ubuntu:20.10 /bin/bash

If your container is running you only have to install hashcat and hashid. First update the repositories and install python and pip (hashid needs these dependencies).

  • apt update && apt upgrade
  • apt install python3 python3-pip hashcat hashid

Creation of test hashes

We want to crack one md5 hash and one sha512 hash. With the following two commands we create a hash for the corresponding type.

  • echo -n administrator | md5sum
  • echo -n administrator | sha512sum

Why “-n“. Do not print the trailing newline character. Very important!

Use hashid to identify unknown hash types

If the case occurs that it is not clear what kind of hash is involved, the tool hashid helps. In the following we examine our two generated hashes. You can read more about the hashid tool here.

  • md5 hash
  • sha512 hash

Hashid is a really powerful tool when it comes to hash analysis.

Attack the Hash – Theory

Hash functions are one-way functions. This means that a hash cannot be closed to its original value. But the same input values always result in the same hash. We can take advantage of this and use or program an application, which uses a word list as input and calculates the corresponding hash for each word. Then we can test if the calculated hash is equal to our hash.Then we have cracked the hash. Instead of word lists you can also work with so called rainbow tables. These are pre calculated hash databases. A good example is the page of Crackstation.

Attack the Hash – Own Application

Short update (02/07/2021): You can now find a short video series here on youtube about that peace of code.

(You can skip this step if you want to see directly how it works with hashcat)

Surely it is exciting for some people to see how to rudimentarily implement an application that can perform the attack described above. But for a “real” attack it is definitely recommended to use hashcat! In this example I decided to use the programming language golang. But it should be relatively easy to port the program to python or to another programming language.

Our go program is simple. We want to be able to pass the following 3 parameters to our program:

  • hash we want to attack
  • path to a wordlist
  • type of the hash (either md5 or sha512)

To parse the command line arguments I used the go extension “kingpin“.

The program reads our word list line by line and creates the corresponding hash. If the calculated hash matches our target hash, we know which text or password is behind the hash. We want to call our program as follows:

  • go run cmd/hash.go -h 200ceb26807d6bf99fd6f4f0d1ca54d4 -w test.txt -t md5
  • go run cmd/hash.go -h cf835de3d4ea01367c45e412e7a9393a85a4e40af149ed8c3ed6c37c05b67b27813d7ff8072c1035cedd19415adf17128d63186f05f0d656002b0ca1c34f44a0 -w test.txt -t sha512

I use the wordlist test.txt with the following five entries:

  • root
  • password
  • 12345
  • secret
  • administrator

Output of md5 attack:

Output of sha512 attack:

Here is the source of our program:

package main

import (
	"bufio"
	"crypto/md5"
	"crypto/sha512"
	"encoding/hex"
	"fmt"
	"log"
	"os"

	"gopkg.in/alecthomas/kingpin.v2"
)

var (
	hash     = kingpin.Flag("hash", "hash you want to attack").Short('h').String()
	wordlist = kingpin.Flag("wordlist", "path to wordlist you want to process").Short('w').Required().String()
	hashType = kingpin.Flag("type", "typ of your hash. either md5 or sha512").Short('t').Required().String()
)

func isCracked(calculatedHash string, raw string) {
	if *hash == calculatedHash {
		fmt.Println("\n \nhash cracked !!!")
		fmt.Printf("%v \t || \t %v \n", raw, calculatedHash)
		os.Exit(0)
	}
}

func processWordlist() {
	list, err := os.Open(*wordlist)

	if err != nil {
		log.Fatalf("unable to load wordlist: %v", err)
	}

	defer list.Close()

	scanner := bufio.NewScanner(list)

	for scanner.Scan() {
		scannerText := scanner.Text()
		data := []byte(scannerText)

		switch *hashType {
		case "md5":
			sum := md5.Sum(data)
			sumHex := hex.EncodeToString(sum[:])
			fmt.Printf("process: %v \t\t %v \n", scannerText, sumHex)

			isCracked(sumHex, scannerText)

		case "sha512":
			sum := sha512.Sum512(data)
			sumHex := hex.EncodeToString(sum[:])
			fmt.Printf("process: %v \t\t %v \n", scannerText, sumHex)

			isCracked(sumHex, scannerText)

		default:
			log.Fatal("unsupported hash type")
			os.Exit(1)
		}
	}
}

func main() {
	fmt.Printf("attacking hash: %v \n", *hash)

	kingpin.Parse()
	processWordlist()
}

Here is the link to the github repository: https://github.com/AICDEV/thefinn/tree/master/cryptography/simple_hash_breaker

Attack the hash – Hashcat

Now it’s time for hashcat. This time we use a prepared word list. You can use this one from Crackstation for example. So download the wordlist. A really great overview of hashcat can be found here. So enough talk. Let’s go.

Running “hashcat –help” print an amazing help and manual. Important is the section about the hash types

the attack modes

and there is a sample command

So our hashcat comman is this: “hashcat -a 0 -m 0 200ceb26807d6bf99fd6f4f0d1ca54d4 wordlist.txt -O

After a little bit of time the result from hashcat

I hope you were able to see how hashcat works. As a little exercise you can try to crack the SHA512 hash using hashcat.

Attack salted hash with hashcat

To show another example with hashcat, we take a hash from an /etc/shadow entry. The /etc/shadow file stores actual password in encrypted format. You can read more about here. Our example hash is the following:

“$1$.rquYmlo$yFWfaSKplZmp1Id2VZ6iT1”

The prefix “$1$” indicates that the is from type md5. Let’s see what hashid tells us:

Let’s see if hashcat supports this hash type.

Now we have all the information we need to drive an attack on this hash.

The whole thing can take a while. With me it took about 30 minutes. But after that the result looks like this.

Note about the password. I didn’t make it up, I just took it from a CTF challenge.

Summary

I hope you had fun and learned something about cracking hashes. Of course there is much more to tell about it. Nevertheless, I think it was a good start.

Categories:

No responses yet

Leave a Reply

Your email address will not be published. Required fields are marked *