Skip to content

Commit

Permalink
manage passwords using unicode
Browse files Browse the repository at this point in the history
  • Loading branch information
AlessandroZ committed Aug 31, 2017
1 parent aea4929 commit ee9b295
Show file tree
Hide file tree
Showing 5 changed files with 153 additions and 127 deletions.
126 changes: 70 additions & 56 deletions Windows/laZagne.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,9 @@
from lazagne.softwares.browsers.mozilla import Mozilla

# Configuration
from lazagne.config.write_output import write_header, write_footer, print_footer, print_debug, parseJsonResultToBuffer, print_output
from lazagne.config.write_output import parseJsonResultToBuffer, print_debug, StandartOutput
from lazagne.config.changePrivileges import ListSids, rev2self, impersonate_sid_long_handle
from lazagne.config.manageModules import get_categories, get_modules
from lazagne.config.header import Header
from lazagne.config.constant import *
import argparse
import time, sys, os
Expand All @@ -27,6 +26,9 @@
import traceback
import ctypes

# object used to manage the output / write functions (cf write_output file)
constant.st = StandartOutput()

# Tab containing all passwords
stdoutRes = []

Expand Down Expand Up @@ -59,13 +61,17 @@ def output():
# constant.file_name_results = 'credentials' # let the choice of the name to the user

if constant.output != 'json':
write_header()
constant.st.write_header()

# Remove all unecessary variables
del args['write_normal']
del args['write_json']
del args['write_all']

def quiet_mode():
if args['quiet']:
constant.quiet_mode = True

