From 9d558d95dbfb3b7a9b5b43c47d5edc07044f44d2 Mon Sep 17 00:00:00 2001 From: Alexander Neff <alex99.neff@gmx.de> Date: Thu, 28 Nov 2024 17:31:50 -0500 Subject: [PATCH 1/6] Remove unnecessary exception info which results in double logs, caused by kwargs passed as exc_info in log record --- nxc/logger.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/nxc/logger.py b/nxc/logger.py index 2a30a0256..8429de09b 100755 --- a/nxc/logger.py +++ b/nxc/logger.py @@ -43,7 +43,7 @@ def create_temp_logger(caller_frame, formatted_text, args, kwargs): temp_logger = logging.getLogger("temp") formatter = logging.Formatter("%(message)s", datefmt="[%X]") handler = SmartDebugRichHandler(formatter=formatter) - handler.handle(LogRecord(temp_logger.name, logging.INFO, caller_frame.f_code.co_filename, caller_frame.f_lineno, formatted_text, args, kwargs, caller_frame=caller_frame)) + handler.handle(LogRecord(temp_logger.name, logging.INFO, caller_frame.f_code.co_filename, caller_frame.f_lineno, formatted_text, args, None, caller_frame=caller_frame)) class SmartDebugRichHandler(RichHandler): @@ -56,9 +56,6 @@ def __init__(self, formatter=None, *args, **kwargs): def emit(self, record): """Overrides the emit method of the RichHandler class so we can set the proper pathname and lineno""" - # for some reason in RDP, the exc_text is None which leads to a KeyError in Python logging - record.exc_text = record.getMessage() if record.exc_text is None else record.exc_text - if hasattr(record, "caller_frame"): frame_info = inspect.getframeinfo(record.caller_frame) record.pathname = frame_info.filename From 8dabb3d0e6b0a26e324e7a4781f03405a10699f0 Mon Sep 17 00:00:00 2001 From: Alexander Neff <alex99.neff@gmx.de> Date: Thu, 28 Nov 2024 18:27:59 -0500 Subject: [PATCH 2/6] Remove formatter that strips out escape sequence, as already done by Text.from_ansi --- nxc/logger.py | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/nxc/logger.py b/nxc/logger.py index 8429de09b..f44c37a42 100755 --- a/nxc/logger.py +++ b/nxc/logger.py @@ -3,7 +3,6 @@ from logging.handlers import RotatingFileHandler import os.path import sys -import re from nxc.console import nxc_console from nxc.paths import NXC_PATH from termcolor import colored @@ -174,7 +173,7 @@ def log_console_to_file(self, text, *args, **kwargs): self.logger.fail(f"Issue while trying to custom print handler: {e}") def add_file_log(self, log_file=None): - file_formatter = TermEscapeCodeFormatter("%(asctime)s | %(filename)s:%(lineno)s - %(levelname)s - %(message)s", datefmt="%Y-%m-%d %H:%M:%S") + file_formatter = logging.Formatter("%(asctime)s | %(filename)s:%(lineno)s - %(levelname)s - %(message)s", datefmt="%Y-%m-%d %H:%M:%S") output_file = self.init_log_file() if log_file is None else log_file file_creation = False @@ -206,17 +205,5 @@ def init_log_file(): ) -class TermEscapeCodeFormatter(logging.Formatter): - """A class to strip the escape codes for logging to files""" - - def __init__(self, fmt=None, datefmt=None, style="%", validate=True): - super().__init__(fmt, datefmt, style, validate) - - def format(self, record): # noqa: A003 - escape_re = re.compile(r"\x1b\[[0-9;]*m") - record.msg = re.sub(escape_re, "", str(record.msg)) - return super().format(record) - - # initialize the logger for all of nxc - this is imported everywhere nxc_logger = NXCAdapter() From 9e024582a48491ce4909f00fbd46000411bd7e21 Mon Sep 17 00:00:00 2001 From: Alexander Neff <alex99.neff@gmx.de> Date: Thu, 28 Nov 2024 18:41:10 -0500 Subject: [PATCH 3/6] Add timeout check, to not double check a non existent host --- nxc/protocols/smb.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/nxc/protocols/smb.py b/nxc/protocols/smb.py index 0f27f80ae..8fa940bb7 100755 --- a/nxc/protocols/smb.py +++ b/nxc/protocols/smb.py @@ -159,6 +159,7 @@ def __init__(self, args, db, host): self.bootkey = None self.output_filename = None self.smbv1 = None + self.is_timeouted = False self.signing = False self.smb_share_name = smb_share_name self.pvkbytes = None @@ -551,8 +552,13 @@ def create_smbv1_conn(self): ) self.smbv1 = True except OSError as e: - if str(e).find("Connection reset by peer") != -1: + if "Connection reset by peer" in str(e): self.logger.info(f"SMBv1 might be disabled on {self.host}") + if "timed out" in str(e): + self.is_timeouted = True + return False + except NetBIOSError: + self.logger.info(f"SMBv1 disabled on {self.host}") return False except (Exception, NetBIOSTimeout) as e: self.logger.info(f"Error creating SMBv1 connection to {self.host}: {e}") @@ -596,7 +602,7 @@ def create_conn_obj(self, no_smbv1=False): self.smbv1 = self.create_smbv1_conn() if self.smbv1: return True - else: + elif not self.is_timeouted: return self.create_smbv3_conn() elif not no_smbv1 and self.smbv1: return self.create_smbv1_conn() From 9644cae865ebc3cc5c29d14e0641b3b24adbfb6a Mon Sep 17 00:00:00 2001 From: Alexander Neff <alex99.neff@gmx.de> Date: Thu, 28 Nov 2024 18:43:23 -0500 Subject: [PATCH 4/6] Simplify logging --- nxc/protocols/smb.py | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/nxc/protocols/smb.py b/nxc/protocols/smb.py index 8fa940bb7..e58b8de09 100755 --- a/nxc/protocols/smb.py +++ b/nxc/protocols/smb.py @@ -554,8 +554,11 @@ def create_smbv1_conn(self): except OSError as e: if "Connection reset by peer" in str(e): self.logger.info(f"SMBv1 might be disabled on {self.host}") - if "timed out" in str(e): + elif "timed out" in str(e): self.is_timeouted = True + self.logger.debug(f"Timeout creating SMBv1 connection to {self.host}") + else: + self.logger.info(f"Error creating SMBv1 connection to {self.host}: {e}") return False except NetBIOSError: self.logger.info(f"SMBv1 disabled on {self.host}") @@ -576,15 +579,7 @@ def create_smbv3_conn(self): timeout=self.args.smb_timeout, ) self.smbv1 = False - except OSError as e: - # This should not happen anymore!!! - if str(e).find("Too many open files") != -1: - if not self.logger: - print("DEBUG ERROR: logger not set, please open an issue on github: " + str(self) + str(self.logger)) - self.proto_logger() - self.logger.fail(f"SMBv3 connection error on {self.host}: {e}") - return False - except (Exception, NetBIOSTimeout) as e: + except (Exception, NetBIOSTimeout, OSError) as e: self.logger.info(f"Error creating SMBv3 connection to {self.host}: {e}") return False return True From 410e040a283b4c35279db7d0528b3b4fa53a6884 Mon Sep 17 00:00:00 2001 From: Alexander Neff <alex99.neff@gmx.de> Date: Thu, 28 Nov 2024 19:00:45 -0500 Subject: [PATCH 5/6] Don't print an index error with null session, we won't have null user in the db --- nxc/protocols/smb.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nxc/protocols/smb.py b/nxc/protocols/smb.py index e58b8de09..23a3567fe 100755 --- a/nxc/protocols/smb.py +++ b/nxc/protocols/smb.py @@ -846,7 +846,7 @@ def shares(self): self.logger.debug(f"domain: {self.domain}") user_id = self.db.get_user(self.domain.upper(), self.username)[0][0] except IndexError as e: - if self.kerberos: + if self.kerberos or self.username == "": pass else: self.logger.fail(f"IndexError: {e!s}") From b9f52fdd4b90148ef2ea06618273919eb02a211a Mon Sep 17 00:00:00 2001 From: Alexander Neff <alex99.neff@gmx.de> Date: Thu, 28 Nov 2024 19:00:54 -0500 Subject: [PATCH 6/6] Formating --- nxc/protocols/smb.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/nxc/protocols/smb.py b/nxc/protocols/smb.py index 23a3567fe..2ba130245 100755 --- a/nxc/protocols/smb.py +++ b/nxc/protocols/smb.py @@ -948,10 +948,9 @@ def shares(self): self.logger.highlight(f"{name:<15} {','.join(perms):<15} {remark}") return permissions - def dir(self): # noqa: A003 search_path = ntpath.join(self.args.dir, "*") - try: + try: contents = self.conn.listPath(self.args.share, search_path) except SessionError as e: error = get_error_string(e) @@ -960,7 +959,7 @@ def dir(self): # noqa: A003 color="magenta" if error in smb_error_status else "red", ) return - + if not contents: return @@ -970,7 +969,6 @@ def dir(self): # noqa: A003 full_path = ntpath.join(self.args.dir, content.get_longname()) self.logger.highlight(f"{'d' if content.is_directory() else 'f'}{'rw-' if content.is_readonly() > 0 else 'r--':<8}{content.get_filesize():<15}{ctime(float(content.get_mtime_epoch())):<30}{full_path:<45}") - @requires_admin def interfaces(self): """