Skip to content

Commit 574afc0

Browse files
Merge branch 'main' into 281-multi-file-put
2 parents 3216380 + 535a106 commit 574afc0

3 files changed

Lines changed: 62 additions & 14 deletions

File tree

netexec.spec

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ a = Analysis(
4242
'nxc.helpers.bash',
4343
'nxc.helpers.bloodhound',
4444
'nxc.helpers.msada_guids',
45+
'nxc.helpers.ntlm_parser',
4546
'paramiko',
4647
'pypsrp.client',
4748
'pywerview.cli.helpers',

nxc/logger.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ def setup_debug_logging():
3030
root_logger.setLevel(logging.INFO)
3131
elif debug_args.debug:
3232
nxc_logger.logger.setLevel(logging.DEBUG)
33-
root_logger.setLevel(logging.DEBUG)
33+
root_logger.setLevel(logging.INFO)
3434
else:
3535
nxc_logger.logger.setLevel(logging.ERROR)
3636
root_logger.setLevel(logging.ERROR)
@@ -53,13 +53,15 @@ def __init__(self, formatter=None, *args, **kwargs):
5353

5454
def emit(self, record):
5555
"""Overrides the emit method of the RichHandler class so we can set the proper pathname and lineno"""
56+
# for some reason in RDP, the exc_text is None which leads to a KeyError in Python logging
57+
record.exc_text = record.getMessage() if record.exc_text is None else record.exc_text
58+
5659
if hasattr(record, "caller_frame"):
5760
frame_info = inspect.getframeinfo(record.caller_frame)
5861
record.pathname = frame_info.filename
5962
record.lineno = frame_info.lineno
6063
super().emit(record)
6164

62-
6365
def no_debug(func):
6466
"""Stops logging non-debug messages when we are in debug mode
6567
It creates a temporary logger and logs the message to the console and file

tests/e2e_tests.py

Lines changed: 57 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import os
33
import subprocess
44
from rich.console import Console
5+
import platform
56

67

78
def get_cli_args():
@@ -60,25 +61,59 @@ def get_cli_args():
6061
required=False,
6162
help="Protocols to test",
6263
)
63-
64+
parser.add_argument(
65+
"--line-nums",
66+
nargs="+",
67+
type=parse_line_nums,
68+
required=False,
69+
help="Specify line numbers or ranges to run commands from",
70+
)
71+
parser.add_argument(
72+
"--print-failures",
73+
action="store_true",
74+
required=False,
75+
help="Prints all the commands of failed tests at the end"
76+
)
6477
return parser.parse_args()
6578

79+
def parse_line_nums(value):
80+
line_nums = []
81+
for item in value.split():
82+
if "-" in item:
83+
start, end = item.split("-")
84+
line_nums.extend(range(int(start), int(end) + 1))
85+
else:
86+
line_nums.append(int(item))
87+
return line_nums
6688

6789
def generate_commands(args):
6890
lines = []
6991
file_loc = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__)))
7092
commands_file = os.path.join(file_loc, "e2e_commands.txt")
7193

7294
with open(commands_file) as file:
73-
for line in file:
74-
if line.startswith("#"):
75-
continue
76-
line = line.strip()
77-
if args.protocols:
78-
if line.split()[1] in args.protocols:
95+
if args.line_nums:
96+
flattened_list = list({num for sublist in args.line_nums for num in sublist})
97+
for i, line in enumerate(file):
98+
if i + 1 in flattened_list:
99+
if line.startswith("#"):
100+
continue
101+
line = line.strip()
102+
if args.protocols:
103+
if line.split()[1] in args.protocols:
104+
lines.append(replace_command(args, line))
105+
else:
106+
lines.append(replace_command(args, line))
107+
else:
108+
for line in file:
109+
if line.startswith("#"):
110+
continue
111+
line = line.strip()
112+
if args.protocols:
113+
if line.split()[1] in args.protocols:
114+
lines.append(replace_command(args, line))
115+
else:
79116
lines.append(replace_command(args, line))
80-
else:
81-
lines.append(replace_command(args, line))
82117
return lines
83118

84119
def replace_command(args, line):
@@ -93,6 +128,7 @@ def replace_command(args, line):
93128
def run_e2e_tests(args):
94129
console = Console()
95130
tasks = generate_commands(args)
131+
failures = []
96132

97133
result = subprocess.Popen(
98134
"netexec --version",
@@ -107,10 +143,13 @@ def run_e2e_tests(args):
107143
failed = 0
108144

109145
while tasks:
110-
task = tasks.pop(0)
111-
console.log(f"Running command: {task!s}")
146+
task = str(tasks.pop(0))
147+
# replace double quotes with single quotes for Linux due to special chars/escaping
148+
if platform.system() == "Linux":
149+
task = task.replace('"', "'")
150+
console.log(f"Running command: {task}")
112151
result = subprocess.Popen(
113-
str(task),
152+
task,
114153
shell=True,
115154
stdin=subprocess.PIPE,
116155
stdout=subprocess.PIPE,
@@ -125,6 +164,7 @@ def run_e2e_tests(args):
125164
passed += 1
126165
else:
127166
console.log(f"[bold red]{task.strip()} :cross_mark:[/]")
167+
failures.append(task.strip())
128168
failed += 1
129169

130170
if args.errors:
@@ -136,6 +176,11 @@ def run_e2e_tests(args):
136176
if args.verbose:
137177
# this prints sorta janky, but it does its job
138178
console.log(f"[*] Results:\n{text.decode('utf-8')}")
179+
180+
if args.print_failures and failures:
181+
console.log("[bold red]Failed Commands:")
182+
for failure in failures:
183+
console.log(f"[bold red]{failure}")
139184
console.log(f"Tests [bold green] Passed: {passed} [bold red] Failed: {failed}")
140185

141186

0 commit comments

Comments
 (0)