Skip to content

Commit ffa4636

Browse files
committed
Execute each command seperatly so files are still deleted when previous commands fail
1 parent 50edae4 commit ffa4636

2 files changed

Lines changed: 13 additions & 8 deletions

File tree

nxc/protocols/wmi/proto_args.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ def proto_args(parser, parents):
1717
cgroup.add_argument("--no-output", action="store_true", help="do not retrieve command output")
1818
cgroup.add_argument("-x", metavar="COMMAND", dest="execute", type=str, help="Creates a new cmd process and executes the specified command with output")
1919
cgroup.add_argument("--exec-method", choices={"wmiexec", "wmiexec-event"}, default="wmiexec", help="method to execute the command. (default: wmiexec). [wmiexec (win32_process + StdRegProv)]: get command results over registry instead of using smb connection. [wmiexec-event (T1546.003)]: this method is not very stable, highly recommend use this method in single host, using on multiple hosts may crash (just try again if it crashed).")
20-
cgroup.add_argument("--exec-timeout", default=5, metavar="exec_timeout", dest="exec_timeout", type=int, help="Set timeout (in seconds) when executing a command, minimum 5 seconds is recommended. Default: %(default)s")
20+
cgroup.add_argument("--exec-timeout", default=3, metavar="exec_timeout", dest="exec_timeout", type=int, help="Set timeout (in seconds) when executing a command, minimum 5 seconds is recommended. Default: %(default)s")
2121
cgroup.add_argument("--codec", default="utf-8", help="Set encoding used (codec) from the target's output (default: utf-8). 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")
2222
return parser
2323

nxc/protocols/wmi/wmiexec.py

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ def __init__(self, target, username, password, domain, lmhash, nthash, doKerbero
3939
self.__exec_timeout = exec_timeout
4040
self.__registry_Path = ""
4141
self.__outputBuffer = ""
42-
self.__retOutput = True
4342

4443
self.__shell = "cmd.exe /Q /c "
4544
self.__pwd = "C:\\"
@@ -53,8 +52,7 @@ def __init__(self, target, username, password, domain, lmhash, nthash, doKerbero
5352
self.__win32Process, _ = self.__iWbemServices.GetObject("Win32_Process")
5453

5554
def execute(self, command, output=False):
56-
self.__retOutput = output
57-
if self.__retOutput:
55+
if output:
5856
self.execute_WithOutput(command)
5957
else:
6058
command = self.__shell + command
@@ -77,9 +75,16 @@ def execute_WithOutput(self, command):
7775
keyName = str(uuid.uuid4())
7876
self.__registry_Path = f"Software\\Classes\\{gen_random_string(6)}"
7977

80-
command = rf"""{self.__shell} {command} 1> {result_output} 2>&1 && certutil -encodehex -f {result_output} {result_output_b64} 0x40000001 && for /F "usebackq" %G in ("{result_output_b64}") do reg add HKLM\{self.__registry_Path} /v {keyName} /t REG_SZ /d "%G" /f && del /q /f /s {result_output} {result_output_b64}"""
78+
commands = [
79+
f"{self.__shell} {command} 1> {result_output} 2>&1",
80+
f"{self.__shell} certutil -encodehex -f {result_output} {result_output_b64} 0x40000001",
81+
f'{self.__shell} for /F "usebackq" %G in ("{result_output_b64}") do reg add HKLM\\{self.__registry_Path} /v {keyName} /t REG_SZ /d "%G" /f',
82+
f"{self.__shell} del /q /f /s {result_output} {result_output_b64}",
83+
]
8184

82-
self.execute_remote(command)
85+
for cmd in commands:
86+
self.execute_remote(cmd)
87+
time.sleep(0.5)
8388
self.logger.info(f"Waiting {self.__exec_timeout}s for command completely executed.")
8489
time.sleep(self.__exec_timeout)
8590

@@ -90,13 +95,13 @@ def queryRegistry(self, keyName):
9095
self.logger.debug(f"Querying registry key: HKLM\\{self.__registry_Path}")
9196
descriptor, _ = self.__iWbemServices.GetObject("StdRegProv")
9297
descriptor = descriptor.SpawnInstance()
93-
retVal = descriptor.GetStringValue(2147483650, self.__registry_Path, keyName)
98+
retVal = descriptor.GetStringValue(0x80000002, self.__registry_Path, keyName)
9499
self.__outputBuffer = base64.b64decode(retVal.sValue).decode(self.__codec, errors="replace").rstrip("\r\n")
95100
except Exception:
96101
self.logger.fail("WMIEXEC: Could not retrieve output file, it may have been detected by AV. Please try increasing the timeout with the '--exec-timeout' option. If it is still failing, try the 'smb' protocol or another exec method")
97102

98103
try:
99104
self.logger.debug(f"Removing temporary registry path: HKLM\\{self.__registry_Path}")
100-
retVal = descriptor.DeleteKey(2147483650, self.__registry_Path)
105+
retVal = descriptor.DeleteKey(0x80000002, self.__registry_Path)
101106
except Exception as e:
102107
self.logger.debug(f"Target: {self.__target} removing temporary registry path error: {e!s}")

0 commit comments

Comments
 (0)