Skip to content

Commit 5b77505

Browse files
committed
fix #154 and #156
Former-commit-id: 2c95f39 [formerly 2c95f39 [formerly 2c95f39 [formerly 39a9859]]] Former-commit-id: da18c8acb5e16ee018abbe8b60169a5db8c0e054 Former-commit-id: 7e35d9d Former-commit-id: 7ae43cd
1 parent 3afb5fe commit 5b77505

33 files changed

+257
-282
lines changed

Windows/laZagne.py

Lines changed: 47 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ def manage_advanced_options():
156156
if 'historic' in args:
157157
constant.ie_historic = args['historic']
158158

159-
if 'drive' in args:
159+
if args['drive']:
160160
drive = args['drive'].upper()
161161
# drive letter between A and Z
162162
if drive != constant.drive:
@@ -201,37 +201,41 @@ def write_in_file(result):
201201

202202
# Get user list to retrieve their passwords
203203
def get_user_list_on_filesystem(impersonated_user=[]):
204+
204205
# Check users existing on the system (get only directories)
205-
all_users = os.walk('%s:\\Users' % constant.drive).next()[1]
206-
207-
# Remove default users
208-
for user in ['All Users', 'Default User', 'Default', 'Public']:
209-
if user in all_users:
210-
all_users.remove(user)
206+
user_path = u'%s:\\Users' % constant.drive
207+
all_users = []
208+
if os.path.exists(user_path):
209+
all_users = os.listdir(user_path)
210+
211+
# Remove default users
212+
for user in ['All Users', 'Default User', 'Default', 'Public', 'desktop.ini']:
213+
if user in all_users:
214+
all_users.remove(user)
211215

212-
# Removing user that have already been impersonated
213-
for imper_user in impersonated_user:
214-
if imper_user in all_users:
215-
all_users.remove(imper_user)
216+
# Removing user that have already been impersonated
217+
for imper_user in impersonated_user:
218+
if imper_user in all_users:
219+
all_users.remove(imper_user)
216220

217221
return all_users
218222

219223
def set_env_variables(user=getpass.getuser(), toImpersonate=False):
220224
constant.username = user
221225
if not toImpersonate:
222-
constant.profile['APPDATA'] = os.environ.get('APPDATA', '%s:\\Users\\%s\\AppData\\Roaming\\' % (constant.drive, user))
223-
constant.profile['USERPROFILE'] = os.environ.get('USERPROFILE', '%s:\\Users\\%s\\' % (constant.drive, user))
224-
constant.profile['HOMEDRIVE'] = os.environ.get('HOMEDRIVE', '%s:' % constant.drive)
225-
constant.profile['HOMEPATH'] = os.environ.get('HOMEPATH', '%s:\\Users\\%s' % (constant.drive, user))
226-
constant.profile['ALLUSERSPROFILE'] = os.environ.get('ALLUSERSPROFILE', '%s:\\ProgramData' % constant.drive)
227-
constant.profile['COMPOSER_HOME'] = os.environ.get('COMPOSER_HOME', '%s:\\Users\\%s\\AppData\\Roaming\\Composer\\' % (constant.drive, user))
228-
constant.profile['LOCALAPPDATA'] = os.environ.get('LOCALAPPDATA', '%s:\\Users\\%s\\AppData\\Local' % (constant.drive, user))
226+
constant.profile['APPDATA'] = unicode(os.environ.get('APPDATA', u'%s:\\Users\\%s\\AppData\\Roaming\\' % (constant.drive, user)))
227+
constant.profile['USERPROFILE'] = unicode(os.environ.get('USERPROFILE', u'%s:\\Users\\%s\\' % (constant.drive, user)))
228+
constant.profile['HOMEDRIVE'] = unicode(os.environ.get('HOMEDRIVE', u'%s:' % constant.drive))
229+
constant.profile['HOMEPATH'] = unicode(os.environ.get('HOMEPATH', u'%s:\\Users\\%s' % (constant.drive, user)))
230+
constant.profile['ALLUSERSPROFILE'] = unicode(os.environ.get('ALLUSERSPROFILE', u'%s:\\ProgramData' % constant.drive))
231+
constant.profile['COMPOSER_HOME'] = unicode(os.environ.get('COMPOSER_HOME', u'%s:\\Users\\%s\\AppData\\Roaming\\Composer\\' % (constant.drive, user)))
232+
constant.profile['LOCALAPPDATA'] = unicode(os.environ.get('LOCALAPPDATA', u'%s:\\Users\\%s\\AppData\\Local' % (constant.drive, user)))
229233
else:
230-
constant.profile['APPDATA'] = '%s:\\Users\\%s\\AppData\\Roaming\\' % (constant.drive, user)
231-
constant.profile['USERPROFILE'] = '%s:\\Users\\%s\\' % (constant.drive, user)
232-
constant.profile['HOMEPATH'] = '%s:\\Users\\%s' % (constant.drive, user)
233-
constant.profile['COMPOSER_HOME'] = '%s:\\Users\\%s\\AppData\\Roaming\\Composer\\' % (constant.drive, user)
234-
constant.profile['LOCALAPPDATA'] = '%s:\\Users\\%s\\AppData\\Local' % (constant.drive, user)
234+
constant.profile['APPDATA'] = u'%s:\\Users\\%s\\AppData\\Roaming\\' % (constant.drive, user)
235+
constant.profile['USERPROFILE'] = u'%s:\\Users\\%s\\' % (constant.drive, user)
236+
constant.profile['HOMEPATH'] = u'%s:\\Users\\%s' % (constant.drive, user)
237+
constant.profile['COMPOSER_HOME'] = u'%s:\\Users\\%s\\AppData\\Roaming\\Composer\\' % (constant.drive, user)
238+
constant.profile['LOCALAPPDATA'] = u'%s:\\Users\\%s\\AppData\\Local' % (constant.drive, user)
235239

