diff --git a/nxc/protocols/mssql.py b/nxc/protocols/mssql.py index bb6da7a4..71b928e4 100755 --- a/nxc/protocols/mssql.py +++ b/nxc/protocols/mssql.py @@ -322,41 +322,34 @@ class mssql(connection): return raw_output @requires_admin - def execute(self, payload=None, print_output=False): + def execute(self, payload=None, get_output=False): if not payload and self.args.execute: payload = self.args.execute - self.logger.info(f"Command to execute:\n{payload}") + if not self.args.no_output: + get_output = True + + self.logger.info(f"Command to execute: {payload}") try: - exec_method = MSSQLEXEC(self.conn) - raw_output = exec_method.execute(payload, print_output) - self.logger.info("Executed command via mssqlexec") - self.logger.debug(f"Raw output: {raw_output}") + exec_method = MSSQLEXEC(self.conn, self.logger) + raw_output = exec_method.execute(payload, get_output) except Exception as e: - self.logger.exception(e) - return None - - if hasattr(self, "server"): - self.server.track_host(self.host) - - if self.args.execute or self.args.ps_execute: + self.logger.fail(f"Execute command failed, error: {e!s}") + return False + else: self.logger.success("Executed command via mssqlexec") - if self.args.no_output: - self.logger.debug("Output set to disabled") - else: + if raw_output: for line in raw_output: self.logger.highlight(line) - - return raw_output + return raw_output @requires_admin def ps_execute( self, payload=None, get_output=False, - methods=None, force_ps32=False, - dont_obfs=True, + dont_obfs=False, ): if not payload and self.args.ps_execute: payload = self.args.ps_execute @@ -374,7 +367,7 @@ class mssql(connection): try: data = f.read() self.logger.display(f"Size is {len(data)} bytes") - exec_method = MSSQLEXEC(self.conn) + exec_method = MSSQLEXEC(self.conn, self.logger) exec_method.put_file(data, self.args.put_file[1]) if exec_method.file_exists(self.args.put_file[1]): self.logger.success("File has been uploaded on the remote machine") @@ -390,7 +383,7 @@ class mssql(connection): self.logger.display(f'Copying "{remote_path}" to "{download_path}"') try: - exec_method = MSSQLEXEC(self.conn) + exec_method = MSSQLEXEC(self.conn, self.logger) exec_method.get_file(self.args.get_file[0], self.args.get_file[1]) self.logger.success(f'File "{remote_path}" was downloaded to "{download_path}"') except Exception as e: diff --git a/nxc/protocols/mssql/mssql_ntlm_parser.py b/nxc/protocols/mssql/mssql_ntlm_parser.py index 2ca8ea55..3d4506df 100644 --- a/nxc/protocols/mssql/mssql_ntlm_parser.py +++ b/nxc/protocols/mssql/mssql_ntlm_parser.py @@ -2,6 +2,7 @@ import datetime + def decoder(byte_string, decode_type): if decode_type == "byte": return byte_string.decode("UTF-8").replace("\x00", "") diff --git a/nxc/protocols/mssql/mssqlexec.py b/nxc/protocols/mssql/mssqlexec.py index a2081a99..5272b631 100755 --- a/nxc/protocols/mssql/mssqlexec.py +++ b/nxc/protocols/mssql/mssqlexec.py @@ -1,38 +1,38 @@ import binascii -from nxc.logger import nxc_logger class MSSQLEXEC: - def __init__(self, connection): + def __init__(self, connection, logger): self.mssql_conn = connection - self.outputBuffer = "" + self.outputBuffer = [] + self.logger = logger def execute(self, command, output=False): - command_output = [] try: self.enable_xp_cmdshell() except Exception as e: - nxc_logger.error(f"Error when attempting to enable x_cmdshell: {e}") + self.logger.error(f"Error when attempting to enable x_cmdshell: {e}") + try: result = self.mssql_conn.sql_query(f"exec master..xp_cmdshell '{command}'") - nxc_logger.debug(f"SQL Query Result: {result}") - for row in result: - if row["output"] == "NULL": - continue - command_output.append(row["output"]) except Exception as e: - nxc_logger.error(f"Error when attempting to execute command via xp_cmdshell: {e}") + self.logger.error(f"Error when attempting to execute command via xp_cmdshell: {e}") - if output: - nxc_logger.debug("Output is enabled") - for row in command_output: - nxc_logger.debug(row) - # if len(self.outputBuffer): try: self.disable_xp_cmdshell() except Exception as e: - nxc_logger.error(f"[OPSEC] Error when attempting to disable xp_cmdshell: {e}") - return command_output + self.logger.error(f"[OPSEC] Error when attempting to disable xp_cmdshell: {e}") + + if output: + self.logger.debug(f"SQL Query Result: {result}") + for row in result: + if row["output"] == "NULL": + continue + self.outputBuffer.append(row["output"]) + else: + self.logger.info("Output set to disabled") + + return self.outputBuffer def enable_xp_cmdshell(self): self.mssql_conn.sql_query("exec master.dbo.sp_configure 'show advanced options',1;RECONFIGURE;exec master.dbo.sp_configure 'xp_cmdshell', 1;RECONFIGURE;") @@ -53,7 +53,7 @@ class MSSQLEXEC: self.mssql_conn.sql_query(f"DECLARE @ob INT;EXEC sp_OACreate 'ADODB.Stream', @ob OUTPUT;EXEC sp_OASetProperty @ob, 'Type', 1;EXEC sp_OAMethod @ob, 'Open';EXEC sp_OAMethod @ob, 'Write', NULL, 0x{hexdata};EXEC sp_OAMethod @ob, 'SaveToFile', NULL, '{remote}', 2;EXEC sp_OAMethod @ob, 'Close';EXEC sp_OADestroy @ob;") self.disable_ole() except Exception as e: - nxc_logger.debug(f"Error uploading via mssqlexec: {e}") + self.logger.debug(f"Error uploading via mssqlexec: {e}") def file_exists(self, remote): try: @@ -71,4 +71,4 @@ class MSSQLEXEC: f.write(binascii.unhexlify(data)) except Exception as e: - nxc_logger.debug(f"Error downloading via mssqlexec: {e}") + self.logger.debug(f"Error downloading via mssqlexec: {e}") diff --git a/nxc/protocols/mssql/proto_args.py b/nxc/protocols/mssql/proto_args.py index 4ee7fcc8..6f4d3641 100644 --- a/nxc/protocols/mssql/proto_args.py +++ b/nxc/protocols/mssql/proto_args.py @@ -25,8 +25,8 @@ def proto_args(parser, std_parser, module_parser): psgroup.add_argument("--clear-obfscripts", action="store_true", help="Clear all cached obfuscated PowerShell scripts") tgroup = mssql_parser.add_argument_group("Files", "Options for put and get remote files") - tgroup.add_argument("--put-file", nargs=2, metavar="FILE", help="Put a local file into remote target, ex: whoami.txt C:\\Windows\\Temp\\whoami.txt") - tgroup.add_argument("--get-file", nargs=2, metavar="FILE", help="Get a remote file, ex: C:\\Windows\\Temp\\whoami.txt whoami.txt") + tgroup.add_argument("--put-file", nargs=2, metavar=("SRC_FILE", "DEST_FILE"), help="Put a local file into remote target, ex: whoami.txt C:\\Windows\\Temp\\whoami.txt") + tgroup.add_argument("--get-file", nargs=2, metavar=("SRC_FILE", "DEST_FILE"), help="Get a remote file, ex: C:\\Windows\\Temp\\whoami.txt whoami.txt") return parser