Skip to content

Commit bab59de

Browse files
committed
Optimize execution speed
1 parent e192f3c commit bab59de

2 files changed

Lines changed: 16 additions & 19 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=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")
20+
cgroup.add_argument("--exec-timeout", default=2, 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: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -73,35 +73,32 @@ def execute_WithOutput(self, command):
7373
result_output = f"C:\\windows\\temp\\{uuid.uuid4()!s}.txt"
7474
result_output_b64 = f"C:\\windows\\temp\\{uuid.uuid4()!s}.txt"
7575
keyName = str(uuid.uuid4())
76-
self.__registry_Path = f"Software\\Classes\\{gen_random_string(6)}"
76+
self.__registry_Path = f"Software\\Classes\\test_nxc_{gen_random_string(6)}"
7777

78-
commands = [
79-
# 1. Run the command and write output to file
80-
f'{self.__shell} {command} 1> "{result_output}" 2>&1',
78+
# 1. Run the command and write output to file
79+
self.execute_remote(f'{self.__shell} {command} 1> "{result_output}" 2>&1')
80+
self.logger.info(f"Waiting {self.__exec_timeout}s for command to complete.")
81+
time.sleep(self.__exec_timeout)
8182

82-
# 2. Base64 encode the file using PowerShell
83-
f'{self.__shell} powershell -Command "[Convert]::ToBase64String([IO.File]::ReadAllBytes(\'{result_output}\')) | Out-File -Encoding ASCII \'{result_output_b64}\'"',
83+
# 2. Base64 encode the file using PowerShell
84+
self.execute_remote(f'{self.__shell} powershell -Command "[Convert]::ToBase64String([IO.File]::ReadAllBytes(\'{result_output}\')) | Out-File -Encoding ASCII \'{result_output_b64}\'"')
85+
time.sleep(0.5)
8486

85-
# 3. Use PowerShell to split base64 content into 16KB chunks and store in registry
87+
# 3. Use PowerShell to split base64 content into 16KB chunks and store in registry
88+
self.execute_remote(
8689
f'{self.__shell} powershell -Command "$b64 = Get-Content -Raw \'{result_output_b64}\'; '
8790
f'$chunksize = 16000; '
8891
f'$count = [math]::Ceiling($b64.Length / $chunksize); '
8992
f'for ($i = 0; $i -lt $count; $i++) {{ '
9093
f' $chunk = $b64.Substring($i * $chunksize, [math]::Min($chunksize, $b64.Length - ($i * $chunksize))); '
9194
f' $name = \\"{keyName}_chunk_$i\\"; '
9295
f' reg add \\"HKLM\\{self.__registry_Path}\\" /v $name /t REG_SZ /d $chunk /f }}; '
93-
f'reg add \\"HKLM\\{self.__registry_Path}\\" /v \\"{keyName}\\" /t REG_DWORD /d $count /f"',
94-
95-
# 4. Delete temporary files
96-
f'{self.__shell} del /q /f "{result_output}" "{result_output_b64}"'
97-
]
96+
f'reg add \\"HKLM\\{self.__registry_Path}\\" /v \\"{keyName}\\" /t REG_DWORD /d $count /f"'
97+
)
98+
time.sleep(1)
9899

99-
for cmd in commands:
100-
self.execute_remote(cmd)
101-
time.sleep(0.5)
102-
103-
self.logger.info(f"Waiting {self.__exec_timeout}s for command to complete.")
104-
time.sleep(self.__exec_timeout)
100+
# 4. Delete temporary files
101+
self.execute_remote(f'{self.__shell} del /q /f "{result_output}" "{result_output_b64}"')
105102

106103
self.queryRegistry(keyName)
107104

0 commit comments

Comments
 (0)