diff --git a/CHANGELOG b/CHANGELOG index 0cf28de9..df9c7489 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,9 +1,18 @@ +LaZagne 0.9 (01/07/2015) +- Only Windows + * Fix Opera bug (thanks to rolandstarke) + * Fix encoding error for generic network passwords + +- For Windows / Linux + * Version number available from the main menu (before: Lazagne all --version => now: Lazagne --version) + * spelling mistake corrected + LaZagne 0.8 (11/06/2015) - Only Linux * /etc/shadow modules (dictionary attack on hash) - For Windows / Linux - * management of the following options "-path" (for dictionary attack) and "-b" (for bruteforce attack) in a different way. Used as general options and not implemented by module. Using the same option, the file will be used by different modules; example: to find the mozilla masterpassword, the unix system password (from the hash), used by skype (for windows), etc. + * Management of the following options "-path" (for dictionary attack) and "-b" (for bruteforce attack) in a different way. Used as general options and not implemented by module. Using the same option, the file will be used by different modules; example: to find the mozilla masterpassword, the unix system password (from the hash), used by skype (for windows), etc. LaZagne 0.71 (04/06/2015) - Only Linux diff --git a/Linux/src/LaZagne.py b/Linux/src/LaZagne.py index cbc7c1ab..d43cdac5 100644 --- a/Linux/src/LaZagne.py +++ b/Linux/src/LaZagne.py @@ -124,14 +124,14 @@ def error(self, message): sys.exit(2) parser = MyParser() +parser.add_argument('--version', action='version', version='Version ' + str(constant.CURRENT_VERSION), help='laZagne version') # ------------------------------------------- Permanent options ------------------------------------------- # Version and verbosity PPoptional = argparse.ArgumentParser(add_help=False,formatter_class=lambda prog: argparse.HelpFormatter(prog, max_help_position=constant.MAX_HELP_POSITION)) PPoptional._optionals.title = 'optional arguments' PPoptional.add_argument('-v', dest='verbose', action='count', default=0, help='increase verbosity level') -PPoptional.add_argument('--version', action='version', version='Version ' + str(constant.CURRENT_VERSION), help='laZagne version') -PPoptional.add_argument('-path', dest='path', action= 'store', help = 'path of a file used for dictionnary file') +PPoptional.add_argument('-path', dest='path', action= 'store', help = 'path of a file used for dictionary file') PPoptional.add_argument('-b', dest='bruteforce', action= 'store', help = 'number of character to brute force') # Output diff --git a/Linux/src/config/constant.py b/Linux/src/config/constant.py index dca92664..cbafcb2a 100644 --- a/Linux/src/config/constant.py +++ b/Linux/src/config/constant.py @@ -2,7 +2,7 @@ class constant(): folder_name = 'results' MAX_HELP_POSITION = 27 - CURRENT_VERSION = 0.8 + CURRENT_VERSION = 0.9 output = None file_logger = None verbose = False diff --git a/Linux/src/softwares/browsers/mozilla.py b/Linux/src/softwares/browsers/mozilla.py index c3956622..c40bd5da 100644 --- a/Linux/src/softwares/browsers/mozilla.py +++ b/Linux/src/softwares/browsers/mozilla.py @@ -82,7 +82,7 @@ class Mozilla(ModuleInfo): # b = brute force attack # m = manually # d = default list - # a = dictionnary attack + # a = dictionary attack def __init__(self, isThunderbird = False): @@ -90,7 +90,7 @@ def __init__(self, isThunderbird = False): self.toCheck = [] self.manually_pass = None - self.dictionnary_path = None + self.dictionary_path = None self.number_toStop = 0 self.key3 = '' @@ -122,7 +122,7 @@ def manage_advanced_options(self): self.toCheck.append('m') if constant.path: - self.dictionnary_path = constant.path + self.dictionary_path = constant.path self.toCheck.append('a') if constant.bruteforce: @@ -349,19 +349,19 @@ def found_masterpassword(self): else: print_debug('WARNING', 'The Master password entered is not correct') - # dictionnary attack + # dictionary attack if 'a' in self.toCheck: try: - pass_file = open(self.dictionnary_path, 'r') + 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.dictionnary_path)) + print_debug('ERROR', 'Unable to open passwords file: %s' % str(self.dictionary_path)) return False pass_file.close() - print_debug('ATTACK', 'Dictionnary Attack !!! (%s words)' % str(num_lines)) + print_debug('ATTACK', 'Dictionary Attack !!! (%s words)' % str(num_lines)) try: - with open(self.dictionnary_path) as f: + 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()) @@ -369,11 +369,11 @@ def found_masterpassword(self): except (KeyboardInterrupt, SystemExit): print 'INTERRUPTED!' - print_debug('DEBUG', 'Dictionnary attack 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 dictionnary attack') + print_debug('WARNING', 'The Master password has not been found using the dictionary attack') # 500 most used passwords if 'd' in self.toCheck: @@ -405,7 +405,7 @@ def found_masterpassword(self): return w.strip() except (KeyboardInterrupt, SystemExit): print 'INTERRUPTED!' - print_debug('INFO', 'Dictionnary attack interrupted') + print_debug('INFO', 'Dictionary attack interrupted') except Exception,e: print_debug('DEBUG', '{0}'.format(e)) diff --git a/Linux/src/softwares/sysadmin/env_variable.py b/Linux/src/softwares/sysadmin/env_variable.py index 898127aa..a2eaa3d6 100644 --- a/Linux/src/softwares/sysadmin/env_variable.py +++ b/Linux/src/softwares/sysadmin/env_variable.py @@ -51,7 +51,7 @@ def run(self): # write credentials into a text file if len(values) != 0: # print the results - print_output('Environnement variables', pwdFound) + print_output('Environment variables', pwdFound) else: print_debug('INFO', 'No passwords stored in the environment variables.') diff --git a/Linux/src/softwares/sysadmin/shadow.py b/Linux/src/softwares/sysadmin/shadow.py index 37930d05..5776afde 100644 --- a/Linux/src/softwares/sysadmin/shadow.py +++ b/Linux/src/softwares/sysadmin/shadow.py @@ -19,14 +19,14 @@ def __init__(self): self.pwdFound = [] # used for dictionary attack, if user specify a specific file - def get_dic(self, dictionnary_path): + def get_dic(self, dictionary_path): words = [] - if dictionnary_path: + if dictionary_path: try: - dicFile = open (dictionnary_path,'r') + dicFile = open (dictionary_path,'r') except Exception,e: print_debug('DEBUG', '{0}'.format(e)) - print_debug('ERROR', 'Unable to open passwords file: %s' % str(self.dictionnary_path)) + print_debug('ERROR', 'Unable to open passwords file: %s' % str(self.dictionary_path)) return [] for word in dicFile.readlines(): @@ -40,7 +40,7 @@ def attack(self, user, cryptPwd): # add the user on the list to found weak password (login equal password) dic.insert(0, user) - # file for dictionnary attack entered + # file for dictionary attack entered if constant.path: if os.path.exists(constant.path): dic = self.get_dic(constant.path) @@ -71,7 +71,7 @@ def attack(self, user, cryptPwd): realSalt = "$" + hashType + "$" + salt + "$" # -------------------------- Dictionary attack -------------------------- - print_debug('INFO', 'Dictionnary Attack on the hash !!! ') + print_debug('INFO', 'Dictionary Attack on the hash !!! ') try: for word in dic: try: @@ -87,7 +87,7 @@ def attack(self, user, cryptPwd): return except (KeyboardInterrupt, SystemExit): print 'INTERRUPTED!' - print_debug('DEBUG', 'Dictionnary attack interrupted') + print_debug('DEBUG', 'Dictionary attack interrupted') except Exception,e: print_debug('DEBUG', '{0}'.format(e)) diff --git a/Linux/standalone/32bits/LaZagne-32bits.REMOVED.git-id b/Linux/standalone/32bits/LaZagne-32bits.REMOVED.git-id index 48a16767..79fdce4d 100644 --- a/Linux/standalone/32bits/LaZagne-32bits.REMOVED.git-id +++ b/Linux/standalone/32bits/LaZagne-32bits.REMOVED.git-id @@ -1 +1 @@ -e0f04fc22887ac0c6bcaab0f7d07bca9a61c55ae \ No newline at end of file +d4d0b8da741cf3d0b17f81558aab61207b199deb \ No newline at end of file diff --git a/Linux/standalone/64bits/LaZagne-64bits.REMOVED.git-id b/Linux/standalone/64bits/LaZagne-64bits.REMOVED.git-id index 58e710cf..4e9846ec 100644 --- a/Linux/standalone/64bits/LaZagne-64bits.REMOVED.git-id +++ b/Linux/standalone/64bits/LaZagne-64bits.REMOVED.git-id @@ -1 +1 @@ -cd51611a2a210e3162d27b35de4b49f5daa21900 \ No newline at end of file +2a274fdcb8f1abc7e73a6310461b4fcee0f4ac0e \ No newline at end of file diff --git a/README.md b/README.md index b495135c..9cbfd821 100644 --- a/README.md +++ b/README.md @@ -10,9 +10,15 @@ At this moment, it supports 22 Programs on Microsoft Windows and 12 on a Linux/U

