2525 except NotImplementedError :
2626 pass
2727
28+ import base64
29+ import binascii
2830import gc
2931import os
3032import re
@@ -261,7 +263,31 @@ def apache_sha1_passwd(password, **kwargs):
261263 '{SHA}IGyAQTualsExLMNGt9JRe4RGPt0='
262264 """
263265
264- return "{SHA}%s" % sha1 (password ).digest ().encode ("base64" ).strip ()
266+ return "{SHA}%s" % base64 .b64encode (sha1 (password ).digest ())
267+
268+ def ssha_passwd (password , salt , ** kwargs ):
269+ """
270+ >>> ssha_passwd(password='testpass', salt='salt')
271+ '{SSHA}mU1HPTvnmoXOhE4ROHP6sWfbfoRzYWx0'
272+ """
273+
274+ return "{SSHA}%s" % base64 .b64encode (sha1 (password + salt ).digest () + salt )
275+
276+ def ssha256_passwd (password , salt , ** kwargs ):
277+ """
278+ >>> ssha256_passwd(password='testpass', salt='salt')
279+ '{SSHA256}hhubsLrO/Aje9F/kJrgv5ZLE40UmTrVWvI7Dt6InP99zYWx0'
280+ """
281+
282+ return "{SSHA256}%s" % base64 .b64encode (sha256 (password + salt ).digest () + salt )
283+
284+ def ssha512_passwd (password , salt , ** kwargs ):
285+ """
286+ >>> ssha512_passwd(password='testpass', salt='salt')
287+ '{SSHA512}mCUSLfPMhXCQOJl9WHW/QMn9v9sjq7Ht/Wk7iVau8vLOfh+PeynkGMikqIE8sStFd0khdfcCD8xZmC6UyjTxsHNhbHQ='
288+ """
289+
290+ return "{SSHA512}%s" % base64 .b64encode (sha512 (password + salt ).digest () + salt )
265291
266292def sha224_generic_passwd (password , uppercase = False ):
267293 """
@@ -487,6 +513,9 @@ def _encode64(input_, count):
487513 HASH .APACHE_SHA1 : apache_sha1_passwd ,
488514 HASH .VBULLETIN : vbulletin_passwd ,
489515 HASH .VBULLETIN_OLD : vbulletin_passwd ,
516+ HASH .SSHA : ssha_passwd ,
517+ HASH .SSHA256 : ssha256_passwd ,
518+ HASH .SSHA512 : ssha512_passwd ,
490519 }
491520
492521def storeHashesToFile (attack_dict ):
@@ -829,44 +858,54 @@ def dictionaryAttack(attack_dict):
829858 hash_ = hash_ .split ()[0 ] if hash_ and hash_ .strip () else hash_
830859
831860 if re .match (hash_regex , hash_ ):
832- item = None
861+ try :
862+ item = None
863+
864+ if hash_regex not in (HASH .CRYPT_GENERIC , HASH .JOOMLA , HASH .WORDPRESS , HASH .UNIX_MD5_CRYPT , HASH .APACHE_MD5_CRYPT , HASH .APACHE_SHA1 , HASH .VBULLETIN , HASH .VBULLETIN_OLD , HASH .SSHA , HASH .SSHA256 , HASH .SSHA512 ):
865+ hash_ = hash_ .lower ()
866+
867+ if hash_regex in (HASH .MYSQL , HASH .MYSQL_OLD , HASH .MD5_GENERIC , HASH .SHA1_GENERIC , HASH .APACHE_SHA1 ):
868+ item = [(user , hash_ ), {}]
869+ elif hash_regex in (HASH .SSHA ,):
870+ item = [(user , hash_ ), {'salt' : hash_ .decode ("base64" )[20 :]}]
871+ elif hash_regex in (HASH .SSHA256 ,):
872+ item = [(user , hash_ ), {'salt' : hash_ .decode ("base64" )[32 :]}]
873+ elif hash_regex in (HASH .SSHA512 ,):
874+ item = [(user , hash_ ), {'salt' : hash_ .decode ("base64" )[64 :]}]
875+ elif hash_regex in (HASH .ORACLE_OLD , HASH .POSTGRES ):
876+ item = [(user , hash_ ), {'username' : user }]
877+ elif hash_regex in (HASH .ORACLE ,):
878+ item = [(user , hash_ ), {'salt' : hash_ [- 20 :]}]
879+ elif hash_regex in (HASH .MSSQL , HASH .MSSQL_OLD , HASH .MSSQL_NEW ):
880+ item = [(user , hash_ ), {'salt' : hash_ [6 :14 ]}]
881+ elif hash_regex in (HASH .CRYPT_GENERIC ,):
882+ item = [(user , hash_ ), {'salt' : hash_ [0 :2 ]}]
883+ elif hash_regex in (HASH .UNIX_MD5_CRYPT , HASH .APACHE_MD5_CRYPT ):
884+ item = [(user , hash_ ), {'salt' : hash_ .split ('$' )[2 ], 'magic' : '$%s$' % hash_ .split ('$' )[1 ]}]
885+ elif hash_regex in (HASH .JOOMLA , HASH .VBULLETIN , HASH .VBULLETIN_OLD ):
886+ item = [(user , hash_ ), {'salt' : hash_ .split (':' )[- 1 ]}]
887+ elif hash_regex in (HASH .WORDPRESS ,):
888+ if ITOA64 .index (hash_ [3 ]) < 32 :
889+ item = [(user , hash_ ), {'salt' : hash_ [4 :12 ], 'count' : 1 << ITOA64 .index (hash_ [3 ]), 'prefix' : hash_ [:12 ]}]
890+ else :
891+ warnMsg = "invalid hash '%s'" % hash_
892+ logger .warn (warnMsg )
893+
894+ if item and hash_ not in keys :
895+ resumed = hashDBRetrieve (hash_ )
896+ if not resumed :
897+ attack_info .append (item )
898+ user_hash .append (item [0 ])
899+ else :
900+ infoMsg = "resuming password '%s' for hash '%s'" % (resumed , hash_ )
901+ if user and not user .startswith (DUMMY_USER_PREFIX ):
902+ infoMsg += " for user '%s'" % user
903+ logger .info (infoMsg )
904+ resumes .append ((user , hash_ , resumed ))
905+ keys .add (hash_ )
833906
834- if hash_regex not in (HASH .CRYPT_GENERIC , HASH .JOOMLA , HASH .WORDPRESS , HASH .UNIX_MD5_CRYPT , HASH .APACHE_MD5_CRYPT , HASH .APACHE_SHA1 , HASH .VBULLETIN , HASH .VBULLETIN_OLD ):
835- hash_ = hash_ .lower ()
836-
837- if hash_regex in (HASH .MYSQL , HASH .MYSQL_OLD , HASH .MD5_GENERIC , HASH .SHA1_GENERIC , HASH .APACHE_SHA1 ):
838- item = [(user , hash_ ), {}]
839- elif hash_regex in (HASH .ORACLE_OLD , HASH .POSTGRES ):
840- item = [(user , hash_ ), {'username' : user }]
841- elif hash_regex in (HASH .ORACLE ,):
842- item = [(user , hash_ ), {'salt' : hash_ [- 20 :]}]
843- elif hash_regex in (HASH .MSSQL , HASH .MSSQL_OLD , HASH .MSSQL_NEW ):
844- item = [(user , hash_ ), {'salt' : hash_ [6 :14 ]}]
845- elif hash_regex in (HASH .CRYPT_GENERIC ,):
846- item = [(user , hash_ ), {'salt' : hash_ [0 :2 ]}]
847- elif hash_regex in (HASH .UNIX_MD5_CRYPT , HASH .APACHE_MD5_CRYPT ):
848- item = [(user , hash_ ), {'salt' : hash_ .split ('$' )[2 ], 'magic' : '$%s$' % hash_ .split ('$' )[1 ]}]
849- elif hash_regex in (HASH .JOOMLA , HASH .VBULLETIN , HASH .VBULLETIN_OLD ):
850- item = [(user , hash_ ), {'salt' : hash_ .split (':' )[- 1 ]}]
851- elif hash_regex in (HASH .WORDPRESS ,):
852- if ITOA64 .index (hash_ [3 ]) < 32 :
853- item = [(user , hash_ ), {'salt' : hash_ [4 :12 ], 'count' : 1 << ITOA64 .index (hash_ [3 ]), 'prefix' : hash_ [:12 ]}]
854- else :
855- warnMsg = "invalid hash '%s'" % hash_
856- logger .warn (warnMsg )
857-
858- if item and hash_ not in keys :
859- resumed = hashDBRetrieve (hash_ )
860- if not resumed :
861- attack_info .append (item )
862- user_hash .append (item [0 ])
863- else :
864- infoMsg = "resuming password '%s' for hash '%s'" % (resumed , hash_ )
865- if user and not user .startswith (DUMMY_USER_PREFIX ):
866- infoMsg += " for user '%s'" % user
867- logger .info (infoMsg )
868- resumes .append ((user , hash_ , resumed ))
869- keys .add (hash_ )
907+ except (binascii .Error , IndexError ):
908+ pass
870909
871910 if not attack_info :
872911 continue
@@ -875,7 +914,7 @@ def dictionaryAttack(attack_dict):
875914 while not kb .wordlists :
876915
877916 # the slowest of all methods hence smaller default dict
878- if hash_regex in (HASH .ORACLE_OLD , HASH . WORDPRESS ):
917+ if hash_regex in (HASH .ORACLE_OLD ,):
879918 dictPaths = [paths .SMALL_DICT ]
880919 else :
881920 dictPaths = [paths .WORDLIST ]
0 commit comments