diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
new file mode 100644
index 00000000..423f56d5
--- /dev/null
+++ b/.github/CODEOWNERS
@@ -0,0 +1,6 @@
+##########################################
+# code ownership
+##########################################
+
+# default ownership:
+* @zblurx @Marshall-Hallenbeck @NeffIsBack
\ No newline at end of file
diff --git a/.github/workflows/crackmapexec-test.yml b/.github/workflows/crackmapexec-test.yml
index bc6fcb63..3769e312 100644
--- a/.github/workflows/crackmapexec-test.yml
+++ b/.github/workflows/crackmapexec-test.yml
@@ -1,11 +1,8 @@
name: CrackMapExec Tests
on:
- workflow_dispatch:
- push:
- branches: [ master ]
- pull_request:
- branches: [ master ]
+ pull_request_review:
+ types: [submitted]
jobs:
build:
diff --git a/.github/workflows/crackmapexec.yml b/.github/workflows/crackmapexec.yml
index e1ab04d1..c8067330 100644
--- a/.github/workflows/crackmapexec.yml
+++ b/.github/workflows/crackmapexec.yml
@@ -1,12 +1,7 @@
-name: CrackMapExec Tests & Build
+name: CrackMapExec Build Binaries
on:
workflow_dispatch:
- branches: [ main ]
- push:
- branches: [ main ]
- pull_request:
- branches: [ main ]
jobs:
build:
diff --git a/README.md b/README.md
index becafb58..3dacb6e5 100755
--- a/README.md
+++ b/README.md
@@ -1,58 +1,37 @@
![Supported Python versions](https://img.shields.io/badge/python-3.7+-blue.svg)
-[![Twitter](https://img.shields.io/twitter/follow/byt3bl33d3r?label=byt3bl33d3r&style=social)](https://twitter.com/intent/follow?screen_name=byt3bl33d3r)
-[![Twitter](https://img.shields.io/twitter/follow/mpgn_x64?label=mpgn_x64&style=social)](https://twitter.com/intent/follow?screen_name=mpgn_x64)
[![Twitter](https://img.shields.io/twitter/follow/al3xn3ff?label=al3x_n3ff&style=social)](https://twitter.com/intent/follow?screen_name=al3x_n3ff)
[![Twitter](https://img.shields.io/twitter/follow/_zblurx?label=_zblurx&style=social)](https://twitter.com/intent/follow?screen_name=_zblurx)
[![Twitter](https://img.shields.io/twitter/follow/MJHallenbeck?label=MJHallenbeck&style=social)](https://twitter.com/intent/follow?screen_name=MJHallenbeck)
-🚩 This is the open source repository of CrackMapExec maintained by a community of passionate people
-# CrackMapExec
+🚩 This is the open source repository of NetExec maintained by a community of passionate people
+# NetExec - The Network Execution Tool
-
+
+You are on the **latest up-to-date** repository of the project NetExec (nxc) ! 🎉
-This project was initially created in 2015 by **@byt3bl33d3r**. In 2019 **@mpgn_x64** started maintaining the project. Five years and a lot of additions later, he retired from maintaining the project. Like many other contributer we (NeffIsBack, Marshall-Hallenbeck and zblurx) started working on new features, bugfixes and helped maintaining CME. With the end of mpgn's maintainer role, we decided to maintain the project together as an full open source project.
-
-You are on the **latest up-to-date** repository of the project CrackMapExec ! 🎉
-
-- 🚧 If you want to report a problem, open un [Issue](https://github.com/Pennyw0rth/CrackMapExec/issues)
-- 🔀 If you want to contribute, open a [Pull Request](https://github.com/Pennyw0rth/CrackMapExec/pulls)
-- 💬 If you want to discuss, open a [Discussion](https://github.com/Pennyw0rth/CrackMapExec/discussions)
+- 🚧 If you want to report a problem, open un [Issue](https://github.com/Pennyw0rth/NetExec/issues)
+- 🔀 If you want to contribute, open a [Pull Request](https://github.com/Pennyw0rth/NetExec/pulls)
+- 💬 If you want to discuss, open a [Discussion](https://github.com/Pennyw0rth/NetExec/discussions)
# Acknowledgments
-**(These are the people who did the hard stuff)**
+All the hard work and development over the years from everyone in the CrackMapExec project.
-This project was originally inspired by:
-- [CredCrack](https://github.com/gojhonny/CredCrack)
-- [smbexec](https://github.com/pentestgeek/smbexec)
-- [smbmap](https://github.com/ShawnDEvans/smbmap)
-
-Unintentional contributors:
-
-- The [Empire](https://github.com/PowerShellEmpire/Empire) project
-- @T-S-A's [smbspider](https://github.com/T-S-A/smbspider) script
-- @ConsciousHacker's partial Python port of Invoke-obfuscation from the [GreatSCT](https://github.com/GreatSCT/GreatSCT) project
# Documentation, Tutorials, Examples
-See the project's [wiki](https://www.crackmapexec.wiki/) for documentation and usage examples
+See the project's wiki (in development) for documentation and usage examples
# Installation
-Please see the installation instructions on the [official wiki](https://www.crackmapexec.wiki/getting-started/installation)
+Please see the installation instructions on the wiki (in development)
# Code Contributors
-
-Awesome code contributors of CME:
+Awesome code contributors of NetExec:
[![](https://github.com/mpgn.png?size=50)](https://github.com/mpgn)
[![](https://github.com/Marshall-Hallenbeck.png?size=50)](https://github.com/Marshall-Hallenbeck)
[![](https://github.com/zblurx.png?size=50)](https://github.com/zblurx)
[![](https://github.com/NeffIsBack.png?size=50)](https://github.com/NeffIsBack)
[![](https://github.com/Hackndo.png?size=50)](https://github.com/Hackndo)
-[![](https://github.com/nurfed1?size=50)](https://github.com/nurfed1)
-
-
-# To do
-- ~~0wn everything~~
diff --git a/cme/cli.py b/cme/cli.py
index 623ff288..a8f7e407 100755
--- a/cme/cli.py
+++ b/cme/cli.py
@@ -24,7 +24,8 @@ def gen_cli_args():
\______|| _| `._____|/__/ \__\ \______||__|\__\ |__| |__| /__/ \__\ | _| |_______|/__/ \__\ |_______| \______|
A swiss army knife for pentesting networks
- Forged by @byt3bl33d3r and @mpgn_x64 using the powah of dank memes
+ Forged by @byt3bl33d3r and @mpgn_x64 using the powah of dank memes.
+ Maintained as an open source project by @NeffIsBack, @MJHallenbeck, @_zblurx
{highlight('Version', 'red')} : {highlight(VERSION)}
{highlight('Codename', 'red')}: {highlight(CODENAME)}
diff --git a/cme/connection.py b/cme/connection.py
index 09aa0ef3..05ede773 100755
--- a/cme/connection.py
+++ b/cme/connection.py
@@ -341,6 +341,12 @@ class connection(object):
secret.append(aesKey)
cred_type.append('aesKey')
+ # Allow trying multiple users with a single password
+ if len(username) > 1 and len(secret) == 1:
+ secret = secret * len(username)
+ cred_type = cred_type * len(username)
+ self.args.no_bruteforce = True
+
return domain, username, owned, secret, cred_type, [None] * len(secret)
def try_credentials(self, domain, username, owned, secret, cred_type, data=None):
diff --git a/cme/modules/veeam_dump.py b/cme/modules/veeam_dump.py
index e2092a79..c43a678b 100644
--- a/cme/modules/veeam_dump.py
+++ b/cme/modules/veeam_dump.py
@@ -144,7 +144,7 @@ class CMEModule:
return connection.execute("powershell.exe -e {} -OutputFormat Text".format(psScipt_b64), True)
def printCreds(self, context, output):
- # Format ouput if returned in some XML Format
+ # Format output if returned in some XML Format
if "CLIXML" in output:
output = self.stripXmlOutput(context, output)
diff --git a/cme/protocols/smb.py b/cme/protocols/smb.py
index a9cc2265..c1cfd162 100755
--- a/cme/protocols/smb.py
+++ b/cme/protocols/smb.py
@@ -734,8 +734,9 @@ class smb(connection):
self.kdcHost,
self.hash,
self.logger,
- self.args.get_output_tries
- ) # self.args.share)
+ self.args.get_output_tries,
+ self.args.share
+ )
self.logger.info("Executed command via atexec")
break
except:
diff --git a/cme/protocols/smb/atexec.py b/cme/protocols/smb/atexec.py
index 1e4d02bd..ae8273d2 100755
--- a/cme/protocols/smb/atexec.py
+++ b/cme/protocols/smb/atexec.py
@@ -38,6 +38,8 @@ class TSCH_EXEC:
self.__doKerberos = doKerberos
self.__kdcHost = kdcHost
self.__tries = tries
+ self.__output_filename = None
+ self.__share = share
self.logger = logger
if hashes is not None:
@@ -73,7 +75,7 @@ class TSCH_EXEC:
def output_callback(self, data):
self.__outputBuffer = data
- def gen_xml(self, command, tmpFileName, fileless=False):
+ def gen_xml(self, command, fileless=False):
xml = """
@@ -114,11 +116,12 @@ class TSCH_EXEC:
cmd.exe
"""
if self.__retOutput:
+ self.__output_filename = "\\Windows\\Temp\\" + gen_random_string(6)
if fileless:
local_ip = self.__rpctransport.get_socket().getsockname()[0]
- argument_xml = f" /C {command} > \\\\{local_ip}\\{self.__share_name}\\{tmpFileName} 2>&1"
+ argument_xml = f" /C {command} > \\\\{local_ip}\\{self.__share_name}\\{self.__output_filename} 2>&1"
else:
- argument_xml = f" /C {command} > %windir%\\Temp\\{tmpFileName} 2>&1"
+ argument_xml = f" /C {command} > {self.__output_filename} 2>&1"
elif self.__retOutput is False:
argument_xml = f" /C {command}"
@@ -143,9 +146,8 @@ class TSCH_EXEC:
# dce.set_auth_level(ntlm.NTLM_AUTH_PKT_PRIVACY)
tmpName = gen_random_string(8)
- tmpFileName = tmpName + ".tmp"
- xml = self.gen_xml(command, tmpFileName, fileless)
+ xml = self.gen_xml(command, fileless)
self.logger.info(f"Task XML: {xml}")
taskCreated = False
@@ -187,7 +189,7 @@ class TSCH_EXEC:
if fileless:
while True:
try:
- with open(os.path.join("/tmp", "cme_hosted", tmpFileName), "r") as output:
+ with open(os.path.join("/tmp", "cme_hosted", self.__output_filename), "r") as output:
self.output_callback(output.read())
break
except IOError:
@@ -198,15 +200,15 @@ class TSCH_EXEC:
tries = 1
while True:
try:
- self.logger.info(f"Attempting to read ADMIN$\\Temp\\{tmpFileName}")
- smbConnection.getFile("ADMIN$", f"Temp\\{tmpFileName}", self.output_callback)
+ self.logger.info(f"Attempting to read {self.__share}\\{self.__output_filename}")
+ smbConnection.getFile(self.__share, self.__output_filename, self.output_callback)
break
except Exception as e:
if tries >= self.__tries:
- self.logger.fail(f'ATEXEC: Get output file error, maybe got detected by AV software, please increase the number of tries with the option "--get-output-tries". If it\'s still failing maybe something is blocking the schedule job, try another exec method')
+ self.logger.fail(f"ATEXEC: Could not retrieve output file, it may have been detected by AV. Please increase the number of tries with the option '--get-output-tries'. If it is still failing, try the 'wmi' protocol or another exec method")
break
if str(e).find("STATUS_BAD_NETWORK_NAME") >0 :
- self.logger.fail(f'ATEXEC: Get ouput failed, target has blocked ADMIN$ access (maybe command executed!)')
+ self.logger.fail(f"ATEXEC: Getting the output file failed - target has blocked access to the share: {self.__share} (but the command may have executed!)")
break
if str(e).find("SHARING") > 0 or str(e).find("STATUS_OBJECT_NAME_NOT_FOUND") >= 0:
sleep(3)
@@ -215,7 +217,7 @@ class TSCH_EXEC:
self.logger.debug(str(e))
if self.__outputBuffer:
- self.logger.debug(f"Deleting file ADMIN$\\Temp\\{tmpFileName}")
- smbConnection.deleteFile("ADMIN$", f"Temp\\{tmpFileName}")
+ self.logger.debug(f"Deleting file {self.__share}\\{self.__output_filename}")
+ smbConnection.deleteFile(self.__share, self.__output_filename)
dce.disconnect()
diff --git a/cme/protocols/smb/mmcexec.py b/cme/protocols/smb/mmcexec.py
index 4ab99c76..44dd802f 100644
--- a/cme/protocols/smb/mmcexec.py
+++ b/cme/protocols/smb/mmcexec.py
@@ -252,10 +252,10 @@ class MMCEXEC:
break
except Exception as e:
if tries >= self.__tries:
- self.logger.fail(f'MMCEXEC: Get output file error, maybe got detected by AV software, please increase the number of tries with the option "--get-output-tries". If it\'s still failing maybe something is blocking the schedule job, try another exec method')
+ self.logger.fail(f"MMCEXEC: Could not retrieve output file, it may have been detected by AV. Please increase the number of tries with the option '--get-output-tries'. If it is still failing, try the 'wmi' protocol or another exec method")
break
if str(e).find("STATUS_BAD_NETWORK_NAME") >0 :
- self.logger.fail(f'MMCEXEC: Get ouput failed, target has blocked {self.__share} access (maybe command executed!)')
+ self.logger.fail(f"MMCEXEC: Getting the output file failed - target has blocked access to the share: {self.__share} (but the command may have executed!)")
break
if str(e).find("STATUS_SHARING_VIOLATION") >= 0 or str(e).find("STATUS_OBJECT_NAME_NOT_FOUND") >= 0:
# Output not finished, let's wait
diff --git a/cme/protocols/smb/proto_args.py b/cme/protocols/smb/proto_args.py
index 9dac1c8b..eb083226 100644
--- a/cme/protocols/smb/proto_args.py
+++ b/cme/protocols/smb/proto_args.py
@@ -91,7 +91,7 @@ def proto_args(parser, std_parser, module_parser):
help="force the PowerShell command to run in a 32-bit process")
cgroup.add_argument("--no-output", action="store_true", help="do not retrieve command output")
cegroup = cgroup.add_mutually_exclusive_group()
- cegroup.add_argument("-x", metavar="COMMAND", dest="execute", help="execute the specified command")
+ cegroup.add_argument("-x", metavar="COMMAND", dest="execute", help="execute the specified CMD command")
cegroup.add_argument("-X", metavar="PS_COMMAND", dest="ps_execute", help="execute the specified PowerShell command")
psgroup = smb_parser.add_argument_group("Powershell Obfuscation", "Options for PowerShell script obfuscation")
psgroup.add_argument("--obfs", action="store_true", help="Obfuscate PowerShell scripts")
diff --git a/cme/protocols/smb/smbexec.py b/cme/protocols/smb/smbexec.py
index 1f51acd2..73c8a765 100755
--- a/cme/protocols/smb/smbexec.py
+++ b/cme/protocols/smb/smbexec.py
@@ -170,10 +170,10 @@ class SMBEXEC:
break
except Exception as e:
if tries >= self.__tries:
- self.logger.fail(f'SMBEXEC: Get output file error, maybe got detected by AV software, please increase the number of tries with the option "--get-output-tries". If it\'s still failing maybe something is blocking the schedule job, try another exec method')
+ self.logger.fail(f"SMBEXEC: Could not retrieve output file, it may have been detected by AV. Please increase the number of tries with the option '--get-output-tries'. If it is still failing, try the 'wmi' protocol or another exec method")
break
if str(e).find("STATUS_BAD_NETWORK_NAME") >0 :
- self.logger.fail(f'SMBEXEC: Get ouput failed, target has blocked {self.__share} access (maybe command executed!)')
+ self.logger.fail(f"SMBEXEC: Getting the output file failed - target has blocked access to the share: {self.__share} (but the command may have executed!)")
break
if str(e).find("STATUS_SHARING_VIOLATION") >= 0 or str(e).find("STATUS_OBJECT_NAME_NOT_FOUND") >= 0:
# Output not finished, let's wait
diff --git a/cme/protocols/smb/wmiexec.py b/cme/protocols/smb/wmiexec.py
index 419ed4fb..6046df34 100755
--- a/cme/protocols/smb/wmiexec.py
+++ b/cme/protocols/smb/wmiexec.py
@@ -166,10 +166,10 @@ class WMIEXEC:
break
except Exception as e:
if tries >= self.__tries:
- self.logger.fail(f'WMIEXEC: Get output file error, maybe got detected by AV software, please increase the number of tries with the option "--get-output-tries". If it\'s still failing maybe something is blocking the schedule job, try another exec method')
+ self.logger.fail(f"WMIEXEC: Could not retrieve output file, it may have been detected by AV. If it is still failing, try the 'wmi' protocol or another exec method")
break
if str(e).find("STATUS_BAD_NETWORK_NAME") >0 :
- self.logger.fail(f'SMB connection: target has blocked {self.__share} access (maybe command executed!)')
+ self.logger.fail(f"SMB connection: target has blocked {self.__share} access (maybe command executed!)")
break
if str(e).find("STATUS_SHARING_VIOLATION") >= 0 or str(e).find("STATUS_OBJECT_NAME_NOT_FOUND") >= 0:
sleep(2)
diff --git a/cme/protocols/winrm.py b/cme/protocols/winrm.py
index 1c460bc3..5fea95e3 100644
--- a/cme/protocols/winrm.py
+++ b/cme/protocols/winrm.py
@@ -231,31 +231,14 @@ class winrm(connection):
self.password = password
self.username = username
self.domain = domain
- if self.args.ssl and self.args.ignore_ssl_cert:
- self.conn = Client(
- self.host,
- auth="ntlm",
- username=f"{domain}\\{self.username}",
- password=self.password,
- ssl=True,
- cert_validation=False,
- )
- elif self.args.ssl:
- self.conn = Client(
- self.host,
- auth="ntlm",
- username=f"{domain}\\{self.username}",
- password=self.password,
- ssl=True,
- )
- else:
- self.conn = Client(
- self.host,
- auth="ntlm",
- username=f"{domain}\\{self.username}",
- password=self.password,
- ssl=False,
- )
+ self.conn = Client(
+ self.host,
+ auth="ntlm",
+ username=f"{domain}\\{self.username}",
+ password=self.password,
+ ssl=True if self.args.ssl else False,
+ cert_validation=False if self.args.ignore_ssl_cert else True,
+ )
# TO DO: right now we're just running the hostname command to make the winrm library auth to the server
# we could just authenticate without running a command :) (probably)
@@ -308,31 +291,14 @@ class winrm(connection):
nthash = self.hash
self.domain = domain
- if self.args.ssl and self.args.ignore_ssl_cert:
- self.conn = Client(
- self.host,
- auth="ntlm",
- username=f"{self.domain}\\{self.username}",
- password=lmhash + nthash,
- ssl=True,
- cert_validation=False,
- )
- elif self.args.ssl:
- self.conn = Client(
- self.host,
- auth="ntlm",
- username=f"{self.domain}\\{self.username}",
- password=lmhash + nthash,
- ssl=True,
- )
- else:
- self.conn = Client(
- self.host,
- auth="ntlm",
- username=f"{self.domain}\\{self.username}",
- password=lmhash + nthash,
- ssl=False,
- )
+ self.conn = Client(
+ self.host,
+ auth="ntlm",
+ username=f"{self.domain}\\{self.username}",
+ password=lmhash + nthash,
+ ssl=True if self.args.ssl else False,
+ cert_validation=False if self.args.ignore_ssl_cert else True,
+ )
# TO DO: right now we're just running the hostname command to make the winrm library auth to the server
# we could just authenticate without running a command :) (probably)
diff --git a/cme/protocols/wmi.py b/cme/protocols/wmi.py
index da1b56f4..81cbdac9 100644
--- a/cme/protocols/wmi.py
+++ b/cme/protocols/wmi.py
@@ -432,7 +432,7 @@ class wmi(connection):
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
@@ -441,11 +441,11 @@ class wmi(connection):
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()
diff --git a/cme/protocols/wmi/proto_args.py b/cme/protocols/wmi/proto_args.py
index 6bb1605e..53d37f68 100644
--- a/cme/protocols/wmi/proto_args.py
+++ b/cme/protocols/wmi/proto_args.py
@@ -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, "
diff --git a/cme/protocols/wmi/wmiexec.py b/cme/protocols/wmi/wmiexec.py
index 70b027af..e32594dc 100644
--- a/cme/protocols/wmi/wmiexec.py
+++ b/cme/protocols/wmi/wmiexec.py
@@ -34,7 +34,7 @@ from impacket.dcerpc.v5.dcomrt import DCOMConnection
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
@@ -45,7 +45,7 @@ class WMIEXEC:
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
@@ -91,8 +91,8 @@ class WMIEXEC:
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)
@@ -104,7 +104,7 @@ class WMIEXEC:
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: 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")
try:
self.logger.debug(f"Removing temporary registry path: HKLM\\{self.__registry_Path}")
diff --git a/cme/protocols/wmi/wmiexec_event.py b/cme/protocols/wmi/wmiexec_event.py
index e1ada22c..3a7f1e3f 100644
--- a/cme/protocols/wmi/wmiexec_event.py
+++ b/cme/protocols/wmi/wmiexec_event.py
@@ -37,7 +37,7 @@ from impacket.dcerpc.v5.dcom.wmi import WBEMSTATUS
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
@@ -51,7 +51,7 @@ class WMIEXEC_EVENT:
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())}"
@@ -84,8 +84,8 @@ class WMIEXEC_EVENT:
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()
@@ -190,7 +190,7 @@ class WMIEXEC_EVENT:
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: 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")
def remove_Instance(self):
if self.__retOutput: