From 7531bf62d50e65ab30b7feb503f86c321e4782dc Mon Sep 17 00:00:00 2001 From: Adam Hassan Date: Wed, 7 May 2025 00:26:38 -0400 Subject: [PATCH] add initial rdp exec code based on winrm --- nxc/protocols/rdp.py | 19 +++++++++++++++++++ nxc/protocols/rdp/proto_args.py | 13 +++++++++++++ 2 files changed, 32 insertions(+) diff --git a/nxc/protocols/rdp.py b/nxc/protocols/rdp.py index d9656694..81e6a8ef 100644 --- a/nxc/protocols/rdp.py +++ b/nxc/protocols/rdp.py @@ -357,6 +357,25 @@ class rdp(connection): color=("magenta" if ((reason or "CredSSP" in str(e)) and reason != "STATUS_LOGON_FAILURE") else "red"), ) return False + + def execute(self, payload=None, get_output=True, shell_type="cmd"): + if not payload: + payload = self.args.execute + + if self.args.no_output: + get_output = False + + try: + result = self.conn.execute_cmd(payload, encoding=self.args.codec) if shell_type == "cmd" else self.conn.execute_ps(payload) + except Exception as e: + self.logger.info("Cannot execute command via cmd - now switching to Powershell to attempt execution") + try: + self.execute(payload, get_output, shell_type="poewrshell") + except Exception as e: + self.logger.fail(f"Execute command failed, error: {e!s}") + + def ps_execute(self): + self.sexecute(payload=self.args.ps_execute, get_output=True, shell_type="powershell") async def screen(self): try: diff --git a/nxc/protocols/rdp/proto_args.py b/nxc/protocols/rdp/proto_args.py index 13b972cf..943f7aff 100644 --- a/nxc/protocols/rdp/proto_args.py +++ b/nxc/protocols/rdp/proto_args.py @@ -17,4 +17,17 @@ def proto_args(parser, parents): egroup.add_argument("--screentime", type=int, default=10, help="Time to wait for desktop image") egroup.add_argument("--res", default="1024x768", help="Resolution in WIDTHxHEIGHT format") + cmd_exec_group = rdp_parser.add_argument_group("Command Execution", "Options for executing commands") + cmd_exec_group.add_argument("--exec-method", choices={"wmiexec", "mmcexec", "smbexec", "atexec"}, default="wmiexec", help="method to execute the command. Ignored if in MSSQL mode", action=DefaultTrackingAction) + cmd_exec_group.add_argument("--dcom-timeout", help="DCOM connection timeout", type=int, default=5) + cmd_exec_group.add_argument("--get-output-tries", help="Number of times atexec/smbexec/mmcexec tries to get results", type=int, default=10) + cmd_exec_group.add_argument("--codec", default="utf-8", help="Set encoding used (codec) from the target's output. If errors are detected, run chcp.com at the target & map the result with https://docs.python.org/3/library/codecs.html#standard-encodings and then execute again with --codec and the corresponding codec") + cmd_exec_group.add_argument("--no-output", action="store_true", help="do not retrieve command output") + + cgroup = rdp_parser.add_argument_group("Command Execution", "Options for executing commands") + cgroup.add_argument("--codec", default="utf-8", help="Set encoding used (codec) from the target's output. If errors are detected, run chcp.com at the target & map the result with https://docs.python.org/3/library/codecs.html#standard-encodings and then execute again with --codec and the corresponding codec") + cgroup.add_argument("--no-output", action="store_true", help="do not retrieve command output") + cgroup.add_argument("-x", metavar="COMMAND", dest="execute", help="execute the specified command") + cgroup.add_argument("-X", metavar="PS_COMMAND", dest="ps_execute", help="execute the specified PowerShell command") + return parser