def verbosity():
# Write on the console + debug file
if args['verbose']==0: level=logging.CRITICAL
Expand Down Expand Up @@ -113,9 +119,9 @@ def launch_module(module, need_high_privileges=False, need_system_privileges=Fal
continue

try:
Header().title_info(i.capitalize()) # print title
pwdFound = module[i].run(i.capitalize()) # run the module
print_output(i.capitalize(), pwdFound) # print the results
constant.st.title_info(i.capitalize()) # print title
pwdFound = module[i].run(i.capitalize()) # run the module
constant.st.print_output(i.capitalize(), pwdFound) # print the results

# return value - not used but needed
yield True, i.capitalize(), pwdFound
Expand Down Expand Up @@ -146,6 +152,14 @@ def manage_advanced_options():
if 'historic' in args:
constant.ie_historic = args['historic']

if 'drive' in args:
drive = args['drive'].upper()
# drive letter between A and Z
if drive != constant.drive and len(drive) == 1 and (ord(drive) >= 50 and ord(drive) <= 90):
constant.drive = drive
else:
print_debug('ERROR', 'Drive letter should be a letter between A and Z')

# Run only one module
def runModule(category_choosed, need_high_privileges=False, need_system_privileges=False, not_need_to_be_in_env=False, cannot_be_impersonate_using_tokens=False):
global category
Expand All @@ -159,27 +173,31 @@ def runModule(category_choosed, need_high_privileges=False, need_system_privileg

# write output to file (json and txt files)
def write_in_file(result):
try:
if constant.output == 'json' or constant.output == 'all':
# Human readable Json format
if constant.output == 'json' or constant.output == 'all':
try:
# Human readable Json format
prettyJson = json.dumps(result, sort_keys=True, indent=4, separators=(',', ': '))
with open(constant.folder_name + os.sep + constant.file_name_results + '.json', 'w+') as f:
f.write(prettyJson.encode('utf-8', errors='replace'))
print '[+] File written: ' + constant.folder_name + os.sep + constant.file_name_results + '.json'
with open(constant.folder_name + os.sep + constant.file_name_results + '.json', 'a+b') as f:
f.write(prettyJson.decode('unicode-escape').encode('UTF-8'))
constant.st.do_print('[+] File written: ' + constant.folder_name + os.sep + constant.file_name_results + '.json')
except Exception as e:
print_debug('ERROR', 'Error writing the output file: %s' % e)

if constant.output == 'txt' or constant.output == 'all':
if constant.output == 'txt' or constant.output == 'all':
try:
with open(constant.folder_name + os.sep + constant.file_name_results + '.txt', 'a+b') as f:
f.write(parseJsonResultToBuffer(result))
write_footer()
print '[+] File written: ' + constant.folder_name + os.sep + constant.file_name_results + '.txt'
a = parseJsonResultToBuffer(result)
f.write(a.encode("UTF-8"))
constant.st.write_footer()
constant.st.do_print('[+] File written: ' + constant.folder_name + os.sep + constant.file_name_results + '.txt')
except Exception as e:
print_debug('ERROR', 'Error writing the output file: %s' % e)

except Exception as e:
print_debug('ERROR', 'Error writing the output file: %s' % e)

# Get user list to retrieve their passwords
def get_user_list_on_filesystem(impersonated_user=[]):
# Check users existing on the system (get only directories)
all_users = os.walk('C:\\Users').next()[1]
all_users = os.walk('%s:\\Users' % constant.drive).next()[1]

# Remove default users
for user in ['All Users', 'Default User', 'Default', 'Public']:
Expand All @@ -193,37 +211,27 @@ def get_user_list_on_filesystem(impersonated_user=[]):

return all_users

def set_env_variables(user = getpass.getuser(), toImpersonate = False):
def set_env_variables(user=getpass.getuser(), toImpersonate=False):
constant.username = user
if not toImpersonate:
constant.profile['APPDATA'] = os.environ.get('APPDATA', 'C:\\Users\\%s\\AppData\\Roaming\\' % user)
constant.profile['USERPROFILE'] = os.environ.get('USERPROFILE', 'C:\\Users\\%s\\' % user)
constant.profile['HOMEDRIVE'] = os.environ.get('HOMEDRIVE', 'C:')
constant.profile['HOMEPATH'] = os.environ.get('HOMEPATH', 'C:\\Users\\%s' % user)
constant.profile['ALLUSERSPROFILE'] = os.environ.get('ALLUSERSPROFILE', 'C:\\ProgramData')
constant.profile['COMPOSER_HOME'] = os.environ.get('COMPOSER_HOME', 'C:\\Users\\%s\\AppData\\Roaming\\Composer\\' % user)
constant.profile['LOCALAPPDATA'] = os.environ.get('LOCALAPPDATA', 'C:\\Users\\%s\\AppData\\Local' % user)
constant.profile['APPDATA'] = os.environ.get('APPDATA', '%s:\\Users\\%s\\AppData\\Roaming\\' % (constant.drive, user))
constant.profile['USERPROFILE'] = os.environ.get('USERPROFILE', '%s:\\Users\\%s\\' % (constant.drive, user))
constant.profile['HOMEDRIVE'] = os.environ.get('HOMEDRIVE', '%s:' % constant.drive)
constant.profile['HOMEPATH'] = os.environ.get('HOMEPATH', '%s:\\Users\\%s' % (constant.drive, user))
constant.profile['ALLUSERSPROFILE'] = os.environ.get('ALLUSERSPROFILE', '%s:\\ProgramData' % constant.drive)
constant.profile['COMPOSER_HOME'] = os.environ.get('COMPOSER_HOME', '%s:\\Users\\%s\\AppData\\Roaming\\Composer\\' % (constant.drive, user))
constant.profile['LOCALAPPDATA'] = os.environ.get('LOCALAPPDATA', '%s:\\Users\\%s\\AppData\\Local' % (constant.drive, user))
else:
constant.profile['APPDATA'] = 'C:\\Users\\%s\\AppData\\Roaming\\' % user
constant.profile['USERPROFILE'] = 'C:\\Users\\%s\\' % user
constant.profile['HOMEPATH'] = 'C:\\Users\\%s' % user
constant.profile['COMPOSER_HOME'] = 'C:\\Users\\%s\\AppData\\Roaming\\Composer\\' % user
constant.profile['LOCALAPPDATA'] = 'C:\\Users\\%s\\AppData\\Local' % user

# Used to print help menu when an error occurs
class MyParser(argparse.ArgumentParser):
def error(self, message):
sys.stderr.write('error: %s\n\n' % message)
self.print_help()
sys.exit(2)
constant.profile['APPDATA'] = '%s:\\Users\\%s\\AppData\\Roaming\\' % (constant.drive, user)
constant.profile['USERPROFILE'] = '%s:\\Users\\%s\\' % (constant.drive, user)
constant.profile['HOMEPATH'] = '%s:\\Users\\%s' % (constant.drive, user)
constant.profile['COMPOSER_HOME'] = '%s:\\Users\\%s\\AppData\\Roaming\\Composer\\' % (constant.drive, user)
constant.profile['LOCALAPPDATA'] = '%s:\\Users\\%s\\AppData\\Local' % (constant.drive, user)

# print user when verbose mode is enabled (without verbose mode the user is printed on the write_output python file)
def print_user(user):
if logging.getLogger().isEnabledFor(logging.INFO) == True:
try:
print '\n\n########## User: %s ##########\n' % user
except:
print '\n\n########## User: %s ##########\n' % user.encode('utf-8', errors='replace')
constant.st.print_user(user)

def clean_temporary_files():
# try to remove all temporary files
Expand All @@ -238,7 +246,7 @@ def runLaZagne(category_choosed='all'):

# ------ Part used for user impersonation ------

current_user = getpass.getuser().encode('utf-8', errors='ignore')
current_user = getpass.getuser()
if not current_user.endswith('$'):
constant.finalResults = {'User': current_user}
print_user(current_user)
Expand Down Expand Up @@ -298,7 +306,7 @@ def runLaZagne(category_choosed='all'):
# Ready to check for all users remaining
all_users = get_user_list_on_filesystem(impersonated_user)
for user in all_users:
set_env_variables(user, toImpersonate = True)
set_env_variables(user, toImpersonate=True)
print_user(user)

# Fix value by default for user environnment (appdata and userprofile)
Expand All @@ -312,22 +320,22 @@ def runLaZagne(category_choosed='all'):

if __name__ == '__main__':

# Print the title
Header().first_title()

parser = MyParser()
parser = argparse.ArgumentParser(description=constant.st.banner, formatter_class=argparse.RawTextHelpFormatter)
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 = 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('-quiet', dest='quiet', action= 'store_true', default=False, help = 'quiet mode: nothing is printed to the output')
PPoptional.add_argument('-drive', dest='drive', action= 'store', default='C', help = 'drive to perform the test (default: C)')
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
PWrite = argparse.ArgumentParser(add_help=False,formatter_class=lambda prog: argparse.HelpFormatter(prog, max_help_position=constant.MAX_HELP_POSITION))
PWrite = argparse.ArgumentParser(add_help=False, formatter_class=lambda prog: argparse.HelpFormatter(prog, max_help_position=constant.MAX_HELP_POSITION))
PWrite._optionals.title = 'Output'
PWrite.add_argument('-oN', dest='write_normal', action='store_true', help = 'output file in a readable format')
PWrite.add_argument('-oJ', dest='write_json', action='store_true', help = 'output file in a json format')
Expand All @@ -336,7 +344,7 @@ def runLaZagne(category_choosed='all'):
# ------------------------------------------- Add options and suboptions to all modules -------------------------------------------
all_subparser = []
for c in category:
category[c]['parser'] = argparse.ArgumentParser(add_help=False,formatter_class=lambda prog: argparse.HelpFormatter(prog, max_help_position=constant.MAX_HELP_POSITION))
category[c]['parser'] = argparse.ArgumentParser(add_help=False, formatter_class=lambda prog: argparse.HelpFormatter(prog, max_help_position=constant.MAX_HELP_POSITION))
category[c]['parser']._optionals.title = category[c]['help']

# Manage options
Expand Down Expand Up @@ -382,6 +390,11 @@ def runLaZagne(category_choosed='all'):
arguments = parser.parse_args()
category_choosed = args['auditType']

quiet_mode()

# Print the title
constant.st.first_title()

# Define constant variables
output()
verbosity()
Expand All @@ -394,7 +407,8 @@ def runLaZagne(category_choosed='all'):

clean_temporary_files()
write_in_file(stdoutRes)
print_footer()

elapsed_time = time.time() - start_time
print '\nelapsed time = ' + str(elapsed_time)

if not constant.quiet_mode:
constant.st.print_footer()
elapsed_time = time.time() - start_time
print '\nelapsed time = ' + str(elapsed_time)
57 changes: 31 additions & 26 deletions Windows/lazagne/config/constant.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,43 +3,48 @@
date = time.strftime("%d%m%Y_%H%M%S")

class constant():
folder_name = 'results_{current_time}'.format(current_time=date)
file_name_results = 'credentials' # the extention is added depending on the user output choice
MAX_HELP_POSITION = 27
CURRENT_VERSION = '2.1'
output = None
file_logger = None

folder_name = 'results_{current_time}'.format(current_time=date)
file_name_results = 'credentials' # the extention is added depending on the user output choice
MAX_HELP_POSITION = 27
CURRENT_VERSION = '2.3'
output = None
file_logger = None
# jitsi options
jitsi_masterpass = None
jitsi_masterpass = None

# mozilla options
manually = None
path = None
bruteforce = None
specific_path = None
manually = None
path = None
bruteforce = None
specific_path = None

# ie options
ie_historic = None
ie_historic = None

# total password found
nbPasswordFound = 0
passwordFound = []
nbPasswordFound = 0
passwordFound = []

finalResults = {}
finalResults = {}

profile = {
'APPDATA': '',
'USERPROFILE': '',
'HOMEDRIVE': '',
'HOMEPATH': '',
'APPDATA' : '',
'USERPROFILE' : '',
'HOMEDRIVE' : '',
'HOMEPATH' : '',
'ALLUSERSPROFILE': '',
'COMPOSER_HOME': '',
'LOCALAPPDATA': ''
'COMPOSER_HOME' : '',
'LOCALAPPDATA' : ''
}
username = ''
username = ''

keepass = {}
hives = []

checkUnattended = False

keepass = {}
hives = []
quiet_mode = False

checkUnattended = False
# standart output
st = None
drive = 'C'
Loading

0 comments on commit ee9b295

Please sign in to comment.