mirror of
				https://github.com/sqlmapproject/sqlmap.git
				synced 2025-10-30 15:37:43 +03:00 
			
		
		
		
	Adding support for SSHA, SSHA256 and SSHA512 (Issue #1881)
This commit is contained in:
		
							parent
							
								
									311444a4ac
								
							
						
					
					
						commit
						7c874350d2
					
				|  | @ -133,6 +133,9 @@ class HASH: | ||||||
|     APACHE_SHA1 = r'\A\{SHA\}[a-zA-Z0-9+/]+={0,2}\Z' |     APACHE_SHA1 = r'\A\{SHA\}[a-zA-Z0-9+/]+={0,2}\Z' | ||||||
|     VBULLETIN = r'\A[0-9a-fA-F]{32}:.{30}\Z' |     VBULLETIN = r'\A[0-9a-fA-F]{32}:.{30}\Z' | ||||||
|     VBULLETIN_OLD = r'\A[0-9a-fA-F]{32}:.{3}\Z' |     VBULLETIN_OLD = r'\A[0-9a-fA-F]{32}:.{3}\Z' | ||||||
|  |     SSHA = r'\A\{SSHA\}[a-zA-Z0-9+/]+={0,2}\Z' | ||||||
|  |     SSHA256 = r'\A\{SSHA256\}[a-zA-Z0-9+/]+={0,2}\Z' | ||||||
|  |     SSHA512 = r'\A\{SSHA512\}[a-zA-Z0-9+/]+={0,2}\Z' | ||||||
| 
 | 
 | ||||||
| # Reference: http://www.zytrax.com/tech/web/mobile_ids.html | # Reference: http://www.zytrax.com/tech/web/mobile_ids.html | ||||||
| class MOBILES: | class MOBILES: | ||||||
|  |  | ||||||
|  | @ -25,6 +25,8 @@ else: | ||||||
|     except NotImplementedError: |     except NotImplementedError: | ||||||
|         pass |         pass | ||||||
| 
 | 
 | ||||||
|  | import base64 | ||||||
|  | import binascii | ||||||
| import gc | import gc | ||||||
| import os | import os | ||||||
| import re | import re | ||||||
|  | @ -261,7 +263,31 @@ def apache_sha1_passwd(password, **kwargs): | ||||||
|     '{SHA}IGyAQTualsExLMNGt9JRe4RGPt0=' |     '{SHA}IGyAQTualsExLMNGt9JRe4RGPt0=' | ||||||
|     """ |     """ | ||||||
| 
 | 
 | ||||||
|     return "{SHA}%s" % sha1(password).digest().encode("base64").strip() |     return "{SHA}%s" % base64.b64encode(sha1(password).digest()) | ||||||
|  | 
 | ||||||
|  | def ssha_passwd(password, salt, **kwargs): | ||||||
|  |     """ | ||||||
|  |     >>> ssha_passwd(password='testpass', salt='salt') | ||||||
|  |     '{SSHA}mU1HPTvnmoXOhE4ROHP6sWfbfoRzYWx0' | ||||||
|  |     """ | ||||||
|  | 
 | ||||||
|  |     return "{SSHA}%s" % base64.b64encode(sha1(password + salt).digest() + salt) | ||||||
|  | 
 | ||||||
|  | def ssha256_passwd(password, salt, **kwargs): | ||||||
|  |     """ | ||||||
|  |     >>> ssha256_passwd(password='testpass', salt='salt') | ||||||
|  |     '{SSHA256}hhubsLrO/Aje9F/kJrgv5ZLE40UmTrVWvI7Dt6InP99zYWx0' | ||||||
|  |     """ | ||||||
|  | 
 | ||||||
|  |     return "{SSHA256}%s" % base64.b64encode(sha256(password + salt).digest() + salt) | ||||||
|  | 
 | ||||||
|  | def ssha512_passwd(password, salt, **kwargs): | ||||||
|  |     """ | ||||||
|  |     >>> ssha512_passwd(password='testpass', salt='salt') | ||||||
|  |     '{SSHA512}mCUSLfPMhXCQOJl9WHW/QMn9v9sjq7Ht/Wk7iVau8vLOfh+PeynkGMikqIE8sStFd0khdfcCD8xZmC6UyjTxsHNhbHQ=' | ||||||
|  |     """ | ||||||
|  | 
 | ||||||
|  |     return "{SSHA512}%s" % base64.b64encode(sha512(password + salt).digest() + salt) | ||||||
| 
 | 
 | ||||||
| def sha224_generic_passwd(password, uppercase=False): | def sha224_generic_passwd(password, uppercase=False): | ||||||
|     """ |     """ | ||||||
|  | @ -487,6 +513,9 @@ __functions__ = { | ||||||
|                     HASH.APACHE_SHA1: apache_sha1_passwd, |                     HASH.APACHE_SHA1: apache_sha1_passwd, | ||||||
|                     HASH.VBULLETIN: vbulletin_passwd, |                     HASH.VBULLETIN: vbulletin_passwd, | ||||||
|                     HASH.VBULLETIN_OLD: vbulletin_passwd, |                     HASH.VBULLETIN_OLD: vbulletin_passwd, | ||||||
|  |                     HASH.SSHA: ssha_passwd, | ||||||
|  |                     HASH.SSHA256: ssha256_passwd, | ||||||
|  |                     HASH.SSHA512: ssha512_passwd, | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
| def storeHashesToFile(attack_dict): | def storeHashesToFile(attack_dict): | ||||||
|  | @ -829,44 +858,54 @@ def dictionaryAttack(attack_dict): | ||||||
|                 hash_ = hash_.split()[0] if hash_ and hash_.strip() else hash_ |                 hash_ = hash_.split()[0] if hash_ and hash_.strip() else hash_ | ||||||
| 
 | 
 | ||||||
|                 if re.match(hash_regex, hash_): |                 if re.match(hash_regex, hash_): | ||||||
|                     item = None |                     try: | ||||||
|  |                         item = None | ||||||
| 
 | 
 | ||||||
|                     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): |                         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): | ||||||
|                         hash_ = hash_.lower() |                             hash_ = hash_.lower() | ||||||
| 
 | 
 | ||||||
