[smb] Move firewall_checker to built-in function & bugs fix
Signed-off-by: XiaoliChan <2209553467@qq.com>main
parent
5d8fa3c1e3
commit
be5b543338
|
@ -15,6 +15,8 @@ from cme.helpers.logger import highlight
|
|||
from cme.logger import cme_logger, CMEAdapter
|
||||
from cme.context import Context
|
||||
|
||||
from impacket.dcerpc.v5 import transport
|
||||
|
||||
sem = BoundedSemaphore(1)
|
||||
global_failed_logins = 0
|
||||
user_failed_logins = {}
|
||||
|
@ -31,7 +33,6 @@ def gethost_addrinfo(hostname):
|
|||
return sa[0]
|
||||
return canonname
|
||||
|
||||
|
||||
def requires_admin(func):
|
||||
def _decorator(self, *args, **kwargs):
|
||||
if self.admin_privs is False:
|
||||
|
@ -40,6 +41,31 @@ def requires_admin(func):
|
|||
|
||||
return wraps(func)(_decorator)
|
||||
|
||||
def dcom_FirewallChecker(iInterface, timeout):
|
||||
stringBindings = iInterface.get_cinstance().get_string_bindings()
|
||||
for strBinding in stringBindings:
|
||||
if strBinding['wTowerId'] == 7:
|
||||
if strBinding['aNetworkAddr'].find('[') >= 0:
|
||||
binding, _, bindingPort = strBinding['aNetworkAddr'].partition('[')
|
||||
bindingPort = '[' + bindingPort
|
||||
else:
|
||||
binding = strBinding['aNetworkAddr']
|
||||
bindingPort = ''
|
||||
|
||||
if binding.upper().find(iInterface.get_target().upper()) >= 0:
|
||||
stringBinding = 'ncacn_ip_tcp:' + strBinding['aNetworkAddr'][:-1]
|
||||
break
|
||||
elif iInterface.is_fqdn() and binding.upper().find(iInterface.get_target().upper().partition('.')[0]) >= 0:
|
||||
stringBinding = 'ncacn_ip_tcp:%s%s' % (iInterface.get_target(), bindingPort)
|
||||
try:
|
||||
rpctransport = transport.DCERPCTransportFactory(stringBinding)
|
||||
rpctransport.set_connect_timeout(timeout)
|
||||
rpctransport.connect()
|
||||
rpctransport.disconnect()
|
||||
except:
|
||||
return False, stringBinding
|
||||
else:
|
||||
return True, stringBinding
|
||||
|
||||
class connection(object):
|
||||
def __init__(self, args, db, host):
|
||||
|
|
|
@ -690,7 +690,7 @@ class smb(connection):
|
|||
self.hash,
|
||||
self.args.share,
|
||||
logger=self.logger,
|
||||
timeout=self.args.wmiexec_timeout,
|
||||
timeout=self.args.dcom_timeout,
|
||||
tries=self.args.get_output_tries
|
||||
)
|
||||
self.logger.info("Executed command via wmiexec")
|
||||
|
@ -711,7 +711,8 @@ class smb(connection):
|
|||
self.args.share,
|
||||
self.hash,
|
||||
self.logger,
|
||||
self.args.get_output_tries
|
||||
self.args.get_output_tries,
|
||||
self.args.dcom_timeout
|
||||
)
|
||||
self.logger.info("Executed command via mmcexec")
|
||||
break
|
||||
|
|
|
@ -141,8 +141,7 @@ class TSCH_EXEC:
|
|||
dce.set_credentials(*self.__rpctransport.get_credentials())
|
||||
dce.connect()
|
||||
# dce.set_auth_level(ntlm.NTLM_AUTH_PKT_PRIVACY)
|
||||
dce.set_auth_level(RPC_C_AUTHN_LEVEL_PKT_PRIVACY)
|
||||
dce.bind(tsch.MSRPC_UUID_TSCHS)
|
||||
|
||||
tmpName = gen_random_string(8)
|
||||
tmpFileName = tmpName + ".tmp"
|
||||
|
||||
|
@ -152,11 +151,18 @@ class TSCH_EXEC:
|
|||
taskCreated = False
|
||||
self.logger.info(f"Creating task \\{tmpName}")
|
||||
try:
|
||||
# windows server 2003 has no MSRPC_UUID_TSCHS, if it bind, it will return abstract_syntax_not_supported
|
||||
dce.set_auth_level(RPC_C_AUTHN_LEVEL_PKT_PRIVACY)
|
||||
dce.bind(tsch.MSRPC_UUID_TSCHS)
|
||||
tsch.hSchRpcRegisterTask(dce, f"\\{tmpName}", xml, tsch.TASK_CREATE, NULL, tsch.TASK_LOGON_NONE)
|
||||
except Exception as e:
|
||||
self.logger.fail(str(e))
|
||||
if hex(e.error_code) == "0x80070005":
|
||||
self.logger.fail("ATEXEC: Create schedule task got blocked.")
|
||||
else:
|
||||
self.logger.fail(str(e))
|
||||
return
|
||||
taskCreated = True
|
||||
else:
|
||||
taskCreated = True
|
||||
|
||||
self.logger.info(f"Running task \\{tmpName}")
|
||||
tsch.hSchRpcRun(dce, f"\\{tmpName}")
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
from os.path import join as path_join
|
||||
from time import sleep
|
||||
from cme.connection import dcom_FirewallChecker
|
||||
from cme.helpers.misc import gen_random_string
|
||||
|
||||
from impacket.dcerpc.v5.dcom.oaut import (
|
||||
|
@ -59,7 +60,7 @@ from impacket.dcerpc.v5.dtypes import NULL
|
|||
|
||||
|
||||
class MMCEXEC:
|
||||
def __init__(self, host, share_name, username, password, domain, smbconnection, share, hashes=None, logger=None, tries=None):
|
||||
def __init__(self, host, share_name, username, password, domain, smbconnection, share, hashes=None, logger=None, tries=None, timeout=None):
|
||||
self.__host = host
|
||||
self.__username = username
|
||||
self.__password = password
|
||||
|
@ -78,6 +79,7 @@ class MMCEXEC:
|
|||
self.__share = share
|
||||
self.__dcom = None
|
||||
self.__tries = tries
|
||||
self.__timeout = timeout
|
||||
self.logger = logger
|
||||
|
||||
if hashes is not None:
|
||||
|
@ -98,6 +100,11 @@ class MMCEXEC:
|
|||
)
|
||||
try:
|
||||
iInterface = self.__dcom.CoCreateInstanceEx(string_to_bin("49B2791A-B1AE-4C90-9B8E-E860BA07F889"), IID_IDispatch)
|
||||
flag, self.__stringBinding = dcom_FirewallChecker(iInterface, self.__timeout)
|
||||
if flag is False:
|
||||
self.logger.fail(f'MMCEXEC: Dcom initialization failed on connection with stringbinding: "{self.__stringBinding}", please increase the timeout with the option "--dcom-timeout". If it\'s still failing maybe something is blocking the RPC connection, try another exec method')
|
||||
# Make it force break function
|
||||
self.__dcom.disconnect()
|
||||
iMMC = IDispatch(iInterface)
|
||||
|
||||
resp = iMMC.GetIDsOfNames(("Document",))
|
||||
|
|
|
@ -79,7 +79,7 @@ def proto_args(parser, std_parser, module_parser):
|
|||
cgroup = smb_parser.add_argument_group("Command Execution", "Options for executing commands")
|
||||
cgroup.add_argument("--exec-method", choices={"wmiexec", "mmcexec", "smbexec", "atexec"}, default=None,
|
||||
help="method to execute the command. Ignored if in MSSQL mode (default: wmiexec)")
|
||||
cgroup.add_argument("--wmiexec-timeout", help="WMIEXEC connection timeout, default is 5 secondes", type=int, default=5)
|
||||
cgroup.add_argument("--dcom-timeout", help="DCOM connection timeout, default is 5 secondes", type=int, default=5)
|
||||
cgroup.add_argument("--get-output-tries", help="Number of times atexec/smbexec/mmcexec tries to get results, default is 5", type=int, default=5)
|
||||
cgroup.add_argument("--codec", default="utf-8",
|
||||
help="Set encoding used (codec) from the target's output (default "
|
||||
|
|
|
@ -141,18 +141,21 @@ class SMBEXEC:
|
|||
except Exception as e:
|
||||
if "rpc_s_access_denied" in str(e):
|
||||
self.logger.fail("SMBEXEC: Create services got blocked.")
|
||||
return self.__outputBuffer
|
||||
else:
|
||||
pass
|
||||
self.logger.fail(str(e))
|
||||
|
||||
return self.__outputBuffer
|
||||
|
||||
try:
|
||||
self.logger.debug(f"Remote service {self.__serviceName} started.")
|
||||
scmr.hRStartServiceW(self.__scmr, service)
|
||||
except:
|
||||
|
||||
self.logger.debug(f"Remote service {self.__serviceName} deleted.")
|
||||
scmr.hRDeleteService(self.__scmr, service)
|
||||
scmr.hRCloseServiceHandle(self.__scmr, service)
|
||||
except Exception as e:
|
||||
pass
|
||||
self.logger.debug(f"Remote service {self.__serviceName} deleted.")
|
||||
scmr.hRDeleteService(self.__scmr, service)
|
||||
scmr.hRCloseServiceHandle(self.__scmr, service)
|
||||
|
||||
self.get_output_remote()
|
||||
|
||||
def get_output_remote(self):
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
import ntpath
|
||||
import os
|
||||
from time import sleep
|
||||
from cme.connection import dcom_FirewallChecker
|
||||
from cme.helpers.misc import gen_random_string
|
||||
from impacket.dcerpc.v5 import transport
|
||||
from impacket.dcerpc.v5.dcomrt import DCOMConnection
|
||||
|
@ -73,39 +74,16 @@ class WMIEXEC:
|
|||
kdcHost=self.__kdcHost,
|
||||
)
|
||||
iInterface = self.__dcom.CoCreateInstanceEx(wmi.CLSID_WbemLevel1Login, wmi.IID_IWbemLevel1Login)
|
||||
try:
|
||||
self.firewall_check(iInterface, self.__timeout)
|
||||
except:
|
||||
self.logger.fail(f'WMIEXEC: Dcom initialization failed on connection with stringbinding: "{self.__stringBinding}", please increase the timeout with the option "--wmiexec-timeout". If it\'s still failing maybe something is blocking the RPC connection, try another exec method')
|
||||
flag, self.__stringBinding = dcom_FirewallChecker(iInterface, self.__timeout)
|
||||
if flag is False:
|
||||
self.logger.fail(f'WMIEXEC: Dcom initialization failed on connection with stringbinding: "{self.__stringBinding}", please increase the timeout with the option "--dcom-timeout". If it\'s still failing maybe something is blocking the RPC connection, try another exec method')
|
||||
# Make it force break function
|
||||
self.__dcom.disconnect()
|
||||
iWbemLevel1Login = wmi.IWbemLevel1Login(iInterface)
|
||||
iWbemServices = iWbemLevel1Login.NTLMLogin("//./root/cimv2", NULL, NULL)
|
||||
iWbemLevel1Login.RemRelease()
|
||||
self.__win32Process, _ = iWbemServices.GetObject("Win32_Process")
|
||||
|
||||
def firewall_check(self, iInterface ,timeout):
|
||||
stringBindings = iInterface.get_cinstance().get_string_bindings()
|
||||
for strBinding in stringBindings:
|
||||
if strBinding['wTowerId'] == 7:
|
||||
if strBinding['aNetworkAddr'].find('[') >= 0:
|
||||
binding, _, bindingPort = strBinding['aNetworkAddr'].partition('[')
|
||||
bindingPort = '[' + bindingPort
|
||||
else:
|
||||
binding = strBinding['aNetworkAddr']
|
||||
bindingPort = ''
|
||||
|
||||
if binding.upper().find(iInterface.get_target().upper()) >= 0:
|
||||
stringBinding = 'ncacn_ip_tcp:' + strBinding['aNetworkAddr'][:-1]
|
||||
break
|
||||
elif iInterface.is_fqdn() and binding.upper().find(iInterface.get_target().upper().partition('.')[0]) >= 0:
|
||||
stringBinding = 'ncacn_ip_tcp:%s%s' % (iInterface.get_target(), bindingPort)
|
||||
|
||||
self.__stringBinding = stringBinding
|
||||
rpctransport = transport.DCERPCTransportFactory(stringBinding)
|
||||
rpctransport.set_connect_timeout(timeout)
|
||||
rpctransport.connect()
|
||||
rpctransport.disconnect()
|
||||
|
||||
def execute(self, command, output=False):
|
||||
self.__retOutput = output
|
||||
if self.__retOutput:
|
||||
|
|
Loading…
Reference in New Issue