* 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:
Zeecka 2023-10-03 07:27:06 +02:00 committed by GitHub
parent 0c27276c15
commit a660ac7783
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 2479 additions and 2394 deletions

View File

@ -265,26 +265,26 @@ def first_run(options):
conn.close() conn.close()
def seatbelt_thread(datas): def seatbelt_thread(datas):
global assets global assets
target,options, logger=datas target,options, logger=datas
logging.debug("[*] SeatBelt thread for {ip} Started".format(ip=target)) logging.debug("[*] SeatBelt thread for {ip} Started".format(ip=target))
try: try:
mysb = MySeatBelt(target,options,logger) mysb = MySeatBelt(target,options,logger)
if mysb.admin_privs: if mysb.admin_privs:
mysb.do_test() mysb.do_test()
# mysb.run() # mysb.run()
#mysb.quit() #mysb.close_smb()
else: else:
logging.debug("[*] No ADMIN account on target {ip}".format(ip=target)) logging.debug("[*] No ADMIN account on target {ip}".format(ip=target))
#assets[target] = mysb.get_secrets() #assets[target] = mysb.get_secrets()
logging.debug("[*] SeatBelt thread for {ip} Ended".format(ip=target)) logging.debug("[*] SeatBelt thread for {ip} Ended".format(ip=target))
except Exception as e: except Exception as e:
if logging.getLogger().level == logging.DEBUG: if logging.getLogger().level == logging.DEBUG:
import traceback import traceback
traceback.print_exc() traceback.print_exc()
logging.error(str(e)) logging.error(str(e))
def export_results_seatbelt(output_dir=''): def export_results_seatbelt(output_dir=''):

File diff suppressed because it is too large Load Diff

View File

@ -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 from donpapi.lib.toolbox import bcolors
class MyUser: class MyUser:
def __init__(self, username,logger,options): """MyUser class."""
self.username = username def __init__(self, username, logger, options):
self.options=options self.username = username
self.logging = logger self.options = options
self.sid = ''#un user peut avoir plusieurs SID ? self.logging = logger
self.type = 'LOCAL'#LOCAL,DOMAIN,MACHINE,MACHINE-USER self.sid = '' # A user may have many SID ?
self.type_validated = False self.type = 'LOCAL' # LOCAL, DOMAIN, MACHINE, MACHINE-USER
self.appdata = '' self.type_validated = False
self.password = '' self.appdata = ''
self.domain = '' self.password = ''
self.lmhash = '' self.domain = ''
self.nthash = '' self.lmhash = ''
self.aesKey = '' self.nthash = ''
self.TGT = '' self.aesKey = ''
#self.masterkeys = {} # GUID_File: masterkey self.TGT = ''
self.masterkeys_file = {} # self.masterkeys = {} # GUID_File: masterkey
self.files = {} self.masterkeys_file = {}
self.secrets = {} self.files = {}
self.dpapi_machinekey: [] self.secrets = {}
self.dpapi_userkey: [] self.dpapi_machinekey: []
self.share = None self.dpapi_userkey: []
self.pwd = None self.share = None
self.is_adconnect = False self.pwd = None
self.is_adconnect = False
def resume_user_info(self): def resume_user_info(self):
try: """Resume user informations."""
encrypted=0 try:
decrypted=0 encrypted = 0
decryption_failed=0 decrypted = 0
decryption_failed = 0
for masterkey in self.masterkeys_file: for masterkey in self.masterkeys_file.items():
if self.masterkeys_file[masterkey]['status']=='decrypted': if masterkey['status'] == 'decrypted':
decrypted+=1 decrypted += 1
elif self.masterkeys_file[masterkey]['status']=='encrypted': elif masterkey['status'] == 'encrypted':
encrypted+=1 encrypted += 1
elif self.masterkeys_file[masterkey]['status'] == 'decryption_failed': elif masterkey['status'] == 'decryption_failed':
decryption_failed+=1 decryption_failed += 1
file_stats={} file_stats = {}
for file in self.files: for key, user_file in self.files.items():
if self.files[file]['type'] not in file_stats: if user_file['type'] not in file_stats:
file_stats[self.files[file]['type']]={} file_stats[user_file['type']] = {}
if self.files[file]['status'] not in file_stats[self.files[file]['type']]: if user_file['status'] not in file_stats[user_file['type']]:
file_stats[self.files[file]['type']][self.files[file]['status']]=[file] file_stats[user_file['type']][user_file['status']] = [key]
else: else:
file_stats[self.files[file]['type']][self.files[file]['status']].append(file) 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]") for secret_type, file_status in file_stats.items():
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})]") for status in file_status:
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']}")
else: msg_log = f"[{self.options.target_ip}] - " \
if secret_file in self.files: #For Credential & Wifi f"{bcolors.OKGREEN}{len(file_status[status])}{bcolors.ENDC} " \
self.logging.info(f"[{self.options.target_ip}] {secret_file} : {self.files[secret_file]['secret']}") f"{status} {secret_type}"
except Exception as ex: self.logging.info(msg_log)
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']}")
self.logging.debug(f"[{self.options.target_ip}] -=-=-=-= Masterkeys details =-=-=-=-") if status == 'decrypted':
for masterkey in self.masterkeys_file: for secret_file in file_status[status]:
self.logging.debug(f" [*]GUID : {masterkey}") try:
self.logging.debug(f" [*]Status : {self.masterkeys_file[masterkey]['status']}") s_file = self.files[secret_file]
self.logging.debug(f" [*]path : {self.masterkeys_file[masterkey]['path']}") if secret_type == 'vault':
if self.masterkeys_file[masterkey]['status']=='decrypted': for vcrd_file in s_file['vcrd']:
self.logging.debug(f" [*]key : {self.masterkeys_file[masterkey]['key']}") if s_file['vcrd'][vcrd_file]['status'] == 'decrypted':
self.logging.debug(f" [*] -=- -=- -=- -=- -=- -=- [*]") msg_log = f"[{self.options.target_ip}] Vault " \
self.resume_secrets() f"{secret_file} - {vcrd_file} : " \
except Exception as ex: f"{s_file['vcrd'][vcrd_file]['secret']}"
self.logging.debug(f"[{self.options.target_ip}] {bcolors.WARNING}Exception in ResumeUserInfo for user {self.username} {bcolors.ENDC}") self.logging.info(msg_log)
self.logging.debug(ex) 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.debug(f"[{self.options.target_ip}] -=-=-=-= Masterkeys details =-=-=-=-")
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]}")
def get_secrets(self): for masterkey, masterkey_content in self.masterkeys_file.items():
return self.secrets 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): except OSError as ex:
#Todo msg_log = f"[{self.options.target_ip}] {bcolors.WARNING}Exception in " \
if self.sid =='': f"ResumeUserInfo for user {self.username} {bcolors.ENDC}"
return 'DOMAIN' self.logging.debug(msg_log)
else : self.logging.debug(ex)
return 'LOCAL'
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'