236240
# print user when verbose mode is enabled (without verbose mode the user is printed on the write_output python file)
237241
def print_user(user):
@@ -247,7 +251,7 @@ def clean_temporary_files():
247251
except:
248252
pass
249253

250-
def runLaZagne(category_choosed='all'):
254+
def runLaZagne(category_choosed='all', check_specific_drive=False):
251255

252256
# ------ Part used for user impersonation ------
253257

@@ -256,7 +260,12 @@ def runLaZagne(category_choosed='all'):
256260
constant.finalResults = {'User': current_user}
257261
print_user(current_user)
258262
yield 'User', current_user
259-
set_env_variables()
263+
264+
if check_specific_drive:
265+
set_env_variables(toImpersonate=True)
266+
else:
267+
set_env_variables()
268+
260269
for r in runModule(category_choosed):
261270
yield r
262271
stdoutRes.append(constant.finalResults)
@@ -272,7 +281,7 @@ def runLaZagne(category_choosed='all'):
272281
# Not save the current user's SIDs
273282
if current_user != sid[3].split('\\', 1)[1]:
274283
impersonateUsers.setdefault(sid[3].split('\\', 1)[1], []).append(sid[2])
275-
284+
276285
for user in impersonateUsers:
277286
if 'service ' in user.lower() or ' service' in user.lower():
278287
continue
@@ -333,18 +342,18 @@ def runLaZagne(category_choosed='all'):
333342
PPoptional = argparse.ArgumentParser(add_help=False, formatter_class=lambda prog: argparse.HelpFormatter(prog, max_help_position=constant.MAX_HELP_POSITION))
334343
PPoptional._optionals.title = 'optional arguments'
335344
PPoptional.add_argument('-v', dest='verbose', action='count', default=0, help='increase verbosity level')
336-
PPoptional.add_argument('-quiet', dest='quiet', action= 'store_true', default=False, help = 'quiet mode: nothing is printed to the output')
337-
PPoptional.add_argument('-drive', dest='drive', action= 'store', default='C', help = 'drive to perform the test (default: C)')
338-
PPoptional.add_argument('-path', dest='path', action= 'store', help = 'path of a file used for dictionary file')
339-
PPoptional.add_argument('-b', dest='bruteforce', action= 'store', help = 'number of character to brute force')
345+
PPoptional.add_argument('-quiet', dest='quiet', action='store_true', default=False, help='quiet mode: nothing is printed to the output')
346+
PPoptional.add_argument('-drive', dest='drive', action='store', default=False, help='drive to perform the test (default: C)')
347+
PPoptional.add_argument('-path', dest='path', action='store', help='path of a file used for dictionary file')
348+
PPoptional.add_argument('-b', dest='bruteforce', action='store', help='number of character to brute force')
340349

341350

342351
# Output
343352
PWrite = argparse.ArgumentParser(add_help=False, formatter_class=lambda prog: argparse.HelpFormatter(prog, max_help_position=constant.MAX_HELP_POSITION))
344353
PWrite._optionals.title = 'Output'
345-
PWrite.add_argument('-oN', dest='write_normal', action='store_true', help = 'output file in a readable format')
346-
PWrite.add_argument('-oJ', dest='write_json', action='store_true', help = 'output file in a json format')
347-
PWrite.add_argument('-oA', dest='write_all', action='store_true', help = 'output file in all format')
354+
PWrite.add_argument('-oN', dest='write_normal', action='store_true', help='output file in a readable format')
355+
PWrite.add_argument('-oJ', dest='write_json', action='store_true', help='output file in a json format')
356+
PWrite.add_argument('-oA', dest='write_all', action='store_true', help='output file in all format')
348357

