From 09ca4c91f4d6db2c089a57dc15271abb2378ecd1 Mon Sep 17 00:00:00 2001 From: Alexander Neff Date: Sun, 25 May 2025 09:47:54 -0400 Subject: [PATCH 1/3] Implement unlimited querying with MSEven --- nxc/modules/eventlog_creds.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/nxc/modules/eventlog_creds.py b/nxc/modules/eventlog_creds.py index 5572fcf6..4d2cd283 100644 --- a/nxc/modules/eventlog_creds.py +++ b/nxc/modules/eventlog_creds.py @@ -182,7 +182,7 @@ class MSEven6Trigger: class MSEven6Result: - def __init__(self, conn, handle, limit): + def __init__(self, conn, handle, limit=None): self._conn = conn self._handle = handle self._hardlimit = limit @@ -192,11 +192,12 @@ class MSEven6Result: return self def __next__(self): - self._hardlimit -= 1 - if self._hardlimit < 0: - raise StopIteration + if self._hardlimit is not None: + self._hardlimit -= 1 + if self._hardlimit < 0: + raise StopIteration if self._resp is not None and self._resp["NumActualRecords"] == 0: - return None + raise StopIteration if self._resp is None or self._index == self._resp["NumActualRecords"]: req = even6.EvtRpcQueryNext() From 379641e25cfa9601649f62cd816aaf73df7f011a Mon Sep 17 00:00:00 2001 From: Alexander Neff Date: Sun, 25 May 2025 09:48:38 -0400 Subject: [PATCH 2/3] Allow setting the limit to UNLIMITED --- nxc/modules/eventlog_creds.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/nxc/modules/eventlog_creds.py b/nxc/modules/eventlog_creds.py index 4d2cd283..2c5d2bea 100644 --- a/nxc/modules/eventlog_creds.py +++ b/nxc/modules/eventlog_creds.py @@ -20,13 +20,13 @@ class NXCModule: self.context = None self.module_options = None self.method = "execute" - self.limit = 1000 + self.limit = None def options(self, context, module_options): """ - METHOD EventLog method (Execute or RPCCALL) + METHOD EventLog method (Execute or RPCCALL), default: execute M Alias for METHOD - LIMIT Limit of the number of records to be fetched + LIMIT Limit of the number of records to be fetched, default: unlimited L Alias for LIMIT """ if "METHOD" in module_options: @@ -92,11 +92,12 @@ class NXCModule: def on_admin_login(self, context, connection): content = "" - if self.method[:1].lower() == "e": + if self.method.lower().startswith("e"): + limit_str = f"/c:{self.limit}" if self.limit is not None else "" # https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-10/security/threat-protection/auditing/event-4688 commands = [ - f'wevtutil qe Security /c:{self.limit} /f:text /rd:true /q:"*[System[(EventID=4688)]]" |findstr "Command Line"', - f'wevtutil qe Microsoft-Windows-Sysmon/Operational /c:{self.limit} /f:text /rd:true /q:"*[System[(EventID=1)]]" |findstr "ParentCommandLine"' + f'wevtutil qe Microsoft-Windows-Sysmon/Operational {limit_str} /f:text /rd:true /q:"*[System[(EventID=1)]]" | findstr "ParentCommandLine"', + f'wevtutil qe Security {limit_str} /f:text /rd:true /q:"*[System[(EventID=4688)]]" | findstr "Command Line"', ] for command in commands: context.log.debug("Execute Command: " + command) From 2c12ab72028153c36a255697bcdb62230b63b849 Mon Sep 17 00:00:00 2001 From: Alexander Neff Date: Sun, 25 May 2025 09:48:58 -0400 Subject: [PATCH 3/3] Improve regex match and reduce false positives --- nxc/modules/eventlog_creds.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/nxc/modules/eventlog_creds.py b/nxc/modules/eventlog_creds.py index 2c5d2bea..dccb9d6b 100644 --- a/nxc/modules/eventlog_creds.py +++ b/nxc/modules/eventlog_creds.py @@ -41,8 +41,6 @@ class NXCModule: def find_credentials(self, content, context): # remove unnecessary words content = content.replace("\r\n", "\n") - content = content.replace("/add", "") - content = content.replace("/active:yes", "") # sort and unique lines content = "\n".join(sorted(set(content.split("\n")))) @@ -66,9 +64,16 @@ class NXCModule: # Extracting credentials for line in content.split("\n"): for reg in regexps: - # verbose context.log.debug("Line: " + line) - # verbose context.log.debug("Reg: " + reg) - match = re.search(reg, line, re.IGNORECASE) + # Remove unnecessary words + line_stripped = line.replace("/add", "") \ + .replace("/active:yes", "") \ + .replace("/delete", "") \ + .replace("/domain", "") \ + # Remove command lines that were executed with nxc + line_stripped = re.sub(r"1> \\Windows\\Temp\\[\w]{6} 2>&1", "", line_stripped) + + # Use regex to find credentials + match = re.search(reg, line_stripped, re.IGNORECASE) if match: # eleminate false positives # C:\Windows\system32\svchost.exe -k DcomLaunch -p -s PlugPlay @@ -128,7 +133,6 @@ class NXCModule: content += "CommandLine: " + match.group("CommandLine") + "\n" except Exception as e: context.log.error(f"Error: {e}") - continue self.find_credentials(content, context)