2022-07-18 23:59:14 +00:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
2016-05-16 23:48:31 +00:00
|
|
|
import logging
|
2023-02-21 20:05:35 +00:00
|
|
|
import os.path
|
2016-05-16 23:48:31 +00:00
|
|
|
import sys
|
|
|
|
import re
|
2017-05-08 03:16:18 +00:00
|
|
|
from cme.helpers.misc import called_from_cmd_args
|
2016-05-16 23:48:31 +00:00
|
|
|
from termcolor import colored
|
|
|
|
from datetime import datetime
|
|
|
|
|
|
|
|
#The following hooks the FileHandler.emit function to remove ansi chars before logging to a file
|
2016-12-15 07:28:00 +00:00
|
|
|
#There must be a better way of doing this, but this way we might save some penguins!
|
2016-05-16 23:48:31 +00:00
|
|
|
|
|
|
|
ansi_escape = re.compile(r'\x1b[^m]*m')
|
|
|
|
|
|
|
|
def antiansi_emit(self, record):
|
|
|
|
|
|
|
|
if self.stream is None:
|
|
|
|
self.stream = self._open()
|
|
|
|
|
|
|
|
record.msg = ansi_escape.sub('', record.message)
|
|
|
|
logging.StreamHandler.emit(self, record)
|
|
|
|
|
|
|
|
logging.FileHandler.emit = antiansi_emit
|
|
|
|
|
|
|
|
####################################################################
|
|
|
|
|
|
|
|
class CMEAdapter(logging.LoggerAdapter):
|
|
|
|
|
2017-05-03 00:52:16 +00:00
|
|
|
# For Impacket's TDS library
|
|
|
|
message = ''
|
|
|
|
|
2016-12-15 07:28:00 +00:00
|
|
|
def __init__(self, logger_name='CME', extra=None):
|
|
|
|
self.logger = logging.getLogger(logger_name)
|
2016-05-16 23:48:31 +00:00
|
|
|
self.extra = extra
|
2023-02-17 13:20:16 +00:00
|
|
|
self.outputfile = None
|
2016-05-16 23:48:31 +00:00
|
|
|
|
|
|
|
def process(self, msg, kwargs):
|
|
|
|
if self.extra is None:
|
|
|
|
return u'{}'.format(msg), kwargs
|
|
|
|
|
2017-03-27 21:09:36 +00:00
|
|
|
if 'module' in self.extra.keys():
|
|
|
|
if len(self.extra['module']) > 8:
|
|
|
|
self.extra['module'] = self.extra['module'][:8] + '...'
|
|
|
|
|
2016-05-16 23:48:31 +00:00
|
|
|
#If the logger is being called when hooking the 'options' module function
|
|
|
|
if len(self.extra) == 1 and ('module' in self.extra.keys()):
|
2017-04-30 19:40:00 +00:00
|
|
|
return u'{:<64} {}'.format(colored(self.extra['module'], 'cyan', attrs=['bold']), msg), kwargs
|
2016-05-16 23:48:31 +00:00
|
|
|
|
|
|
|
#If the logger is being called from CMEServer
|
|
|
|
if len(self.extra) == 2 and ('module' in self.extra.keys()) and ('host' in self.extra.keys()):
|
2017-04-30 19:40:00 +00:00
|
|
|
return u'{:<24} {:<39} {}'.format(colored(self.extra['module'], 'cyan', attrs=['bold']), self.extra['host'], msg), kwargs
|
2016-05-16 23:48:31 +00:00
|
|
|
|
2017-03-27 21:09:36 +00:00
|
|
|
#If the logger is being called from a protocol
|
2016-05-16 23:48:31 +00:00
|
|
|
if 'module' in self.extra.keys():
|
|
|
|
module_name = colored(self.extra['module'], 'cyan', attrs=['bold'])
|
|
|
|
else:
|
2016-12-15 07:28:00 +00:00
|
|
|
module_name = colored(self.extra['protocol'], 'blue', attrs=['bold'])
|
2016-05-16 23:48:31 +00:00
|
|
|
|
2017-04-30 18:54:35 +00:00
|
|
|
return u'{:<24} {:<15} {:<6} {:<16} {}'.format(module_name,
|
2017-03-30 00:03:04 +00:00
|
|
|
self.extra['host'],
|
|
|
|
self.extra['port'],
|
2019-11-10 23:12:35 +00:00
|
|
|
self.extra['hostname'] if self.extra['hostname'] else 'NONE',
|
2017-03-30 00:03:04 +00:00
|
|
|
msg), kwargs
|
2016-05-16 23:48:31 +00:00
|
|
|
|
|
|
|
def info(self, msg, *args, **kwargs):
|
2017-05-08 03:16:18 +00:00
|
|
|
try:
|
|
|
|
if 'protocol' in self.extra.keys() and not called_from_cmd_args():
|
|
|
|
return
|
|
|
|
except AttributeError:
|
|
|
|
pass
|
|
|
|
|
2016-05-16 23:48:31 +00:00
|
|
|
msg, kwargs = self.process(u'{} {}'.format(colored("[*]", 'blue', attrs=['bold']), msg), kwargs)
|
|
|
|
self.logger.info(msg, *args, **kwargs)
|
|
|
|
|
2020-06-20 17:20:27 +00:00
|
|
|
def error(self, msg, color='red', *args, **kwargs):
|
|
|
|
msg, kwargs = self.process(u'{} {}'.format(colored("[-]", color, attrs=['bold']), msg), kwargs)
|
2016-05-16 23:48:31 +00:00
|
|
|
self.logger.error(msg, *args, **kwargs)
|
|
|
|
|
|
|
|
def debug(self, msg, *args, **kwargs):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def success(self, msg, *args, **kwargs):
|
2017-05-08 03:16:18 +00:00
|
|
|
try:
|
|
|
|
if 'protocol' in self.extra.keys() and not called_from_cmd_args():
|
|
|
|
return
|
|
|
|
except AttributeError:
|
|
|
|
pass
|
|
|
|
|
2016-05-16 23:48:31 +00:00
|
|
|
msg, kwargs = self.process(u'{} {}'.format(colored("[+]", 'green', attrs=['bold']), msg), kwargs)
|
|
|
|
self.logger.info(msg, *args, **kwargs)
|
|
|
|
|
|
|
|
def highlight(self, msg, *args, **kwargs):
|
2017-05-08 03:16:18 +00:00
|
|
|
try:
|
|
|
|
if 'protocol' in self.extra.keys() and not called_from_cmd_args():
|
|
|
|
return
|
|
|
|
except AttributeError:
|
|
|
|
pass
|
|
|
|
|
2016-05-16 23:48:31 +00:00
|
|
|
msg, kwargs = self.process(u'{}'.format(colored(msg, 'yellow', attrs=['bold'])), kwargs)
|
|
|
|
self.logger.info(msg, *args, **kwargs)
|
|
|
|
|
2017-05-03 00:52:16 +00:00
|
|
|
# For Impacket's TDS library
|
|
|
|
def logMessage(self,message):
|
|
|
|
CMEAdapter.message += message.strip().replace('NULL', '') + '\n'
|
|
|
|
|
|
|
|
def getMessage(self):
|
|
|
|
out = CMEAdapter.message
|
|
|
|
CMEAdapter.message = ''
|
|
|
|
return out
|
2023-02-17 13:20:16 +00:00
|
|
|
|
2023-02-21 20:01:42 +00:00
|
|
|
def setup_logfile(self, log_file=None):
|
2023-02-17 13:20:16 +00:00
|
|
|
formatter = logging.Formatter("%(message)s")
|
2023-02-21 20:01:42 +00:00
|
|
|
self.outputfile = init_log_file() if log_file == None else log_file
|
2023-02-22 09:50:40 +00:00
|
|
|
file_creation = False
|
2023-02-21 19:40:52 +00:00
|
|
|
if not os.path.isfile(self.outputfile):
|
|
|
|
open(self.outputfile, 'x')
|
2023-02-22 09:50:40 +00:00
|
|
|
file_creation = True
|
2023-02-17 13:20:16 +00:00
|
|
|
fileHandler = logging.FileHandler(filename=self.outputfile, mode="a")
|
|
|
|
with fileHandler._open() as f:
|
2023-02-22 09:50:40 +00:00
|
|
|
if file_creation:
|
|
|
|
f.write("[%s]> %s\n\n" % (datetime.now().strftime('%d-%m-%Y %H:%M:%S'), " ".join(sys.argv)))
|
|
|
|
else:
|
|
|
|
f.write("\n[%s]> %s\n\n" % (datetime.now().strftime('%d-%m-%Y %H:%M:%S'), " ".join(sys.argv)))
|
2023-02-17 13:20:16 +00:00
|
|
|
fileHandler.setFormatter(formatter)
|
|
|
|
self.logger.addHandler(fileHandler)
|
2016-05-16 23:48:31 +00:00
|
|
|
|
|
|
|
def setup_debug_logger():
|
2017-03-27 21:09:36 +00:00
|
|
|
debug_output_string = "{} %(message)s".format(colored('DEBUG', 'magenta', attrs=['bold']))
|
2016-09-21 19:40:59 +00:00
|
|
|
formatter = logging.Formatter(debug_output_string)
|
2016-05-16 23:48:31 +00:00
|
|
|
streamHandler = logging.StreamHandler(sys.stdout)
|
|
|
|
streamHandler.setFormatter(formatter)
|
|
|
|
|
|
|
|
root_logger = logging.getLogger()
|
2023-01-25 18:28:12 +00:00
|
|
|
root_logger.handlers = []
|
2016-05-16 23:48:31 +00:00
|
|
|
root_logger.addHandler(streamHandler)
|
|
|
|
root_logger.setLevel(logging.DEBUG)
|
|
|
|
return root_logger
|
|
|
|
|
2023-02-17 13:20:16 +00:00
|
|
|
def setup_logger(level=logging.INFO, logger_name='CME'):
|
2016-09-21 19:40:59 +00:00
|
|
|
formatter = logging.Formatter("%(message)s")
|
2016-05-16 23:48:31 +00:00
|
|
|
|
|
|
|
streamHandler = logging.StreamHandler(sys.stdout)
|
|
|
|
streamHandler.setFormatter(formatter)
|
|
|
|
|
|
|
|
cme_logger = logging.getLogger(logger_name)
|
|
|
|
cme_logger.propagate = False
|
|
|
|
cme_logger.addHandler(streamHandler)
|
|
|
|
cme_logger.setLevel(level)
|
|
|
|
|
2016-12-15 07:28:00 +00:00
|
|
|
return cme_logger
|
2023-02-17 13:20:16 +00:00
|
|
|
|
|
|
|
def init_log_file():
|
2023-02-21 19:40:52 +00:00
|
|
|
log_filename = os.path.join(os.path.expanduser('~/.cme'), 'logs','full-log_{}.log'.format(datetime.now().strftime('%Y-%m-%d')))
|
2023-02-17 13:20:16 +00:00
|
|
|
return log_filename
|