Flake8 (#63)
* Flake8 - MyUsers * Flake8 - MySeatbelt (part 1) * Flake8 - MySeatbelt (part 2) * Flake8 - MySeatbelt (part 3) * fix Database --------- Co-authored-by: zblurx <thomas.seigneuret@login-securite.com>
This commit is contained in:
parent
0c27276c15
commit
a660ac7783
|
@ -265,26 +265,26 @@ def first_run(options):
|
|||
conn.close()
|
||||
|
||||
def seatbelt_thread(datas):
|
||||
global assets
|
||||
target,options, logger=datas
|
||||
logging.debug("[*] SeatBelt thread for {ip} Started".format(ip=target))
|
||||
global assets
|
||||
target,options, logger=datas
|
||||
logging.debug("[*] SeatBelt thread for {ip} Started".format(ip=target))
|
||||
|
||||
try:
|
||||
mysb = MySeatBelt(target,options,logger)
|
||||
if mysb.admin_privs:
|
||||
mysb.do_test()
|
||||
# mysb.run()
|
||||
#mysb.quit()
|
||||
else:
|
||||
logging.debug("[*] No ADMIN account on target {ip}".format(ip=target))
|
||||
try:
|
||||
mysb = MySeatBelt(target,options,logger)
|
||||
if mysb.admin_privs:
|
||||
mysb.do_test()
|
||||
# mysb.run()
|
||||
#mysb.close_smb()
|
||||
else:
|
||||
logging.debug("[*] No ADMIN account on target {ip}".format(ip=target))
|
||||
|
||||
#assets[target] = mysb.get_secrets()
|
||||
logging.debug("[*] SeatBelt thread for {ip} Ended".format(ip=target))
|
||||
except Exception as e:
|
||||
if logging.getLogger().level == logging.DEBUG:
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
logging.error(str(e))
|
||||
#assets[target] = mysb.get_secrets()
|
||||
logging.debug("[*] SeatBelt thread for {ip} Ended".format(ip=target))
|
||||
except Exception as e:
|
||||
if logging.getLogger().level == logging.DEBUG:
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
logging.error(str(e))
|
||||
|
||||
|
||||
def export_results_seatbelt(output_dir=''):
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,128 +1,162 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
"""
|
||||
MyUser module contain MyUser class.
|
||||
@Author: Pierre-Alexandre Vandewoestyne (@T00uF)
|
||||
"""
|
||||
|
||||
#!/usr/bin/env python
|
||||
# coding:utf-8
|
||||
'''
|
||||
PA Vandewoestyne
|
||||
'''
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
import errno, binascii, shutil
|
||||
import sys, json, operator
|
||||
from datetime import datetime
|
||||
from binascii import hexlify, unhexlify
|
||||
import logging
|
||||
import sys
|
||||
from donpapi.lib.toolbox import bcolors
|
||||
|
||||
|
||||
class MyUser:
|
||||
def __init__(self, username,logger,options):
|
||||
self.username = username
|
||||
self.options=options
|
||||
self.logging = logger
|
||||
self.sid = ''#un user peut avoir plusieurs SID ?
|
||||
self.type = 'LOCAL'#LOCAL,DOMAIN,MACHINE,MACHINE-USER
|
||||
self.type_validated = False
|
||||
self.appdata = ''
|
||||
self.password = ''
|
||||
self.domain = ''
|
||||
self.lmhash = ''
|
||||
self.nthash = ''
|
||||
self.aesKey = ''
|
||||
self.TGT = ''
|
||||
#self.masterkeys = {} # GUID_File: masterkey
|
||||
self.masterkeys_file = {}
|
||||
self.files = {}
|
||||
self.secrets = {}
|
||||
self.dpapi_machinekey: []
|
||||
self.dpapi_userkey: []
|
||||
self.share = None
|
||||
self.pwd = None
|
||||
self.is_adconnect = False
|
||||
"""MyUser class."""
|
||||
def __init__(self, username, logger, options):
|
||||
self.username = username
|
||||
self.options = options
|
||||
self.logging = logger
|
||||
self.sid = '' # A user may have many SID ?
|
||||
self.type = 'LOCAL' # LOCAL, DOMAIN, MACHINE, MACHINE-USER
|
||||
self.type_validated = False
|
||||
self.appdata = ''
|
||||
self.password = ''
|
||||
self.domain = ''
|
||||
self.lmhash = ''
|
||||
self.nthash = ''
|
||||
self.aesKey = ''
|
||||
self.TGT = ''
|
||||
# self.masterkeys = {} # GUID_File: masterkey
|
||||
self.masterkeys_file = {}
|
||||
self.files = {}
|
||||
self.secrets = {}
|
||||
self.dpapi_machinekey: []
|
||||
self.dpapi_userkey: []
|
||||
self.share = None
|
||||
self.pwd = None
|
||||
self.is_adconnect = False
|
||||
|
||||
def resume_user_info(self):
|
||||
try:
|
||||
encrypted=0
|
||||
decrypted=0
|
||||
decryption_failed=0
|
||||
def resume_user_info(self):
|
||||
"""Resume user informations."""
|
||||
try:
|
||||
encrypted = 0
|
||||
decrypted = 0
|
||||
decryption_failed = 0
|
||||
|
||||
for masterkey in self.masterkeys_file:
|
||||
if self.masterkeys_file[masterkey]['status']=='decrypted':
|
||||
decrypted+=1
|
||||
elif self.masterkeys_file[masterkey]['status']=='encrypted':
|
||||
encrypted+=1
|
||||
elif self.masterkeys_file[masterkey]['status'] == 'decryption_failed':
|
||||
decryption_failed+=1
|
||||
file_stats={}
|
||||
for file in self.files:
|
||||
if self.files[file]['type'] not in file_stats:
|
||||
file_stats[self.files[file]['type']]={}
|
||||
if self.files[file]['status'] not in file_stats[self.files[file]['type']]:
|
||||
file_stats[self.files[file]['type']][self.files[file]['status']]=[file]
|
||||
else:
|
||||
file_stats[self.files[file]['type']][self.files[file]['status']].append(file)
|
||||
for masterkey in self.masterkeys_file.items():
|
||||
if masterkey['status'] == 'decrypted':
|
||||
decrypted += 1
|
||||
elif masterkey['status'] == 'encrypted':
|
||||
encrypted += 1
|
||||
elif masterkey['status'] == 'decryption_failed':
|
||||
decryption_failed += 1
|
||||
file_stats = {}
|
||||
for key, user_file in self.files.items():
|
||||
if user_file['type'] not in file_stats:
|
||||
file_stats[user_file['type']] = {}
|
||||
if user_file['status'] not in file_stats[user_file['type']]:
|
||||
file_stats[user_file['type']][user_file['status']] = [key]
|
||||
else:
|
||||
file_stats[user_file['type']][user_file['status']].append(key)
|
||||
|
||||
msg_log = f"[{self.options.target_ip}] {bcolors.OKGREEN}{self.username}{bcolors.ENDC}" \
|
||||
f" - ({self.sid}) - [{self.type} account]"
|
||||
self.logging.info(msg_log)
|
||||
|
||||
msg_log = f"[{self.options.target_ip}] [{len(self.masterkeys_file)} Masterkeys " \
|
||||
f"({bcolors.OKGREEN}{decrypted} decrypted{bcolors.ENDC}/{bcolors.WARNING}" \
|
||||
f"{decryption_failed} failed{bcolors.ENDC}/{bcolors.OKBLUE}{encrypted} " \
|
||||
f"not used{bcolors.ENDC})]"
|
||||
self.logging.info(msg_log)
|
||||
self.logging.info(f"[{self.options.target_ip}] [{len(self.files)} secrets files : ]")
|
||||
|
||||
self.logging.info(f"[{self.options.target_ip}] {bcolors.OKGREEN}{self.username}{bcolors.ENDC} - ({self.sid}) - [{self.type} account]")
|
||||
self.logging.info(f"[{self.options.target_ip}] [{len(self.masterkeys_file)} Masterkeys ({bcolors.OKGREEN}{decrypted} decrypted{bcolors.ENDC}/{bcolors.WARNING}{decryption_failed} failed{bcolors.ENDC}/{bcolors.OKBLUE}{encrypted} not used{bcolors.ENDC})]")
|
||||
self.logging.info(f"[{self.options.target_ip}] [{len(self.files)} secrets files : ]")
|
||||
for secret_type in file_stats:
|
||||
for status in file_stats[secret_type]:
|
||||
self.logging.info(f"[{self.options.target_ip}] - {bcolors.OKGREEN}{len(file_stats[secret_type][status])}{bcolors.ENDC} {status} {secret_type}")
|
||||
if status == 'decrypted':
|
||||
for secret_file in file_stats[secret_type][status]:
|
||||
try:
|
||||
if secret_type == 'vault' :
|
||||
for vcrd_file in self.files[secret_file]['vcrd']:
|
||||
if self.files[secret_file]['vcrd'][vcrd_file]['status']=='decrypted':
|
||||
self.logging.info(f"[{self.options.target_ip}] Vault {secret_file} - {vcrd_file} : {self.files[secret_file]['vcrd'][vcrd_file]['secret']}")
|
||||
#self.logging.info(f"[{self.options.target_ip}] Vault {secret_file} : {self.secrets[vcrd_file]}")
|
||||
elif secret_type in ["ChromeLoginData","MozillaLoginData"]:
|
||||
for uri in self.files[secret_file]['secret']:
|
||||
self.logging.info(f"[{self.options.target_ip}] Chrome {uri} - {self.files[secret_file]['secret'][uri]['username']} : {self.files[secret_file]['secret'][uri]['password']}")
|
||||
elif secret_type == "ChromeCookies" :
|
||||
for uri in self.files[secret_file]['secret']:
|
||||
for cookie_name in self.files[secret_file]['secret'][uri]:
|
||||
self.logging.debug(f"[{self.options.target_ip}] Chrome {uri} - {cookie_name} : {self.files[secret_file]['secret'][uri][cookie_name]}")
|
||||
elif secret_type == "wifi":
|
||||
if secret_file in self.files:
|
||||
self.logging.info(f"[{self.options.target_ip}] Wifi : {self.files[secret_file]['wifi_name']} : {self.files[secret_file]['secret']}")
|
||||
for secret_type, file_status in file_stats.items():
|
||||
for status in file_status:
|
||||
|
||||
else:
|
||||
if secret_file in self.files: #For Credential & Wifi
|
||||
self.logging.info(f"[{self.options.target_ip}] {secret_file} : {self.files[secret_file]['secret']}")
|
||||
except Exception as ex:
|
||||
self.logging.debug(f"[{self.options.target_ip}] {bcolors.WARNING}Exception 00 in ResumeUserInfo for user {self.username} secret file {secret_file} type {secret_type} {bcolors.ENDC}")
|
||||
self.logging.debug(ex)
|
||||
else:
|
||||
for secret_file in file_stats[secret_type][status]:
|
||||
self.logging.debug(f"[{self.options.target_ip}] {secret_file} : {self.files[secret_file]['path']}")
|
||||
msg_log = f"[{self.options.target_ip}] - " \
|
||||
f"{bcolors.OKGREEN}{len(file_status[status])}{bcolors.ENDC} " \
|
||||
f"{status} {secret_type}"
|
||||
self.logging.info(msg_log)
|
||||
|
||||
self.logging.debug(f"[{self.options.target_ip}] -=-=-=-= Masterkeys details =-=-=-=-")
|
||||
for masterkey in self.masterkeys_file:
|
||||
self.logging.debug(f" [*]GUID : {masterkey}")
|
||||
self.logging.debug(f" [*]Status : {self.masterkeys_file[masterkey]['status']}")
|
||||
self.logging.debug(f" [*]path : {self.masterkeys_file[masterkey]['path']}")
|
||||
if self.masterkeys_file[masterkey]['status']=='decrypted':
|
||||
self.logging.debug(f" [*]key : {self.masterkeys_file[masterkey]['key']}")
|
||||
self.logging.debug(f" [*] -=- -=- -=- -=- -=- -=- [*]")
|
||||
self.resume_secrets()
|
||||
except Exception as ex:
|
||||
self.logging.debug(f"[{self.options.target_ip}] {bcolors.WARNING}Exception in ResumeUserInfo for user {self.username} {bcolors.ENDC}")
|
||||
self.logging.debug(ex)
|
||||
if status == 'decrypted':
|
||||
for secret_file in file_status[status]:
|
||||
try:
|
||||
s_file = self.files[secret_file]
|
||||
if secret_type == 'vault':
|
||||
for vcrd_file in s_file['vcrd']:
|
||||
if s_file['vcrd'][vcrd_file]['status'] == 'decrypted':
|
||||
msg_log = f"[{self.options.target_ip}] Vault " \
|
||||
f"{secret_file} - {vcrd_file} : " \
|
||||
f"{s_file['vcrd'][vcrd_file]['secret']}"
|
||||
self.logging.info(msg_log)
|
||||
elif secret_type in ["ChromeLoginData", "MozillaLoginData"]:
|
||||
for uri in s_file['secret']:
|
||||
msg_log = f"[{self.options.target_ip}] Chrome {uri} - " \
|
||||
f"{s_file['secret'][uri]['username']} : " \
|
||||
f"{s_file['secret'][uri]['password']}"
|
||||
self.logging.info(msg_log)
|
||||
elif secret_type == "ChromeCookies":
|
||||
for uri in s_file['secret']:
|
||||
for cookie_name in s_file['secret'][uri]:
|
||||
msg_log = f"[{self.options.target_ip}] Chrome {uri}" \
|
||||
f" - {cookie_name} : " \
|
||||
f"{s_file['secret'][uri][cookie_name]}"
|
||||
self.logging.debug(msg_log)
|
||||
elif secret_type == "wifi":
|
||||
if secret_file in self.files:
|
||||
msg_log = f"[{self.options.target_ip}] Wifi : " \
|
||||
f"{s_file['wifi_name']} : {s_file['secret']}"
|
||||
self.logging.info(msg_log)
|
||||
else:
|
||||
if secret_file in self.files: # For Credential & Wifi
|
||||
msg_log = f"[{self.options.target_ip}] {secret_file} : " \
|
||||
f"{s_file['secret']}"
|
||||
self.logging.info(msg_log)
|
||||
except OSError as ex:
|
||||
msg_log = f"[{self.options.target_ip}] {bcolors.WARNING}Exception" \
|
||||
f" in ResumeUserInfo for user {self.username} secret" \
|
||||
f" file {secret_file} type {secret_type} {bcolors.ENDC}"
|
||||
self.logging.debug(msg_log)
|
||||
self.logging.debug(ex)
|
||||
else:
|
||||
for secret_file in file_status[status]:
|
||||
msg_log = f"[{self.options.target_ip}] {secret_file} : " \
|
||||
f"{self.files[secret_file]['path']}"
|
||||
self.logging.debug(msg_log)
|
||||
|
||||
def resume_secrets(self):
|
||||
self.logging.info(f"[{self.options.target_ip}] [*]User : {self.username} - {len(self.secrets)} secrets :")
|
||||
for secret in self.secrets:
|
||||
self.logging.info(f"[{self.options.target_ip}] [*]secret : {secret}")
|
||||
self.logging.info(f"[{self.options.target_ip}] {self.secrets[secret]}")
|
||||
self.logging.debug(f"[{self.options.target_ip}] -=-=-=-= Masterkeys details =-=-=-=-")
|
||||
|
||||
def get_secrets(self):
|
||||
return self.secrets
|
||||
for masterkey, masterkey_content in self.masterkeys_file.items():
|
||||
self.logging.debug(f"\t\t[*]GUID : {masterkey}")
|
||||
self.logging.debug(f"\t\t[*]Status : {masterkey_content['status']}")
|
||||
self.logging.debug(f"\t\t[*]path : {masterkey_content['path']}")
|
||||
if masterkey_content['status'] == 'decrypted':
|
||||
self.logging.debug(f"\t\t[*]key : {masterkey_content['key']}")
|
||||
self.logging.debug("\t\t[*] -=- -=- -=- -=- -=- -=- [*]")
|
||||
self.resume_secrets()
|
||||
|
||||
def check_usertype(self):
|
||||
#Todo
|
||||
if self.sid =='':
|
||||
return 'DOMAIN'
|
||||
else :
|
||||
return 'LOCAL'
|
||||
except OSError as ex:
|
||||
msg_log = f"[{self.options.target_ip}] {bcolors.WARNING}Exception in " \
|
||||
f"ResumeUserInfo for user {self.username} {bcolors.ENDC}"
|
||||
self.logging.debug(msg_log)
|
||||
self.logging.debug(ex)
|
||||
|
||||
def resume_secrets(self):
|
||||
"""Resume secrets."""
|
||||
msg_log = f"[{self.options.target_ip}] [*]User : " \
|
||||
f"{self.username} - {len(self.secrets)} secrets :"
|
||||
self.logging.info(msg_log)
|
||||
for secret, secret_content in self.secrets:
|
||||
self.logging.info(f"[{self.options.target_ip}]\t[*]secret : {secret}")
|
||||
self.logging.info(f"[{self.options.target_ip}]\t{secret_content}")
|
||||
|
||||
def get_secrets(self):
|
||||
"""Get secrets."""
|
||||
return self.secrets
|
||||
|
||||
def check_usertype(self):
|
||||
"""Check user type."""
|
||||
# TODO
|
||||
if self.sid == '':
|
||||
return 'DOMAIN'
|
||||
else:
|
||||
return 'LOCAL'
|
||||
|
|
Loading…
Reference in New Issue