Skip to content

Commit

Permalink
Change wmi --interval-time to --exec-timeout to more accuratly repres…
Browse files Browse the repository at this point in the history
…ent the effect
  • Loading branch information
NeffIsBack committed Sep 9, 2023
1 parent 2400bc6 commit 4a739a0
Show file tree
Hide file tree
Showing 4 changed files with 14 additions and 14 deletions.
6 changes: 3 additions & 3 deletions cme/protocols/wmi.py
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,7 @@ def execute(self, command=None, get_output=False):
if not self.args.no_output:
get_output = True

if "systeminfo" in command and self.args.interval_time < 10:
if "systeminfo" in command and self.args.exec_timeout < 10:
self.logger.fail("Execute 'systeminfo' must set the interval time higher than 10 seconds")
return False

Expand All @@ -441,11 +441,11 @@ def execute(self, command=None, get_output=False):
return False

if self.args.exec_method == "wmiexec":
exec_method = wmiexec.WMIEXEC(self.conn.getRemoteName(), self.username, self.password, self.domain, self.lmhash, self.nthash, self.doKerberos, self.kdcHost, self.aesKey, self.logger, self.args.interval_time, self.args.codec)
exec_method = wmiexec.WMIEXEC(self.conn.getRemoteName(), self.username, self.password, self.domain, self.lmhash, self.nthash, self.doKerberos, self.kdcHost, self.aesKey, self.logger, self.args.exec_timeout, self.args.codec)
output = exec_method.execute(command, get_output)

elif self.args.exec_method == "wmiexec-event":
exec_method = wmiexec_event.WMIEXEC_EVENT(self.conn.getRemoteName(), self.username, self.password, self.domain, self.lmhash, self.nthash, self.doKerberos, self.kdcHost, self.aesKey, self.logger, self.args.interval_time, self.args.codec)
exec_method = wmiexec_event.WMIEXEC_EVENT(self.conn.getRemoteName(), self.username, self.password, self.domain, self.lmhash, self.nthash, self.doKerberos, self.kdcHost, self.aesKey, self.logger, self.args.exec_timeout, self.args.codec)
output = exec_method.execute(command, get_output)

self.conn.disconnect()
Expand Down
2 changes: 1 addition & 1 deletion cme/protocols/wmi/proto_args.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def proto_args(parser, std_parser, module_parser):
"[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).")
cgroup.add_argument("--interval-time", default=5 ,metavar='INTERVAL_TIME', dest='interval_time', type=int, help='Set interval time(seconds) when executing command, unrecommend set it lower than 5')
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')
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, "
Expand Down
10 changes: 5 additions & 5 deletions cme/protocols/wmi/wmiexec.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
from impacket.dcerpc.v5.dcom.wmi import CLSID_WbemLevel1Login, IID_IWbemLevel1Login, WBEM_FLAG_FORWARD_ONLY, IWbemLevel1Login

class WMIEXEC:
def __init__(self, host, username, password, domain, lmhash, nthash, doKerberos, kdcHost, aesKey, logger, interval_time, codec):
def __init__(self, host, username, password, domain, lmhash, nthash, doKerberos, kdcHost, aesKey, logger, exec_timeout, codec):
self.__host = host
self.__username = username
self.__password = password
Expand All @@ -45,7 +45,7 @@ def __init__(self, host, username, password, domain, lmhash, nthash, doKerberos,
self.__kdcHost = kdcHost
self.__aesKey = aesKey
self.logger = logger
self.__interval_time = interval_time
self.__exec_timeout = exec_timeout
self.__registry_Path = ""
self.__outputBuffer = ""
self.__retOutput = True
Expand Down Expand Up @@ -91,8 +91,8 @@ def execute_WithOutput(self, command):
command = fr'''{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}'''

self.execute_remote(command)
self.logger.info("Waiting {}s for command completely executed.".format(self.__interval_time))
time.sleep(self.__interval_time)
self.logger.info("Waiting {}s for command completely executed.".format(self.__exec_timeout))
time.sleep(self.__exec_timeout)

self.queryRegistry(keyName)

Expand All @@ -104,7 +104,7 @@ def queryRegistry(self, keyName):
retVal = descriptor.GetStringValue(2147483650, self.__registry_Path, keyName)
self.__outputBuffer = base64.b64decode(retVal.sValue).decode(self.__codec, errors='replace').rstrip('\r\n')
except Exception as e:
self.logger.fail(f'WMIEXEC: Get output file error, maybe command not executed successfully or got detected by AV software, please increase the interval time of command execution with "--interval-time" option. If it\'s still failing maybe something is blocking the schedule job in vbscript, try another exec method')
self.logger.fail(f'WMIEXEC: Couldn\'t retrieve output-file. Either command timed out or got detected by AV. Try increasing the timeout with "--exec-timeout" option. If it\'s still failing, try the smb protocol or another exec method')

try:
self.logger.debug(f"Removing temporary registry path: HKLM\\{self.__registry_Path}")
Expand Down
10 changes: 5 additions & 5 deletions cme/protocols/wmi/wmiexec_event.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
from impacket.dcerpc.v5.dcom.wmi import CLSID_WbemLevel1Login, IID_IWbemLevel1Login, WBEM_FLAG_FORWARD_ONLY, IWbemLevel1Login, WBEMSTATUS

class WMIEXEC_EVENT:
def __init__(self, host, username, password, domain, lmhash, nthash, doKerberos, kdcHost, aesKey, logger, interval_time, codec):
def __init__(self, host, username, password, domain, lmhash, nthash, doKerberos, kdcHost, aesKey, logger, exec_timeout, codec):
self.__host = host
self.__username = username
self.__password = password
Expand All @@ -51,7 +51,7 @@ def __init__(self, host, username, password, domain, lmhash, nthash, doKerberos,
self.__retOutput = True

self.logger = logger
self.__interval_time = interval_time
self.__exec_timeout = exec_timeout
self.__codec = codec
self.__instanceID = f"windows-object-{str(uuid.uuid4())}"
self.__instanceID_StoreResult = f"windows-object-{str(uuid.uuid4())}"
Expand Down Expand Up @@ -84,8 +84,8 @@ def execute_handler(self, command):
self.execute_remote(command)

# Get command results
self.logger.info("Waiting {}s for command completely executed.".format(self.__interval_time))
time.sleep(self.__interval_time)
self.logger.info("Waiting {}s for command completely executed.".format(self.__exec_timeout))
time.sleep(self.__exec_timeout)

if self.__retOutput:
self.get_CommandResult()
Expand Down Expand Up @@ -190,7 +190,7 @@ def get_CommandResult(self):
record = dict(command_ResultObject.getProperties())
self.__outputBuffer = base64.b64decode(record['ScriptText']['value']).decode(self.__codec, errors='replace')
except Exception as e:
self.logger.fail(f'WMIEXEC-EVENT: Get output file error, maybe command not executed successfully or got detected by AV software, please increase the interval time of command execution with "--interval-time" option. If it\'s still failing maybe something is blocking the schedule job in vbscript, try another exec method')
self.logger.fail(f'WMIEXEC-EVENT: Couldn\'t retrieve output-file. Either command timed out or got detected by AV. Try increasing the timeout with "--exec-timeout" option. If it\'s still failing, try the smb protocol or another exec method')

def remove_Instance(self):
if self.__retOutput:
Expand Down

0 comments on commit 4a739a0

Please sign in to comment.