The LaZagne project

+Standalones +---- +Standalones are now available here: https://github.com/AlessandroZ/LaZagne/releases/tag/0.9 Usage ---- +* Retrieve version + * cmd: laZagne.exe --version + * Launch all modules * cmd: laZagne.exe all @@ -29,6 +35,12 @@ Usage * Write all passwords found into a file (-w options) * cmd: laZagne.exe all -w +* Use a file for dictionary attacks (used only when it's necessary: mozilla masterpassword, system hahes, etc.). The file has to be a wordlist in cleartext (no rainbow), it has not been optmized to be fast but could useful for basic passwords. + * cmd: laZagne.exe all -path file.txt + +* Change verbosity mode (2 different levels) + * cmd: laZagne.exe all -vv + __Note: For wifi passwords \ Windows Secrets, launch it with administrator privileges (UAC Authentication / sudo)__ Supported software diff --git a/Windows/src/LaZagne/config/constant.py b/Windows/src/LaZagne/config/constant.py index e276942c..f7f75e8c 100644 --- a/Windows/src/LaZagne/config/constant.py +++ b/Windows/src/LaZagne/config/constant.py @@ -2,7 +2,7 @@ class constant(): folder_name = 'results' MAX_HELP_POSITION = 27 - CURRENT_VERSION = 0.8 + CURRENT_VERSION = 0.9 output = None file_logger = None diff --git a/Windows/src/LaZagne/laZagne.py b/Windows/src/LaZagne/laZagne.py index eeeccd04..1677e8c9 100644 --- a/Windows/src/LaZagne/laZagne.py +++ b/Windows/src/LaZagne/laZagne.py @@ -123,14 +123,14 @@ def error(self, message): sys.exit(2) parser = MyParser() +parser.add_argument('--version', action='version', version='Version ' + str(constant.CURRENT_VERSION), help='laZagne version') # ------------------------------------------- Permanent options ------------------------------------------- # Version and verbosity PPoptional = argparse.ArgumentParser(add_help=False,formatter_class=lambda prog: argparse.HelpFormatter(prog, max_help_position=constant.MAX_HELP_POSITION)) PPoptional._optionals.title = 'optional arguments' PPoptional.add_argument('-v', dest='verbose', action='count', default=0, help='increase verbosity level') -PPoptional.add_argument('--version', action='version', version='Version ' + str(constant.CURRENT_VERSION), help='laZagne version') -PPoptional.add_argument('-path', dest='path', action= 'store', help = 'path of a file used for dictionnary file') +PPoptional.add_argument('-path', dest='path', action= 'store', help = 'path of a file used for dictionary file') PPoptional.add_argument('-b', dest='bruteforce', action= 'store', help = 'number of character to brute force') # Output diff --git a/Windows/src/LaZagne/softwares/browsers/mozilla.py b/Windows/src/LaZagne/softwares/browsers/mozilla.py index 0dfa60e5..db40c595 100644 --- a/Windows/src/LaZagne/softwares/browsers/mozilla.py +++ b/Windows/src/LaZagne/softwares/browsers/mozilla.py @@ -82,7 +82,7 @@ class Mozilla(ModuleInfo): # b = brute force attack # m = manually # d = default list - # a = dictionnary attack + # a = dictionary attack def __init__(self, isThunderbird = False): @@ -90,7 +90,7 @@ def __init__(self, isThunderbird = False): self.toCheck = [] self.manually_pass = None - self.dictionnary_path = None + self.dictionary_path = None self.number_toStop = None self.key3 = '' @@ -126,7 +126,7 @@ def manage_advanced_options(self): self.toCheck.append('m') if constant.path: - self.dictionnary_path = constant.path + self.dictionary_path = constant.path self.toCheck.append('a') if constant.bruteforce: @@ -353,19 +353,19 @@ def found_masterpassword(self): else: print_debug('WARNING', 'The Master password entered is not correct') - # dictionnary attack + # dictionary attack if 'a' in self.toCheck: try: - pass_file = open(self.dictionnary_path, 'r') + 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.dictionnary_path)) + print_debug('ERROR', 'Unable to open passwords file: %s' % str(self.dictionary_path)) return False pass_file.close() print_debug('ATTACK', 'Dictionnary Attack !!! (%s words)' % str(num_lines)) try: - with open(self.dictionnary_path) as f: + 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()) @@ -377,7 +377,7 @@ def found_masterpassword(self): except Exception,e: print_debug('DEBUG', '{0}'.format(e)) - print_debug('WARNING', 'The Master password has not been found using the dictionnary attack') + print_debug('WARNING', 'The Master password has not been found using the dictionary attack') # 500 most used passwords if 'd' in self.toCheck: diff --git a/Windows/src/LaZagne/softwares/chats/skype.py b/Windows/src/LaZagne/softwares/chats/skype.py index 66f64a2b..90da9d1d 100644 --- a/Windows/src/LaZagne/softwares/chats/skype.py +++ b/Windows/src/LaZagne/softwares/chats/skype.py @@ -76,14 +76,14 @@ def get_md5_hash(self, enc_hex, key): return binascii.hexlify(tmp) # used for dictionary attack, if user specify a specific file - def get_dic_file(self, dictionnary_path): + def get_dic_file(self, dictionary_path): words = [] - if dictionnary_path: + if dictionary_path: try: - dicFile = open (dictionnary_path,'r') + dicFile = open (dictionary_path,'r') except Exception,e: print_debug('DEBUG', '{0}'.format(e)) - print_debug('ERROR', 'Unable to open passwords file: %s' % str(dictionnary_path)) + print_debug('ERROR', 'Unable to open passwords file: %s' % str(dictionary_path)) return [] for word in dicFile.readlines(): diff --git a/Windows/src/LaZagne/softwares/windows/network.py b/Windows/src/LaZagne/softwares/windows/network.py index f6eef4a1..7507ac0f 100644 --- a/Windows/src/LaZagne/softwares/windows/network.py +++ b/Windows/src/LaZagne/softwares/windows/network.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- import struct, platform, win32cred from ctypes import * from ctypes.wintypes import DWORD @@ -91,7 +92,7 @@ def run(self): values['Username'] = i['UserName'] try: - values['Password'] = pwd.decode('utf16') + values['Password'] = pwd.decode('utf16').encode('utf-8') except Exception,e: print_debug('DEBUG', '{0}'.format(e)) values['INFO'] = 'Error decoding the password' diff --git a/Windows/src/LaZagne/softwares/windows/secretsdump.py b/Windows/src/LaZagne/softwares/windows/secretsdump.py index 88d6525c..939c1722 100644 --- a/Windows/src/LaZagne/softwares/windows/secretsdump.py +++ b/Windows/src/LaZagne/softwares/windows/secretsdump.py @@ -1073,14 +1073,14 @@ def bruteFortce_hash(self, hash): return False # used for dictionary attack, if user specify a specific file - def get_dic(self, dictionnary_path): + def get_dic(self, dictionary_path): words = [] - if dictionnary_path: + if dictionary_path: try: - dicFile = open (dictionnary_path,'r') + dicFile = open (dictionary_path,'r') except Exception,e: print_debug('DEBUG', '{0}'.format(e)) - print_debug('ERROR', 'Unable to open passwords file: %s' % str(dictionnary_path)) + print_debug('ERROR', 'Unable to open passwords file: %s' % str(dictionary_path)) return [] for word in dicFile.readlines():