|                     if hash_regex in (HASH.MYSQL, HASH.MYSQL_OLD, HASH.MD5_GENERIC, HASH.SHA1_GENERIC, HASH.APACHE_SHA1): |                         if hash_regex in (HASH.MYSQL, HASH.MYSQL_OLD, HASH.MD5_GENERIC, HASH.SHA1_GENERIC, HASH.APACHE_SHA1): | ||||||
|                         item = [(user, hash_), {}] |                             item = [(user, hash_), {}] | ||||||
|                     elif hash_regex in (HASH.ORACLE_OLD, HASH.POSTGRES): |                         elif hash_regex in (HASH.SSHA,): | ||||||
|                         item = [(user, hash_), {'username': user}] |                             item = [(user, hash_), {'salt': hash_.decode("base64")[20:]}] | ||||||
|                     elif hash_regex in (HASH.ORACLE,): |                         elif hash_regex in (HASH.SSHA256,): | ||||||
|                         item = [(user, hash_), {'salt': hash_[-20:]}] |                             item = [(user, hash_), {'salt': hash_.decode("base64")[32:]}] | ||||||
|                     elif hash_regex in (HASH.MSSQL, HASH.MSSQL_OLD, HASH.MSSQL_NEW): |                         elif hash_regex in (HASH.SSHA512,): | ||||||
|                         item = [(user, hash_), {'salt': hash_[6:14]}] |                             item = [(user, hash_), {'salt': hash_.decode("base64")[64:]}] | ||||||
|                     elif hash_regex in (HASH.CRYPT_GENERIC,): |                         elif hash_regex in (HASH.ORACLE_OLD, HASH.POSTGRES): | ||||||
|                         item = [(user, hash_), {'salt': hash_[0:2]}] |                             item = [(user, hash_), {'username': user}] | ||||||
|                     elif hash_regex in (HASH.UNIX_MD5_CRYPT, HASH.APACHE_MD5_CRYPT): |                         elif hash_regex in (HASH.ORACLE,): | ||||||
|                         item = [(user, hash_), {'salt': hash_.split('$')[2], 'magic': '$%s$' % hash_.split('$')[1]}] |                             item = [(user, hash_), {'salt': hash_[-20:]}] | ||||||
|                     elif hash_regex in (HASH.JOOMLA, HASH.VBULLETIN, HASH.VBULLETIN_OLD): |                         elif hash_regex in (HASH.MSSQL, HASH.MSSQL_OLD, HASH.MSSQL_NEW): | ||||||
|                         item = [(user, hash_), {'salt': hash_.split(':')[-1]}] |                             item = [(user, hash_), {'salt': hash_[6:14]}] | ||||||
|                     elif hash_regex in (HASH.WORDPRESS,): |                         elif hash_regex in (HASH.CRYPT_GENERIC,): | ||||||
|                         if ITOA64.index(hash_[3]) < 32: |                             item = [(user, hash_), {'salt': hash_[0:2]}] | ||||||
|                             item = [(user, hash_), {'salt': hash_[4:12], 'count': 1 << ITOA64.index(hash_[3]), 'prefix': hash_[:12]}] |                         elif hash_regex in (HASH.UNIX_MD5_CRYPT, HASH.APACHE_MD5_CRYPT): | ||||||
|                         else: |                             item = [(user, hash_), {'salt': hash_.split('$')[2], 'magic': '$%s$' % hash_.split('$')[1]}] | ||||||
|                             warnMsg = "invalid hash '%s'" % hash_ |                         elif hash_regex in (HASH.JOOMLA, HASH.VBULLETIN, HASH.VBULLETIN_OLD): | ||||||
|                             logger.warn(warnMsg) |                             item = [(user, hash_), {'salt': hash_.split(':')[-1]}] | ||||||
|  |                         elif hash_regex in (HASH.WORDPRESS,): | ||||||
|  |                             if ITOA64.index(hash_[3]) < 32: | ||||||
|  |                                 item = [(user, hash_), {'salt': hash_[4:12], 'count': 1 << ITOA64.index(hash_[3]), 'prefix': hash_[:12]}] | ||||||
|  |                             else: | ||||||
|  |                                 warnMsg = "invalid hash '%s'" % hash_ | ||||||
|  |                                 logger.warn(warnMsg) | ||||||
| 
 | 
 | ||||||