349358
# ------------------------------------------- Add options and suboptions to all modules -------------------------------------------
350359
all_subparser = []
@@ -395,6 +404,10 @@ def runLaZagne(category_choosed='all'):
395404
arguments = parser.parse_args()
396405
category_choosed = args['auditType']
397406

407+
check_specific_drive = False
408+
if args['drive']:
409+
check_specific_drive = True
410+
398411
quiet_mode()
399412

400413
# Print the title
@@ -407,7 +420,7 @@ def runLaZagne(category_choosed='all'):
407420

408421
start_time = time.time()
409422

410-
for r in runLaZagne(category_choosed):
423+
for r in runLaZagne(category_choosed, check_specific_drive=check_specific_drive):
411424
pass
412425

413426
clean_temporary_files()

Windows/lazagne/config/constant.py

Lines changed: 30 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -3,48 +3,49 @@
33
date = time.strftime("%d%m%Y_%H%M%S")
44

55
class constant():
6-
folder_name = 'results_{current_time}'.format(current_time=date)
7-
file_name_results = 'credentials' # the extention is added depending on the user output choice
8-
MAX_HELP_POSITION = 27
9-
CURRENT_VERSION = '2.3'
10-
output = None
11-
file_logger = None
6+
# folder_name = 'results_{current_time}'.format(current_time=date)
7+
folder_name = '.'
8+
file_name_results = 'credentials_{current_time}'.format(current_time=date) # the extention is added depending on the user output choice
9+
MAX_HELP_POSITION = 27
10+
CURRENT_VERSION = '2.3.1'
11+
output = None
12+
file_logger = None
1213
# jitsi options
13-
jitsi_masterpass = None
14+
jitsi_masterpass = None
1415

1516
# mozilla options
16-
manually = None
17-
path = None
18-
bruteforce = None
19-
specific_path = None
17+
manually = None
18+
path = None
19+
bruteforce = None
20+
specific_path = None
2021

2122
# ie options
22-
ie_historic = None
23+
ie_historic = None
2324

2425
# total password found
25-
nbPasswordFound = 0
26-
passwordFound = []
26+
nbPasswordFound = 0
27+
passwordFound = []
2728

28-
finalResults = {}
29+
finalResults = {}
2930

3031
profile = {
31-
'APPDATA' : '',
32-
'USERPROFILE' : '',
33-
'HOMEDRIVE' : '',
34-
'HOMEPATH' : '',
35-
'ALLUSERSPROFILE': '',
36-
'COMPOSER_HOME' : '',
37-
'LOCALAPPDATA' : ''
32+
'APPDATA' : u'',
33+
'USERPROFILE' : u'',
34+
'HOMEDRIVE' : u'',
35+
'HOMEPATH' : u'',
36+
'ALLUSERSPROFILE' : u'',
37+
'COMPOSER_HOME' : u'',
38+
'LOCALAPPDATA' : u''
3839
}
39-
username = ''
40+
username = u''
4041

41-
keepass = {}
42-
hives = []
42+
keepass = {}
43+
hives = []
4344

44-
checkUnattended = False
45+
checkUnattended = False
4546

46-
quiet_mode = False
47+
quiet_mode = False
4748

4849
# standart output
49-
st = None
50-
drive = 'C'
50+
st = None
51+
drive = u'C'

Windows/lazagne/softwares/browsers/chrome.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@ def __init__(self):
1414

1515
# main function
1616
def run(self, software_name = None):
17-
homedrive = constant.profile['HOMEDRIVE']
18-
homepath = constant.profile['HOMEPATH']
17+
homedrive = constant.profile['HOMEDRIVE']
18+
homepath = constant.profile['HOMEPATH']
1919

2020
# all possible path
2121
pathTab = [
22-
homedrive + homepath + '\\Local Settings\\Application Data\\Google\\Chrome\\User Data',
23-
homedrive + homepath + '\\AppData\\Local\\Google\\Chrome\\User Data',
22+
homedrive + homepath + u'\\Local Settings\\Application Data\\Google\\Chrome\\User Data',
23+
homedrive + homepath + u'\\AppData\\Local\\Google\\Chrome\\User Data',
2424
]
2525

2626
application_path = [p for p in pathTab if os.path.exists(p)]
@@ -33,8 +33,8 @@ def run(self, software_name = None):
3333

