def dictionary_attack(self, login, md5): wordlist = constant.password_found + get_dic() for word in wordlist: hash_ = hashlib.md5('%s\nskyper\n%s' % (login, word)).hexdigest() if hash_ == md5: return word return False
def dictionary_attack(self, user, crypt_pwd): dic = get_dic( ) # By default 500 most famous passwords are used for the dictionary attack dic.insert( 0, user ) # Add the user on the list to found weak password (login equal password) # Different possible hash type # ID | Method # -------------------------------------------------------------------------- # 1 | MD5 # 2 | Blowfish (not in mainline glibc; added in some Linux distributions) # 5 | SHA-256 (since glibc 2.7) # 6 | SHA-512 (since glibc 2.7) if '$' not in crypt_pwd: # Either malformed or old bcrypt password return False hash_type = crypt_pwd.split("$")[1] hash_algo = { '1': 'MD5', '2': 'Blowfish', '5': 'SHA-256', '6': 'SHA-512', # Used by all modern computers } # For Debug information for h_type in hash_algo: if h_type == hash_type: self.debug('[+] Hash type {algo} detected ...'.format( algo=hash_algo[h_type])) real_salt = '${hash_type}${salt}$'.format(hash_type=hash_type, salt=crypt_pwd.split("$")[2]) # -------------------------- Dictionary attack -------------------------- self.info('Dictionary Attack on the hash !!! ') try: for word in dic: try: crypt_word = crypt.crypt(word, real_salt) if crypt_word == crypt_pwd: return {'Login': user, 'Password': word} except Exception as e: pass except (KeyboardInterrupt, SystemExit): self.debug(u'Dictionary attack interrupted') return False
def run(self): user_hashes = [] if self.root_access(): major, minor = self.check_version() if major == 10 and (minor == 3 or minor == 4): for user in self.list_users(): self.info('User found: {user}'.format(user=user)) user_hash = self.get_user_hash_using_niutil(user) if user_hash: user_hashes.append(user_hash) if major == 10 and (minor == 5 or minor == 6): for user in self.list_users(): self.info('User found: {user}'.format(user=user)) user_hash = self.get_user_hash_using_dscl(user) if user_hash: user_hashes.append(user_hash) # TO DO: manage version 10.7 elif major == 10 and minor >= 8: user_names = [ plist.split(".")[0] for plist in os.listdir( u'/var/db/dslocal/nodes/Default/users/') if not plist.startswith(u'_') ] for username in user_names: user_hash = self.get_user_hash_from_plist(username) if user_hash: user_hashes.append(user_hash) # try to get the password in clear text passwords = constant.passwordFound # check if previous passwords are used as system password passwords.insert( 0, username ) # check for weak password (login equal password) if constant.user_password: passwords.insert(0, constant.user_password) found = self.dictionary_attack(username, passwords) # realize a dictionary attack using the 500 most famous passwords if constant.dictionary_attack and not found: dic = get_dic() dic.insert(0, self.username) self.dictionary_attack(username, dic) return ['__SYSTEM__', user_hashes]
def dictionary_attack(self, user, crypt_pwd): dic = get_dic() # By default 500 most famous passwords are used for the dictionary attack dic.insert(0, user) # Add the user on the list to found weak password (login equal password) # Different possible hash type # ID | Method # -------------------------------------------------------------------------- # 1 | MD5 # 2 | Blowfish (not in mainline glibc; added in some Linux distributions) # 5 | SHA-256 (since glibc 2.7) # 6 | SHA-512 (since glibc 2.7) if '$' not in crypt_pwd: # Either malformed or old bcrypt password return False hash_type = crypt_pwd.split("$")[1] hash_algo = { '1': 'MD5', '2': 'Blowfish', '5': 'SHA-256', '6': 'SHA-512', # Used by all modern computers } # For Debug information for h_type in hash_algo: if h_type == hash_type: self.debug('[+] Hash type {algo} detected ...'.format(algo=hash_algo[h_type])) real_salt = '${hash_type}${salt}$'.format(hash_type=hash_type, salt=crypt_pwd.split("$")[2]) # -------------------------- Dictionary attack -------------------------- self.info('Dictionary Attack on the hash !!! ') try: for word in dic: try: crypt_word = crypt.crypt(word, real_salt) if crypt_word == crypt_pwd: return { 'Login': user, 'Password': word } except Exception as e: pass except (KeyboardInterrupt, SystemExit): self.debug(u'Dictionary attack interrupted') return False
def brute_master_password(self, key_data, new_version=True): """ Try to find master_password doing a dictionary attack using the 500 most used passwords """ wordlist = constant.passwordFound + get_dic() num_lines = (len(wordlist) - 1) self.info(u'%d most used passwords !!! ' % num_lines) for word in wordlist: global_salt, master_password, entry_salt = self.is_master_password_correct(key_data=key_data, master_password=word.strip(), new_version=new_version) if master_password: self.info(u'Master password found: {}'.format(master_password)) return global_salt, master_password, entry_salt self.warning(u'No password has been found using the default list') return u'', u'', u''
def brute_master_password(self, key_data, new_version=True): """ Try to find master_password doing a dictionary attack using the 500 most used passwords """ wordlist = constant.password_found + get_dic() num_lines = (len(wordlist) - 1) self.info(u'%d most used passwords !!! ' % num_lines) for word in wordlist: global_salt, master_password, entry_salt = self.is_master_password_correct(key_data=key_data, master_password=word.strip(), new_version=new_version) if master_password: self.debug(u'Master password found: {}'.format(master_password)) return global_salt, master_password, entry_salt self.warning(u'No password has been found using the default list') return '', '', ''
def run(self): user_hashes = [] if self.root_access(): major, minor = self.check_version() if major == 10 and (minor == 3 or minor == 4): for user in self.list_users(): self.info('User found: {user}'.format(user=user)) user_hash = self.get_user_hash_using_niutil(user) if user_hash: user_hashes.append(user_hash) if major == 10 and (minor == 5 or minor == 6): for user in self.list_users(): self.info('User found: {user}'.format(user=user)) user_hash = self.get_user_hash_using_dscl(user) if user_hash: user_hashes.append(user_hash) # TO DO: manage version 10.7 elif major == 10 and minor >= 8: user_names = [plist.split(".")[0] for plist in os.listdir(u'/var/db/dslocal/nodes/Default/users/') if not plist.startswith(u'_')] for username in user_names: user_hash = self.get_user_hash_from_plist(username) if user_hash: user_hashes.append(user_hash) # try to get the password in clear text passwords = constant.passwordFound # check if previous passwords are used as system password passwords.insert(0, username) # check for weak password (login equal password) if constant.user_password: passwords.insert(0, constant.user_password) found = self.dictionary_attack(username, passwords) # realize a dictionary attack using the 500 most famous passwords if constant.dictionary_attack and not found: dic = get_dic() dic.insert(0, self.username) self.dictionary_attack(username, dic) return ['__SYSTEM__', user_hashes]
def dictionary_attack(self, crypt_pwd): dic = get_dic( ) # By default 500 most famous passwords are used for the dictionary attack if '$' not in crypt_pwd: # Either malformed or old bcrypt password return False hash_type = crypt_pwd.split("$")[1] hash_algo = { '1': 'MD5', } # For Debug information for h_type in hash_algo: if h_type == hash_type: self.debug('[+] Hash type {algo} detected ...'.format( algo=hash_algo[h_type])) real_salt = '${hash_type}${salt}$'.format(hash_type=hash_type, salt=crypt_pwd.split("$")[2]) # -------------------------- Dictionary attack -------------------------- self.info('Dictionary Attack on the hash !!! ') try: for word in dic: try: crypt_word = crypt.crypt(word, real_salt) if crypt_word == crypt_pwd: return word except Exception as e: pass except (KeyboardInterrupt, SystemExit): self.debug(u'Dictionary attack interrupted') return False
def dictionary_attack(self, login, md5): for word in get_dic(): hash_ = hashlib.md5('%s\nskyper\n%s' % (login, word)).hexdigest() if hash_ == md5: return word return False