update lsassy module for logging and improved error handling/logging
parent
a5b821d96f
commit
7acc00fe0d
|
@ -5,12 +5,13 @@
|
|||
# Website:
|
||||
# https://beta.hackndo.com [FR]
|
||||
# https://en.hackndo.com [EN]
|
||||
import logging
|
||||
|
||||
from lsassy.dumper import Dumper
|
||||
from lsassy.parser import Parser
|
||||
from lsassy.session import Session
|
||||
from lsassy.impacketfile import ImpacketFile
|
||||
from cme.helpers.bloodhound import add_user_bh
|
||||
import logging
|
||||
|
||||
|
||||
class CMEModule:
|
||||
|
@ -34,12 +35,6 @@ class CMEModule:
|
|||
self.method = module_options['METHOD']
|
||||
|
||||
def on_admin_login(self, context, connection):
|
||||
# lsassy uses a custom "success" level, which requires initializing its logger or an error will be thrown
|
||||
# lsassy also removes all other handlers and overwrites the formatter which is bad for us (we want ours)
|
||||
# so what we do is define "success" as a logging level, then do nothing with the output
|
||||
logging.addLevelName(25, 'SUCCESS')
|
||||
setattr(logging, 'success', lambda message, *args: ())
|
||||
|
||||
host = connection.host
|
||||
domain_name = connection.domain
|
||||
username = connection.username
|
||||
|
@ -80,16 +75,37 @@ class CMEModule:
|
|||
credentials, tickets, masterkeys = parsed
|
||||
|
||||
file.close()
|
||||
ImpacketFile.delete(session, file.get_file_path())
|
||||
context.log.debug(f"Closed dumper file")
|
||||
file_path = file.get_file_path()
|
||||
context.log.debug(f"File path: {file_path}")
|
||||
try:
|
||||
deleted_file = ImpacketFile.delete(session, file_path)
|
||||
if deleted_file:
|
||||
context.log.debug(f"Deleted dumper file")
|
||||
else:
|
||||
context.log.fail(f"[OPSEC] No exception, but failed to delete file: {file_path}")
|
||||
except Exception as e:
|
||||
context.log.fail(f"[OPSEC] Error deleting temporary lsassy dumper file {file_path}: {e}")
|
||||
|
||||
if credentials is None:
|
||||
credentials = []
|
||||
|
||||
for cred in credentials:
|
||||
c = cred.get_object()
|
||||
context.log.debug(f"Cred: {c}")
|
||||
|
||||
credentials = [cred.get_object() for cred in credentials if cred.ticket is None and cred.masterkey is None and not cred.get_username().endswith("$")]
|
||||
credentials_unique = []
|
||||
credentials_output = []
|
||||
context.log.debug(f"Credentials: {credentials}")
|
||||
|
||||
for cred in credentials:
|
||||
context.log.debug(f"Credential: {cred}")
|
||||
if [cred["domain"], cred["username"], cred["password"], cred["lmhash"], cred["nthash"]] not in credentials_unique:
|
||||
credentials_unique.append([cred["domain"], cred["username"], cred["password"], cred["lmhash"], cred["nthash"]])
|
||||
credentials_output.append(cred)
|
||||
|
||||
context.log.debug(f"Calling process_credentials")
|
||||
self.process_credentials(context, connection, credentials_output)
|
||||
|
||||
def process_credentials(self, context, connection, credentials):
|
||||
|
@ -108,6 +124,7 @@ class CMEModule:
|
|||
|
||||
@staticmethod
|
||||
def print_credentials(context, domain, username, password, lmhash, nthash):
|
||||
context.log.debug(f"Inside print_credentials")
|
||||
if password is None:
|
||||
password = ':'.join(h for h in [lmhash, nthash] if h is not None)
|
||||
output = "%s\\%s %s" % (domain, username, password)
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
import logging
|
||||
import os
|
||||
from io import StringIO
|
||||
from cme.protocols.mssql.mssqlexec import MSSQLEXEC
|
||||
from cme.connection import *
|
||||
|
@ -158,7 +159,7 @@ class mssql(connection):
|
|||
else:
|
||||
return False
|
||||
except Exception as e:
|
||||
self.logger.error('Error calling check_if_admin(): {}'.format(e))
|
||||
self.loggerfail('Error calling check_if_admin(): {}'.format(e))
|
||||
return False
|
||||
|
||||
return True
|
||||
|
@ -216,7 +217,7 @@ class mssql(connection):
|
|||
if not self.args.continue_on_success:
|
||||
return True
|
||||
except Exception as e:
|
||||
self.logger.error(u'{}\\{}{} {}'.format('{}\\'.format(domain) if not self.args.local_auth else '',
|
||||
self.logger.fail(u'{}\\{}{} {}'.format('{}\\'.format(domain) if not self.args.local_auth else '',
|
||||
username,
|
||||
# Show what was used between cleartext, nthash, aesKey and ccache
|
||||
" from ccache" if useCache
|
||||
|
@ -258,9 +259,9 @@ class mssql(connection):
|
|||
if not self.args.continue_on_success:
|
||||
return True
|
||||
except BrokenPipeError as e:
|
||||
self.logger.error(f"Broken Pipe Error while attempting to login")
|
||||
self.logger.fail(f"Broken Pipe Error while attempting to login")
|
||||
except Exception as e:
|
||||
self.logger.error(u'{}\\{}:{} {}'.format(
|
||||
self.logger.fail(u'{}\\{}:{} {}'.format(
|
||||
domain,
|
||||
username,
|
||||
password if not self.config.get('CME', 'audit_mode') else self.config.get('CME', 'audit_mode')*8,
|
||||
|
@ -318,9 +319,9 @@ class mssql(connection):
|
|||
if not self.args.continue_on_success:
|
||||
return True
|
||||
except BrokenPipeError as e:
|
||||
self.logger.error(f"Broken Pipe Error while attempting to login")
|
||||
self.logger.fail(f"Broken Pipe Error while attempting to login")
|
||||
except Exception as e:
|
||||
self.logger.error(u'{}\\{}:{} {}'.format(
|
||||
self.logger.fail(u'{}\\{}:{} {}'.format(
|
||||
domain,
|
||||
username,
|
||||
ntlm_hash if not self.config.get('CME', 'audit_mode') else self.config.get('CME', 'audit_mode')*8,
|
||||
|
@ -384,9 +385,9 @@ class mssql(connection):
|
|||
if exec_method.file_exists(self.args.put_file[1]):
|
||||
self.logger.success('File has been uploaded on the remote machine')
|
||||
else:
|
||||
self.logger.error('File does not exist on the remote system.. erorr during upload')
|
||||
self.logger.fail('File does not exist on the remote system.. erorr during upload')
|
||||
except Exception as e:
|
||||
self.logger.error('Error during upload : {}'.format(e))
|
||||
self.logger.fail('Error during upload : {}'.format(e))
|
||||
|
||||
@requires_admin
|
||||
def get_file(self):
|
||||
|
@ -396,7 +397,7 @@ class mssql(connection):
|
|||
exec_method.get_file(self.args.get_file[0], self.args.get_file[1])
|
||||
self.logger.success('File {} was transferred to {}'.format(self.args.get_file[0], self.args.get_file[1]))
|
||||
except Exception as e:
|
||||
self.logger.error('Error reading file {}: {}'.format(self.args.get_file[0], e))
|
||||
self.logger.fail('Error reading file {}: {}'.format(self.args.get_file[0], e))
|
||||
|
||||
|
||||
# We hook these functions in the tds library to use CME's logger instead of printing the output to stdout
|
||||
|
|
Loading…
Reference in New Issue