So the Juniper Netscreen/SSG ScreenOS password hash is a bit of a hidden mystery. I had in my hand the config of a Netscreen device and I wanted to perform a reverse of the password hashes to see if they were weak.

In this case here’s the line from the config:

1
set admin user "admin" password "nAePB0rfAm+Nc4YO3s0JwPHtRXIHdn" privilege "all"

John The ripper has supported Netscreen passwords since back in 2008 when Samuel Moñux released this patch. Unfortunately John was too slow for my needs as I was up against a deadline, thus I looked at the faster approach of using the GPU to perform the cracking. Hashcat is the best tool for the job but unfortunately Hashcat didn’t support this hashing algorithm. 🙁

After a looking through jar source code I found this python script which can generate a Netscreen hash, getting warmer. Here’s a shortened version of the code to show just the function we’re interested in:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
def makepass(user, password):
    middle = "Administration Tools"
    s = "%s:%s:%s" % (user, middle, password)
    print s
    m = hashlib.md5(s).digest()
    narray = []
     
    for i in range(8):
        n1 = ord(m[2*i])
        n2 = ord(m[2*i+1])
        narray.append( (n1<<8 & 0xff00) | (n2 & 0xff) )
   
    res = ""
    for i in narray:
        p1 = i >> 12 & 0xf
        p2 = i >> 6  & 0x3f
        p3 = i       & 0x3f
        res += b64[p1] + b64[p2] + b64[p3]
   
    for c, n in  zip("nrcstn", [0, 6, 12, 17, 23, 29]):
        res = res[:n] + c + res[n:]
    return res

After looking through the code it is clear that there is a fixed salt of Administration Tools and a salt of the username(lines 2 and 3).
The code then takes each 2 chars and adds the binaries together(lines 8-11)
From this it creates 3 characters from the 16bits(lines 14-18)
And finally is scatters the letters n,r,c,s,t & n onto the hash in specific places (lines 20 and 21)
It’s worth noting that the letters nrcstn is actually NeTSCReeN in reverse without the e’s 🙂

Using this code it was possible to write some new code to reverse backwards through the steps in order to go from a Netscreen hash back to the raw MD5 hash. Here’s the function for this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
def reversetomd5(knownhash):
    # strip out nrcstn fixed characters
    clean=""
    for i in [1,2,3,4,5,7,8,9,10,11,13,14,15,16,18,19,20,21,22,24,25,26,27,28]:
        clean+=knownhash[i]
   
    # create blocks
    block=[]
    for i in xrange(2,24,3):
        p1 = b64.index(clean[i-2])
        p2 = b64.index(clean[i-1])
        p3 = b64.index(clean[i])
        block.append(p1 << 12 | p2 << 6 | p3)
   
    # split block into half and find out character for each decimal
    md5hash=""
    for i in block:
        n1 = i >> 8
        n2 = i & 0xff
        md5hash+=chr(n1)+chr(n2)
    return binascii.hexlify(md5hash)

Using this function you are able to give it a Netscreen hash and you’ll get back the raw MD5.

1
Knownhash of:nAePB0rfAm+Nc4YO3s0JwPHtRXIHdn has MD5Hash of: 078f1d1f09bede18edf49c0f745781dd

Now using the power of GPU cracking and my favourite tool Hashcat it is possible to crack the hash. We need to put the hash in a format that hashcat can understand so we create a file called netscreen.txt and put the hash in the following format(note the training colon after the fixed salt):

1
2
[hash]:[user]:Administration Tools:
078f1d1f09bede18edf49c0f745781dd:admin:Administration Tools:

We then use hashcat’s mode 20 which is md5($salt.$pass) to crack the hash:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
C:\cudaHashcat64.exe -m 20 netscreen.txt rockyou.txt
cudaHashcat v1.01 starting...
Hashes: 1 total, 1 unique salts, 1 unique digests
Bitmaps: 8 bits, 256 entries, 0x000000ff mask, 1024 bytes
Watchdog: Temperature abort trigger set to 90c
Watchdog: Temperature retain trigger set to 80c
Device #1: GeForce GTX 660M, 2048MB, 950Mhz, 2MCU
Device #1: Kernel ./kernels/4318/m0020_a0.sm_30.64.ptx
Device #1: Kernel ./kernels/4318/bzero.64.ptx

Generated dictionary stats for rockyou.txt: 139921541 bytes, 14344395 words, 14343300 keyspace

078f1d1f09bede18edf49c0f745781dd:admin:Administration Tools::MySecretPassword

Session.Name...: cudaHashcat
Status.........: Cracked
Input.Mode.....: File (rockyou.txt)
Hash.Target....: 078f1d1f09bede18edf49c0f745781dd:admin:Administration Tools:
Hash.Type......: md5($salt.$pass)
Time.Started...: Fri Jan 10 15:03:24 2014 (5 secs)
Speed.GPU.#1...:  4886.1 kH/s
Recovered......: 1/1 (100.00%) Digests, 1/1 (100.00%) Salts
Progress.......: 11109723/14343300 (77.46%)
Rejected.......: 1371/11109723 (0.01%)
HWMon.GPU.#1...:  0% Util, 41c Temp, N/A Fan

Started: Fri Jan 10 15:03:24 2014
Stopped: Fri Jan 10 15:03:32 2014

Bingo it’s cracked the hash with the password MySecretPassword

As this algorithm uses more than just a fixed salt to create the hash I’ll speak to Atom (the creator of hashcat) to see if he want’s to implement it into a future release, but until then this code should help you in cracking netscreen passwords.

Update: Atom has added this hash type to oclHashcat as of version 1.20 https://hashcat.net/hashcat/ (Feature request here: https://hashcat.net/trac/ticket/235)

7 Responses to Cracking a Juniper Netscreen ScreenOS Password Hash

Leave a Reply