A 53: Password Hashes with Go (60 pts)

What You Need

A Linux machine with Go installed, which you prepared in a previous project.

Purpose

Generate and crack Windows password hashes with Go.

The same techniques work for Linux and Mac hashes, but thousands of times slower, because Windows uses especially weak hashes.

Getting Test Hashes

You can get hashes from Windows machines with Cain, or by using an online hash calculator.

Here's a simple test case. A password of

password
has this hash on Windows machines:
8846f7eaee8fb117ad06bdd830b7586c
Windows does not use any salt, so every user with the same password has the same password hash.

Windows Password Hashes

MD4 Hashes

Microsoft uses the ancient MD4 hashing algorithm, which has been deprecated. It's apparently no longer included in a standard installation of Go, so we'll have to "go get" it from Github.

On your Linux server, in a Terminal window, execute these commands:

go get golang.org/x/crypto/md4
mkdir -p work/src/my_project/hash1
nano ~/work/src/my_project/hash1/hash1.go
In nano, enter this code, as shown below.
package main
import "golang.org/x/crypto/md4"
import "fmt"

func main() {
    s := "password"

    h := md4.New()
    h.Write([]byte(s))
    bs := h.Sum(nil)

    fmt.Println(s)
    fmt.Printf("%x\n", bs)
}

Save the file with Ctrl+X, Y, Enter.

Execute these commands to compile the program and run it:

go install my_project/hash1
hash1
The program runs, but the hash value is wrong, as shown below.

MD4 Hashes with Unicode

The problem is that Microsoft uses 16-bit Unicode, not ASCII. This is arguably a very bad system, and it's very difficult to use in Go, which uses "runes" and the more modern UTF-8 system.

For our purposes, we'll use a horrible nasty hack and just manually insert a null byte after each character.

On your Linux server, in a Terminal window, execute these commands:

mkdir -p work/src/my_project/hash2
nano ~/work/src/my_project/hash2/hash2.go
In nano, enter this code, as shown below.
package main
import ( "golang.org/x/crypto/md4"; "fmt" )

func main() {
	s := "password"
	u := ""
	n := 0

	for i, c := range s {
		u = u + string(c) + "\x00"
		n = i
	}

    h := md4.New()
    h.Write([]byte(u))
    bs := h.Sum(nil)

    fmt.Printf("%s is %d runes long: %x\n", u, n+1, u)
    fmt.Printf("%x\n", bs)
}

Save the file with Ctrl+X, Y, Enter.

Execute these commands to compile the program and run it:

go install my_project/hash2
hash2
The program runs, showing the 16-byte encoded form of the password and the correct hash value, as shown below.


A 53.1: Challenge: Hash GO_LOVER (5 pts)

Calculate the NTLM hash of this password:
GO_LOVER
That hash value is the flag.

A 53.2: Crack a Hashed PIN (10 pts)

Create a program that calculates the NTLM hashes for all two-digit passwords from 00 to 99, as shown below.

Find the hash containing ada. That two-digit PIN is the flag.


A 53.3-5: Challenge: Windows Hashes (15 pts)

The following Windows passwords are constructed according to this system:
CCSF-username-PIN
Where "username" is the username in lowercase and PIN is a two-digit number.

For example, a user named "Sam" might have a password like this:

CCSF-sam-01
Crack these passwords, which were collected from a Windows 7 machine with Cain.

The NTLM hash is at the right end of each line, after the final colon.

Ming:"":"":AAD3B435B51404EEAAD3B435B51404EE:52C4859C0617E4A8FEC24BA890C5FC57
Mohammed:"":"":AAD3B435B51404EEAAD3B435B51404EE:39057EF3A9FE57D98E7A9BAB7CD2F4F9
sam:"":"":AAD3B435B51404EEAAD3B435B51404EE:19A641D2520B983ABB7C931CEFF933FA
Note that the NTLM hash is the rightmost part of each line, after the last colon.

The passwords are the flags, as shown below:


A3.6-8: Challenge: MD5 Hashes with Several Rounds (15 pts)

The company using the Windows passwords in the previous challenge sets up an online system, with passwords formed the same way.

Somewhere in the Terms of Service, it strongly warns users not to re-use the same password as their Windows password.

In addition, it is now much more secure, because it uses MD5 instead of MD4, and not only that, it uses many rounds of MD5.

It doesn't use Unicode encoding.

Crack these hashes.

Ming: 7621eca98fe6a1885d4f5f56a0525915
Mohammed: b2173861e8787a326fb4476aa9585e1c
sam: 42e646b706acfab0cf8079351d176121

The passwords are the flags, as shown below:

Hint: How to get a MD5 hash from a string in Golang?

A3.9-11: Challenge: Many Rounds of MD5 and SHA-1 (15 pts)

Somehow, evil hackers broke into the previous Web application.

So the new, super-enhanced system uses a much larger number of MD5 rounds, followed by an even larger number of SHA1 hash rounds. Of course, the total number of hashing rounds is less than 500, because management is sure that's enough.

And now each user has to click "I Agree" to a pop-up box requiring them not to re-use passwords, so only a complete idiot would do that.

Crack these hashes if you can!

Ming: ce788ed5f855e51e6fd78f923b43a6407467c5f2
Mohammed: 582d99006950cddeb2df9f40b3f65ebc283dc378
sam: da660655f4d4714fe605e9063d1ded4b749c50a9

The passwords are the flags, as shown below:


Posted: 11-3-19