3434
# try to list all users profile
3535
profiles = []
36-
if os.path.exists(os.path.join(application_path, 'Local State')):
37-
with open(os.path.join(application_path, 'Local State')) as file:
36+
if os.path.exists(os.path.join(application_path, u'Local State')):
37+
with open(os.path.join(application_path, u'Local State')) as file:
3838
try:
3939
data = json.load(file)
4040
for profile in data['profile']['info_cache']:
@@ -47,15 +47,15 @@ def run(self, software_name = None):
4747

4848
pwdFound = []
4949
for profile in profiles:
50-
database_path = os.path.join(application_path, profile, 'Login Data')
50+
database_path = os.path.join(application_path, profile, u'Login Data')
5151
if not os.path.exists(database_path):
5252
print_debug('INFO', 'User database not found')
5353
continue
5454

5555
# Copy database before to query it (bypass lock errors)
5656
try:
57-
shutil.copy(database_path, os.path.join(os.getcwd(), 'tmp_db'))
58-
database_path = os.path.join(os.getcwd(), 'tmp_db')
57+
shutil.copy(database_path, os.path.join(unicode(os.getcwd()), u'tmp_db'))
58+
database_path = os.path.join(unicode(os.getcwd()), u'tmp_db')
5959
except Exception,e:
6060
print_debug('DEBUG', '{0}'.format(e))
6161
print_debug('ERROR', 'An error occured copying the database file')
@@ -91,7 +91,7 @@ def run(self, software_name = None):
9191
print_debug('DEBUG', '{0}'.format(e))
9292

9393
conn.close()
94-
if database_path.endswith('tmp_db'):
94+
if database_path.endswith(u'tmp_db'):
9595
os.remove(database_path)
9696

9797
return pwdFound

Windows/lazagne/softwares/browsers/coccoc.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@ def __init__(self):
1414

1515
# main function
1616
def run(self, software_name = None):
17-
homedrive = constant.profile['HOMEDRIVE']
18-
homepath = constant.profile['HOMEPATH']
17+
homedrive = constant.profile['HOMEDRIVE']
18+
homepath = constant.profile['HOMEPATH']
1919

2020
# all possible path
2121
pathTab = [
22-
homedrive + homepath + '\\Local Settings\\Application Data\\CocCoc\\Browser\\User Data',
23-
homedrive + homepath + '\\AppData\\Local\\CocCoc\\Browser\\User Data',
22+
homedrive + homepath + u'\\Local Settings\\Application Data\\CocCoc\\Browser\\User Data',
23+
homedrive + homepath + u'\\AppData\\Local\\CocCoc\\Browser\\User Data',
2424
]
2525

2626
application_path = [p for p in pathTab if os.path.exists(p)]
@@ -33,8 +33,8 @@ def run(self, software_name = None):
3333

3434
# try to list all users profile
3535
profiles = []
36-
if os.path.exists(os.path.join(application_path, 'Local State')):
37-
with open(os.path.join(application_path, 'Local State')) as file:
36+
if os.path.exists(os.path.join(application_path, u'Local State')):
37+
with open(os.path.join(application_path, u'Local State')) as file:
3838
try:
3939
data = json.load(file)
4040
for profile in data['profile']['info_cache']:
@@ -47,15 +47,15 @@ def run(self, software_name = None):
4747

4848
pwdFound = []
4949
for profile in profiles:
50-
database_path = os.path.join(application_path, profile, 'Login Data')
50+
database_path = os.path.join(application_path, profile, u'Login Data')
5151
if not os.path.exists(database_path):
5252
print_debug('INFO', 'User database not found')
5353
continue
5454

5555
# Copy database before to query it (bypass lock errors)
5656
try:
57-
shutil.copy(database_path, os.path.join(os.getcwd(), 'tmp_db'))
58-
database_path = os.path.join(os.getcwd(), 'tmp_db')
57+
shutil.copy(database_path, os.path.join(unicode(os.getcwd()), u'tmp_db'))
58+
database_path = os.path.join(unicode(os.getcwd()), u'tmp_db')
5959
except Exception,e:
6060
print_debug('DEBUG', '{0}'.format(e))
6161
print_debug('ERROR', 'An error occured copying the database file')
@@ -91,7 +91,7 @@ def run(self, software_name = None):
9191
print_debug('DEBUG', '{0}'.format(e))
9292

9393
conn.close()
94-
if database_path.endswith('tmp_db'):
94+
if database_path.endswith(u'tmp_db'):
9595
os.remove(database_path)
9696

9797
return pwdFound

0 commit comments

Comments
 (0)