|                     if item and hash_ not in keys: |                         if item and hash_ not in keys: | ||||||
|                         resumed = hashDBRetrieve(hash_) |                             resumed = hashDBRetrieve(hash_) | ||||||
|                         if not resumed: |                             if not resumed: | ||||||
|                             attack_info.append(item) |                                 attack_info.append(item) | ||||||
|                             user_hash.append(item[0]) |                                 user_hash.append(item[0]) | ||||||
|                         else: |                             else: | ||||||
|                             infoMsg = "resuming password '%s' for hash '%s'" % (resumed, hash_) |                                 infoMsg = "resuming password '%s' for hash '%s'" % (resumed, hash_) | ||||||
|                             if user and not user.startswith(DUMMY_USER_PREFIX): |                                 if user and not user.startswith(DUMMY_USER_PREFIX): | ||||||
|                                 infoMsg += " for user '%s'" % user |                                     infoMsg += " for user '%s'" % user | ||||||
|                             logger.info(infoMsg) |                                 logger.info(infoMsg) | ||||||
|                             resumes.append((user, hash_, resumed)) |                                 resumes.append((user, hash_, resumed)) | ||||||
|                         keys.add(hash_) |                             keys.add(hash_) | ||||||
|  | 
 | ||||||
|  |                     except (binascii.Error, IndexError): | ||||||
|  |                         pass | ||||||
| 
 | 
 | ||||||
|         if not attack_info: |         if not attack_info: | ||||||
|             continue |             continue | ||||||
|  | @ -875,7 +914,7 @@ def dictionaryAttack(attack_dict): | ||||||
|             while not kb.wordlists: |             while not kb.wordlists: | ||||||
| 
 | 
 | ||||||
|                 # the slowest of all methods hence smaller default dict |                 # the slowest of all methods hence smaller default dict | ||||||
|                 if hash_regex in (HASH.ORACLE_OLD, HASH.WORDPRESS): |                 if hash_regex in (HASH.ORACLE_OLD,): | ||||||
|                     dictPaths = [paths.SMALL_DICT] |                     dictPaths = [paths.SMALL_DICT] | ||||||
|                 else: |                 else: | ||||||
|                     dictPaths = [paths.WORDLIST] |                     dictPaths = [paths.WORDLIST] | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user