So I noticed whilst web app testing that would receive a cookie with a value called bIPs:
709aed354747fda133a5da28dbed60e7
95eb48ad7eae5c0aa9766f0258ae8a35

Looks like it’s using a big IP load balancer. I noticed it was MD5 and that was confirmed by finding the code that generates the hash(cheers scriptmonkey).

I decided to use Hashcat to do the bruteforcing. First thing that came to mind was how to use a dictionary containing IP addresses. I did think about writing a script to generate a all_ips.dict file but it would be huge, 4,294,967,296 lines to be exact! No chance am I doing that!

I then decided to try a bruteforce method but it wasn’t possible to generate a decent input mask that would work.

A quick jump onto the hashcat irc channel at #hashcat on rizon network and help from atom and Xanaderp came to the idea to generate 2 word lists, one for the first 2 octets and another for the second 2 octets.

1
2
3
4
5
6
7
8
9
#!/bin/bash
for a in `seq 0 255`
do
  for b in `seq 0 255`
  do
  echo "$a.$b." >> ips_left.txt
  echo "$a.$b" >> ips_right.txt
  done
done

Update from Ben Campbell to do this all in one swoop 🙂

Each dictionary is 65536 lines long and so is only 500K or so in size 🙂

Now to perform the cracking:

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
29
30
phillips321@KubuntuDesktop:$ ./oclHashcat-plus64.bin bIPs.txt -a 1 ips_left.dict ips_right.dict
oclHashcat-plus v0.07 by atom starting...
Hashes: 2
Unique digests: 2
Bitmaps: 8 bits, 256 entries, 0x000000ff mask, 1024 bytes
GPU-Loops: 128
GPU-Accel: 40
Password lengths range: 1 - 15
Platform: AMD compatible platform found
Watchdog: Temperature limit set to 90c
Device #1: Cayman, 2048MB, 0Mhz, 22MCU
Device #1: Allocating 132MB host-memory
Device #1: Kernel ./kernels/4098/m0000_a1.Cayman.64.kernel (250492 bytes)
Scanned dictionary ips_right.dict: 467968 bytes, 65536 words, 65536 keyspace, starting attack...
Scanned dictionary ips_left.dict: 533504 bytes, 65536 words, 4294967296 keyspace, starting attack...
709aed354747fda133a5da28dbed60e7:172.16.40.150
95eb48ad7eae5c0aa9766f0258ae8a35:172.16.41.151
Status.......: Cracked
Input.Base...: File (ips_left.dict)
Input.Mod....: File (ips_right.dict)
Hash.Type....: MD5
Time.Running.: 4 secs
Time.Util....: 4001.3ms/0.0ms Real/CPU, 0.0% idle
Speed........:   308.3M c/s Real,  1332.0M c/s GPU
Recovered....: 2/2 Digests, 1/1 Salts
Progress.....: 1233633280/4294967296 (28.72%)
Rejected.....: 0/1233633280 (0.00%)
HW.Monitor.#1:  0% GPU, 44c Temp
Started: Wed Apr  4 14:29:31 2012
Stopped: Wed Apr  4 14:29:36 2012

Bingo, MD5 hashes of IP addresses cracked in 4 seconds!

Update: Speaking with unix-ninja on the hashcat forum he mentioned that some devices do actually store the zero’s within their IP address, so 192.168.1.1 would actually be 192.168.001.001.

Taking this into consideration I decided to quick throw together another script to combat this:

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
#!/bin/bash
for a in `seq 0 2`
do
 for b in `seq 0 9`
  do
  for c in `seq 0 9`
    do
   for d in `seq 0 2`
   do
    for e in `seq 0 9`
     do
     for f in `seq 0 9`
       do
      echo "$a$b$c.$d$e$f." >> ips_left.txt
        echo "$a$b$c.$d$e$f" >> ips_right.txt
     done
    done
   done
  done
  done
done
for i in `seq 256 299`
do
 grep -v $i ips_left.txt > ips_left.tmp && mv ips_left.tmp ips_left.txt
 grep -v $i ips_right.txt > ips_right.tmp && mv ips_right.tmp ips_right.txt
done

Update
Prior to F5 load balancers using MD5 for the cookie they used to just encode it so you would result in something like:

1
f5cookie=1005421066.20736.0000

This is relatively easy to decode:

1
2
3
4
5
6
>>> import struct
>>> cookie = "1005421066.20736.0000"
>>> (ip,port,end)=cookie.split(".")
>>> (a,b,c,d)=[ord(i) for i in struct.pack("i",int(ip))]
>>> print "Decoded IP: %s %s %s %s" % (a,b,c,d)
Decoded IP: 10.130.237.59

Leave a Reply