def psexec_cmd(session, command, path=None): session.lock.acquire() if commander.server.service_name is not None: svc_name = commander.server.service_name else: svc_name = "smbcom" + random_string(8) connection = SMBConnection(existingConnection=session) installService = serviceinstall.ServiceInstall(session, remcomsvc.RemComSvc(), svc_name) installService.install() tid = connection.connectTree('IPC$') fid_main = openPipe(connection, tid, '\\RemCom_communicaton', 0x12019f) packet = psexec.RemComMessage() pid = os.getpid() packet['Machine'] = ''.join( [random.choice(string.letters) for _ in range(4)]) if path is not None: packet['WorkingDir'] = path packet['Command'] = command packet['ProcessID'] = pid connection.writeNamedPipe(tid, fid_main, str(packet)) stdin_pipe = psexec.CommanderRemoteStdInPipe( connection, '\\%s%s%d' % (psexec.RemComSTDIN, packet['Machine'], packet['ProcessID']), FILE_WRITE_DATA | FILE_APPEND_DATA, installService.getShare()) stdin_pipe.start() stdout_pipe = psexec.CommanderRemoteStdOutPipe( connection, '\\%s%s%d' % (psexec.RemComSTDOUT, packet['Machine'], packet['ProcessID']), FILE_READ_DATA) stdout_pipe.start() stderr_pipe = psexec.CommanderRemoteStdErrPipe( connection, '\\%s%s%d' % (psexec.RemComSTDERR, packet['Machine'], packet['ProcessID']), FILE_READ_DATA) stderr_pipe.start() ans = connection.readNamedPipe(tid, fid_main, 8) session.lock.release()
class PSEXEC: def __init__(self, command, username, domain, smbConnection, TGS, copyFile): self.__username = username self.__command = command self.__path = None self.__domain = domain self.__exeFile = None self.__copyFile = copyFile self.__TGS = TGS self.__smbConnection = smbConnection def run(self, addr): rpctransport = transport.SMBTransport( addr, filename='/svcctl', smb_connection=self.__smbConnection) dce = rpctransport.get_dce_rpc() try: dce.connect() except Exception, e: logging.critical(str(e)) sys.exit(1) global dialect dialect = rpctransport.get_smb_connection().getDialect() try: unInstalled = False s = rpctransport.get_smb_connection() # We don't wanna deal with timeouts from now on. s.setTimeout(100000) if self.__exeFile is None: installService = serviceinstall.ServiceInstall( rpctransport.get_smb_connection(), remcomsvc.RemComSvc()) else: try: f = open(self.__exeFile) except Exception, e: logging.critical(str(e)) sys.exit(1) installService = serviceinstall.ServiceInstall( rpctransport.get_smb_connection(), f) installService.install() if self.__exeFile is not None: f.close() # Check if we need to copy a file for execution if self.__copyFile is not None: installService.copy_file(self.__copyFile, installService.getShare(), os.path.basename(self.__copyFile)) # And we change the command to be executed to this filename self.__command = os.path.basename( self.__copyFile) + ' ' + self.__command tid = s.connectTree('IPC$') fid_main = self.openPipe(s, tid, '\RemCom_communicaton', 0x12019f) packet = RemComMessage() pid = os.getpid() packet['Machine'] = ''.join( [random.choice(string.letters) for _ in range(4)]) if self.__path is not None: packet['WorkingDir'] = self.__path packet['Command'] = self.__command packet['ProcessID'] = pid s.writeNamedPipe(tid, fid_main, str(packet)) # Here we'll store the command we type so we don't print it back ;) # ( I know.. globals are nasty :P ) global LastDataSent LastDataSent = '' # Create the pipes threads stdin_pipe = RemoteStdInPipe( rpctransport, '\%s%s%d' % (RemComSTDIN, packet['Machine'], packet['ProcessID']), smb.FILE_WRITE_DATA | smb.FILE_APPEND_DATA, self.__TGS, installService.getShare()) stdin_pipe.start() stdout_pipe = RemoteStdOutPipe( rpctransport, '\%s%s%d' % (RemComSTDOUT, packet['Machine'], packet['ProcessID']), smb.FILE_READ_DATA) stdout_pipe.start() stderr_pipe = RemoteStdErrPipe( rpctransport, '\%s%s%d' % (RemComSTDERR, packet['Machine'], packet['ProcessID']), smb.FILE_READ_DATA) stderr_pipe.start() # And we stay here till the end ans = s.readNamedPipe(tid, fid_main, 8) if len(ans): retCode = RemComResponse(ans) logging.info( "Process %s finished with ErrorCode: %d, ReturnCode: %d" % (self.__command, retCode['ErrorCode'], retCode['ReturnCode'])) installService.uninstall() if self.__copyFile is not None: # We copied a file for execution, let's remove it s.deleteFile(installService.getShare(), os.path.basename(self.__copyFile)) unInstalled = True sys.exit(retCode['ErrorCode'])
def doStuff(self, rpctransport): dce = rpctransport.get_dce_rpc() try: dce.connect() except Exception as e: if logging.getLogger().level == logging.DEBUG: import traceback traceback.print_exc() logging.critical(str(e)) sys.exit(1) global dialect dialect = rpctransport.get_smb_connection().getDialect() try: unInstalled = False s = rpctransport.get_smb_connection() # We don't wanna deal with timeouts from now on. s.setTimeout(100000) if self.__exeFile is None: installService = serviceinstall.ServiceInstall( rpctransport.get_smb_connection(), remcomsvc.RemComSvc(), self.__serviceName, self.__remoteBinaryName) else: try: f = open(self.__exeFile) except Exception as e: logging.critical(str(e)) sys.exit(1) installService = serviceinstall.ServiceInstall( rpctransport.get_smb_connection(), f) if installService.install() is False: return if self.__exeFile is not None: f.close() # Check if we need to copy a file for execution if self.__copyFile is not None: installService.copy_file(self.__copyFile, installService.getShare(), os.path.basename(self.__copyFile)) # And we change the command to be executed to this filename self.__command = os.path.basename( self.__copyFile) + ' ' + self.__command tid = s.connectTree('IPC$') fid_main = self.openPipe(s, tid, r'\RemCom_communicaton', 0x12019f) packet = RemComMessage() pid = os.getpid() packet['Machine'] = ''.join( [random.choice(string.ascii_letters) for _ in range(4)]) if self.__path is not None: packet['WorkingDir'] = self.__path packet['Command'] = self.__command packet['ProcessID'] = pid s.writeNamedPipe(tid, fid_main, packet.getData()) # Here we'll store the command we type so we don't print it back ;) # ( I know.. globals are nasty :P ) global LastDataSent LastDataSent = '' # Create the pipes threads stdin_pipe = RemoteStdInPipe( rpctransport, r'\%s%s%d' % (RemComSTDIN, packet['Machine'], packet['ProcessID']), smb.FILE_WRITE_DATA | smb.FILE_APPEND_DATA, installService.getShare()) stdin_pipe.start() stdout_pipe = RemoteStdOutPipe( rpctransport, r'\%s%s%d' % (RemComSTDOUT, packet['Machine'], packet['ProcessID']), smb.FILE_READ_DATA) stdout_pipe.start() stderr_pipe = RemoteStdErrPipe( rpctransport, r'\%s%s%d' % (RemComSTDERR, packet['Machine'], packet['ProcessID']), smb.FILE_READ_DATA) stderr_pipe.start() # And we stay here till the end ans = s.readNamedPipe(tid, fid_main, 8) if len(ans): retCode = RemComResponse(ans) logging.info( "Process %s finished with ErrorCode: %d, ReturnCode: %d" % (self.__command, retCode['ErrorCode'], retCode['ReturnCode'])) installService.uninstall() if self.__copyFile is not None: # We copied a file for execution, let's remove it s.deleteFile(installService.getShare(), os.path.basename(self.__copyFile)) unInstalled = True sys.exit(retCode['ErrorCode']) except SystemExit: raise except Exception as e: if logging.getLogger().level == logging.DEBUG: import traceback traceback.print_exc() logging.debug(str(e)) if unInstalled is False: installService.uninstall() if self.__copyFile is not None: s.deleteFile(installService.getShare(), os.path.basename(self.__copyFile)) sys.stdout.flush() sys.exit(1)
class PSEXEC: KNOWN_PROTOCOLS = { '139/SMB': (r'ncacn_np:%s[\pipe\svcctl]', 139), '445/SMB': (r'ncacn_np:%s[\pipe\svcctl]', 445), } def __init__(self, command, path, exeFile, copyFile, protocols=None, username='', password='', domain='', hashes=None): self.__username = username self.__password = password if protocols is None: self.__protocols = PSEXEC.KNOWN_PROTOCOLS.keys() else: self.__protocols = [protocols] self.__command = command self.__path = path self.__domain = domain self.__lmhash = '' self.__nthash = '' self.__exeFile = exeFile self.__copyFile = copyFile if hashes is not None: self.__lmhash, self.__nthash = hashes.split(':') def run(self, addr): for protocol in self.__protocols: protodef = PSEXEC.KNOWN_PROTOCOLS[protocol] port = protodef[1] print "Trying protocol %s...\n" % protocol stringbinding = protodef[0] % addr rpctransport = transport.DCERPCTransportFactory(stringbinding) rpctransport.set_dport(port) #if hasattr(rpctransport,'preferred_dialect'): # rpctransport.preferred_dialect(SMB_DIALECT) if hasattr(rpctransport, 'set_credentials'): # This method exists only for selected protocol sequences. rpctransport.set_credentials(self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash) self.doStuff(rpctransport) def openPipe(self, s, tid, pipe, accessMask): pipeReady = False tries = 50 while pipeReady is False and tries > 0: try: s.waitNamedPipe(tid, pipe) pipeReady = True except: tries -= 1 time.sleep(2) pass if tries == 0: print '[!] Pipe not ready, aborting' raise fid = s.openFile(tid, pipe, accessMask, creationOption=0x40, fileAttributes=0x80) return fid def doStuff(self, rpctransport): dce = rpctransport.get_dce_rpc() try: dce.connect() except Exception, e: print e sys.exit(1) global dialect dialect = rpctransport.get_smb_connection().getDialect() try: unInstalled = False s = rpctransport.get_smb_connection() # We don't wanna deal with timeouts from now on. s.setTimeout(100000) if self.__exeFile is None: installService = serviceinstall.ServiceInstall( rpctransport.get_smb_connection(), remcomsvc.RemComSvc()) else: try: f = open(self.__exeFile) except Exception, e: print e sys.exit(1) installService = serviceinstall.ServiceInstall( rpctransport.get_smb_connection(), f) installService.install() if self.__exeFile is not None: f.close() # Check if we need to copy a file for execution if self.__copyFile is not None: installService.copy_file(self.__copyFile, installService.getShare(), os.path.basename(self.__copyFile)) # And we change the command to be executed to this filename self.__command = os.path.basename( self.__copyFile) + ' ' + self.__command tid = s.connectTree('IPC$') fid_main = self.openPipe(s, tid, '\RemCom_communicaton', 0x12019f) packet = RemComMessage() pid = os.getpid() packet['Machine'] = ''.join( [random.choice(string.letters) for i in range(4)]) if self.__path is not None: packet['WorkingDir'] = self.__path packet['Command'] = self.__command packet['ProcessID'] = pid s.writeNamedPipe(tid, fid_main, str(packet)) # Here we'll store the command we type so we don't print it back ;) # ( I know.. globals are nasty :P ) global LastDataSent LastDataSent = '' # Create the pipes threads stdin_pipe = RemoteStdInPipe( rpctransport, '\%s%s%d' % (RemComSTDIN, packet['Machine'], packet['ProcessID']), smb.FILE_WRITE_DATA | smb.FILE_APPEND_DATA, installService.getShare()) stdin_pipe.start() stdout_pipe = RemoteStdOutPipe( rpctransport, '\%s%s%d' % (RemComSTDOUT, packet['Machine'], packet['ProcessID']), smb.FILE_READ_DATA) stdout_pipe.start() stderr_pipe = RemoteStdErrPipe( rpctransport, '\%s%s%d' % (RemComSTDERR, packet['Machine'], packet['ProcessID']), smb.FILE_READ_DATA) stderr_pipe.start() # And we stay here till the end ans = s.readNamedPipe(tid, fid_main, 8) if len(ans): retCode = RemComResponse(ans) print "[*] Process %s finished with ErrorCode: %d, ReturnCode: %d" % ( self.__command, retCode['ErrorCode'], retCode['ReturnCode']) installService.uninstall() if self.__copyFile is not None: # We copied a file for execution, let's remove it s.deleteFile(installService.getShare(), os.path.basename(self.__copyFile)) unInstalled = True sys.exit(retCode['ErrorCode'])
class PSEXEC: def __init__(self, command, path, exeFile, copyFile, port=445, username='', password='', domain='', hashes=None, aesKey=None, doKerberos=False, kdcHost=None, serviceName=None): self.__username = username self.__password = password self.__port = port self.__command = command self.__path = path self.__domain = domain self.__lmhash = '' self.__nthash = '' self.__aesKey = aesKey self.__exeFile = exeFile self.__copyFile = copyFile self.__doKerberos = doKerberos self.__kdcHost = kdcHost self.__serviceName = serviceName if hashes is not None: self.__lmhash, self.__nthash = hashes.split(':') def run(self, remoteName, remoteHost): stringbinding = 'ncacn_np:%s[\pipe\svcctl]' % remoteName logging.debug('StringBinding %s' % stringbinding) rpctransport = transport.DCERPCTransportFactory(stringbinding) rpctransport.set_dport(self.__port) rpctransport.setRemoteHost(remoteHost) if hasattr(rpctransport, 'set_credentials'): # This method exists only for selected protocol sequences. rpctransport.set_credentials(self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, self.__aesKey) rpctransport.set_kerberos(self.__doKerberos, self.__kdcHost) self.doStuff(rpctransport) def openPipe(self, s, tid, pipe, accessMask): pipeReady = False tries = 50 while pipeReady is False and tries > 0: try: s.waitNamedPipe(tid, pipe) pipeReady = True except: tries -= 1 time.sleep(2) pass if tries == 0: raise Exception('Pipe not ready, aborting') fid = s.openFile(tid, pipe, accessMask, creationOption=0x40, fileAttributes=0x80) return fid def doStuff(self, rpctransport): dce = rpctransport.get_dce_rpc() try: dce.connect() except Exception, e: if logging.getLogger().level == logging.DEBUG: import traceback traceback.print_exc() logging.critical(str(e)) sys.exit(1) global dialect dialect = rpctransport.get_smb_connection().getDialect() try: unInstalled = False s = rpctransport.get_smb_connection() # We don't wanna deal with timeouts from now on. s.setTimeout(100000) if self.__exeFile is None: installService = serviceinstall.ServiceInstall( rpctransport.get_smb_connection(), remcomsvc.RemComSvc(), self.__serviceName) else: try: f = open(self.__exeFile) except Exception, e: logging.critical(str(e)) sys.exit(1) installService = serviceinstall.ServiceInstall( rpctransport.get_smb_connection(), f) if installService.install() is False: return if self.__exeFile is not None: f.close() # Check if we need to copy a file for execution if self.__copyFile is not None: installService.copy_file(self.__copyFile, installService.getShare(), os.path.basename(self.__copyFile)) # And we change the command to be executed to this filename self.__command = os.path.basename( self.__copyFile) + ' ' + self.__command tid = s.connectTree('IPC$') fid_main = self.openPipe(s, tid, '\RemCom_communicaton', 0x12019f) packet = RemComMessage() pid = os.getpid() packet['Machine'] = ''.join( [random.choice(string.letters) for _ in range(4)]) if self.__path is not None: packet['WorkingDir'] = self.__path packet['Command'] = self.__command packet['ProcessID'] = pid s.writeNamedPipe(tid, fid_main, str(packet)) # Here we'll store the command we type so we don't print it back ;) # ( I know.. globals are nasty :P ) global LastDataSent LastDataSent = '' # Create the pipes threads stdin_pipe = RemoteStdInPipe( rpctransport, '\%s%s%d' % (RemComSTDIN, packet['Machine'], packet['ProcessID']), smb.FILE_WRITE_DATA | smb.FILE_APPEND_DATA, installService.getShare()) stdin_pipe.start() stdout_pipe = RemoteStdOutPipe( rpctransport, '\%s%s%d' % (RemComSTDOUT, packet['Machine'], packet['ProcessID']), smb.FILE_READ_DATA) stdout_pipe.start() stderr_pipe = RemoteStdErrPipe( rpctransport, '\%s%s%d' % (RemComSTDERR, packet['Machine'], packet['ProcessID']), smb.FILE_READ_DATA) stderr_pipe.start() # And we stay here till the end ans = s.readNamedPipe(tid, fid_main, 8) if len(ans): retCode = RemComResponse(ans) logging.info( "Process %s finished with ErrorCode: %d, ReturnCode: %d" % (self.__command, retCode['ErrorCode'], retCode['ReturnCode'])) installService.uninstall() if self.__copyFile is not None: # We copied a file for execution, let's remove it s.deleteFile(installService.getShare(), os.path.basename(self.__copyFile)) unInstalled = True sys.exit(retCode['ErrorCode'])
def psexec(self, command=None): srvname = ''.join( [random.choice(string.ascii_letters) for _ in range(8)]) remote_file = '%s.exe' % ''.join( [random.choice(string.ascii_lowercase) for _ in range(8)]) if not command: logger.info( 'Command has not been specified, going to call cmd.exe') command = 'cmd.exe' if command in ('cmd.exe', 'command.com'): logger.info('Launching interactive OS shell') command_and_args = shlex.split(command) if os.path.exists(command_and_args[0]): self.use(DataStore.writable_share) self.upload(command_and_args[0]) logger.debug('Going to use temporary service %s' % srvname) self.deploy(srvname, local_file=remcomsvc.RemComSvc(), srvargs='', remote_file=remote_file) self.smb_transport('svcctl') self.__smb = self.trans.get_smb_connection() self.__smb.setTimeout(100000) self.__tid = self.__smb.connectTree('IPC$') self.__fid_main = self.openPipe(self.__smb, self.__tid, '\\RemCom_communicaton', 0x12019f) packet = RemComMessage() packet['Machine'] = ''.join( [random.choice(string.ascii_letters) for i in range(4)]) packet['Command'] = os.path.basename(command.replace('\\', '/')) packet['ProcessID'] = os.getpid() self.__smb.writeNamedPipe(self.__tid, self.__fid_main, packet.getData()) # Here we'll store the command we type so we don't print it back ;) # ( I know.. globals are nasty :P ) global LastDataSent LastDataSent = '' # Create the pipes threads stdin_pipe = RemoteStdInPipe( self.trans, '\\%s%s%d' % (RemComSTDIN, packet['Machine'], packet['ProcessID']), smb.FILE_WRITE_DATA | smb.FILE_APPEND_DATA, self.share) stdin_pipe.start() stdout_pipe = RemoteStdOutPipe( self.trans, '\\%s%s%d' % (RemComSTDOUT, packet['Machine'], packet['ProcessID']), smb.FILE_READ_DATA) stdout_pipe.start() stderr_pipe = RemoteStdErrPipe( self.trans, '\\%s%s%d' % (RemComSTDERR, packet['Machine'], packet['ProcessID']), smb.FILE_READ_DATA) stderr_pipe.start() # And we stay here till the end ans = self.__smb.readNamedPipe(self.__tid, self.__fid_main, 8) if len(ans): retCode = RemComResponse(ans) logger.info( 'Process %s finished with ErrorCode: %d, ReturnCode: %d' % (os.path.basename(command.replace( '\\', '/')), retCode['ErrorCode'], retCode['ReturnCode'])) self.undeploy(srvname)
def doStuff(self, rpctransport): """.""" dce = dcerpc.DCERPC_v5(rpctransport) try: dce.connect() except Exception as e: print(e) sys.exit(1) global dialect dialect = rpctransport.get_smb_connection().getDialect() try: unInstalled = False s = rpctransport.get_smb_connection() # We don't wanna deal with timeouts from now on. s.setTimeout(100000) svcName = "RackspaceSystemDiscovery" executableName = "RackspaceSystemDiscovery.exe" if self.__exeFile is None: svc = remcomsvc.RemComSvc() installService = serviceinstall.ServiceInstall(s, svc, svcName, executableName) else: try: f = open(self.__exeFile) except Exception as e: print(e) sys.exit(1) installService = serviceinstall.ServiceInstall(s, f, svcName, executableName) installService.install() if self.__exeFile is not None: f.close() tid = s.connectTree('IPC$') fid_main = self.openPipe(s, tid, '\RemCom_communicaton', 0x12019f) packet = RemComMessage() pid = os.getpid() packet['Machine'] = ''.join([random.choice(string.letters) for i in range(4)]) if self.__path is not None: packet['WorkingDir'] = self.__path packet['Command'] = self.__command packet['ProcessID'] = pid s.writeNamedPipe(tid, fid_main, str(packet)) # Here we'll store the command we type so we don't print it back ;) # ( I know.. globals are nasty :P ) global LastDataSent LastDataSent = '' retCode = None # Create the pipes threads stdin_pipe = RemoteStdInPipe(rpctransport, '\%s%s%d' % (RemComSTDIN, packet['Machine'], packet['ProcessID']), smbconnection.smb.FILE_WRITE_DATA | smbconnection.smb.FILE_APPEND_DATA, installService.getShare()) stdin_pipe.start() stdout_pipe = RemoteStdOutPipe(rpctransport, '\%s%s%d' % (RemComSTDOUT, packet['Machine'], packet['ProcessID']), smbconnection.smb.FILE_READ_DATA) stdout_pipe.start() stderr_pipe = RemoteStdErrPipe(rpctransport, '\%s%s%d' % (RemComSTDERR, packet['Machine'], packet['ProcessID']), smbconnection.smb.FILE_READ_DATA) stderr_pipe.start() # And we stay here till the end ans = s.readNamedPipe(tid, fid_main, 8) if len(ans): retCode = RemComResponse(ans) print("[*] Process %s finished with ErrorCode: %d, " "ReturnCode: %d" % (self.__command, retCode['ErrorCode'], retCode['ReturnCode'])) installService.uninstall() unInstalled = True sys.exit(retCode['ReturnCode']) except Exception: if unInstalled is False: installService.uninstall() sys.stdout.flush() if retCode: sys.exit(retCode['ReturnCode']) else: sys.exit(1)
def execute(self, command, output=False): stringbinding = r'ncacn_np:%s[\pipe\svcctl]' % self.__host logging.debug('StringBinding %s' % stringbinding) rpctransport = transport.DCERPCTransportFactory(stringbinding) rpctransport.set_dport(self.__port) rpctransport.setRemoteHost(self.__host) if hasattr(rpctransport, 'set_credentials'): # This method exists only for selected protocol sequences. rpctransport.set_credentials(self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, self.__aesKey) rpctransport.set_kerberos(self.__doKerberos, self.__kdcHost) #doStuff in impacket dce = rpctransport.get_dce_rpc() try: dce.connect() except Exception as e: if logging.getLogger().level == logging.DEBUG: import traceback traceback.print_exc() logging.critical(str(e)) sys.exit(1) global dialect dialect = rpctransport.get_smb_connection().getDialect() try: unInstalled = False s = rpctransport.get_smb_connection() # We don't wanna deal with timeouts from now on. s.setTimeout(100000) if self.__exeFile is None: installService = serviceinstall.ServiceInstall( rpctransport.get_smb_connection(), remcomsvc.RemComSvc(), self.__serviceName) else: try: f = open(self.__exeFile) except Exception as e: logging.critical(str(e)) sys.exit(1) installService = serviceinstall.ServiceInstall( rpctransport.get_smb_connection(), f) if installService.install() is False: return if self.__exeFile is not None: f.close() # Check if we need to copy a file for execution if self.__copyFile is not None: installService.copy_file(self.__copyFile, installService.getShare(), os.path.basename(self.__copyFile)) # And we change the command to be executed to this filename self.__command = os.path.basename( self.__copyFile) + ' ' + self.__command tid = s.connectTree('IPC$') fid_main = self.openPipe(s, tid, r'\RemCom_communicaton', 0x12019f) packet = RemComMessage() pid = os.getpid() packet['Machine'] = ''.join( [random.choice(string.ascii_letters) for _ in range(4)]) if self.__path is not None: packet['WorkingDir'] = self.__path packet['Command'] = command packet['ProcessID'] = pid s.writeNamedPipe(tid, fid_main, packet.getData()) # Here we'll store the command we type so we don't print it back ;) # ( I know.. globals are nasty :P ) global LastDataSent LastDataSent = '' # Create the pipes threads stdin_pipe = RemoteStdInPipe( rpctransport, r'\%s%s%d' % (RemComSTDIN, packet['Machine'], packet['ProcessID']), smb.FILE_WRITE_DATA | smb.FILE_APPEND_DATA, installService.getShare(), command) stdin_pipe.start() stdout_pipe = RemoteStdOutPipe( rpctransport, r'\%s%s%d' % (RemComSTDOUT, packet['Machine'], packet['ProcessID']), smb.FILE_READ_DATA) stdout_pipe.start() stderr_pipe = RemoteStdErrPipe( rpctransport, r'\%s%s%d' % (RemComSTDERR, packet['Machine'], packet['ProcessID']), smb.FILE_READ_DATA) stderr_pipe.start() # And we stay here till the end ans = s.readNamedPipe(tid, fid_main, 8) #pdb.set_trace() if len(ans): retCode = RemComResponse(ans) logging.info( "Process %s finished with ErrorCode: %d, ReturnCode: %d" % (self.__command, retCode['ErrorCode'], retCode['ReturnCode'])) installService.uninstall() if self.__copyFile is not None: # We copied a file for execution, let's remove it s.deleteFile(installService.getShare(), os.path.basename(self.__copyFile)) unInstalled = True except: print('error') pass #read our result file - this executes in RemoteStdInPipe.run functions with open(cfg.TEST_PATH, 'r') as file: data = file.read() return data
class PSEXEC: KNOWN_PROTOCOLS = { '139/SMB': (r'ncacn_np:%s[\pipe\svcctl]', 139), '445/SMB': (r'ncacn_np:%s[\pipe\svcctl]', 445), } def __init__(self, command, path, protocols=None, username='', password='', domain='', hashes=None): if not protocols: protocols = PSEXEC.KNOWN_PROTOCOLS.keys() self.__username = username self.__password = password self.__protocols = [protocols] self.__command = command self.__path = path self.__domain = domain self.__lmhash = '' self.__nthash = '' if hashes is not None: self.__lmhash, self.__nthash = hashes.split(':') def run(self, addr): for protocol in self.__protocols: protodef = PSEXEC.KNOWN_PROTOCOLS[protocol] port = protodef[1] #print "Trying protocol %s...\n" % protocol stringbinding = protodef[0] % addr rpctransport = transport.DCERPCTransportFactory(stringbinding) rpctransport.set_dport(port) if hasattr(rpctransport, 'set_credentials'): # This method exists only for selected protocol sequences. rpctransport.set_credentials(self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash) if self.doStuff(rpctransport): return True else: return False def openPipe(self, s, tid, pipe, accessMask): s.waitNamedPipe(tid, pipe) ntCreate = smb.SMBCommand(smb.SMB.SMB_COM_NT_CREATE_ANDX) ntCreate['Parameters'] = smb.SMBNtCreateAndX_Parameters() ntCreate['Data'] = smb.SMBNtCreateAndX_Data() ntCreate['Parameters']['FileNameLength'] = len(pipe) ntCreate['Parameters']['FileAttributes'] = 0x80 ntCreate['Parameters']['CreateFlags'] = 0x0 ntCreate['Parameters']['AccessMask'] = accessMask ntCreate['Parameters']['CreateOptions'] = 0x40 ntCreate['Parameters']['ShareAccess'] = 0x7 ntCreate['Data']['FileName'] = pipe fid = s.nt_create_andx(tid, pipe, cmd=ntCreate) return fid def doStuff(self, rpctransport): dce = dcerpc.DCERPC_v5(rpctransport) try: dce.connect() except Exception, e: #print e sys.exit(1) try: unInstalled = False s = rpctransport.get_smb_server() # We don't wanna deal with timeouts from now on. s.set_timeout(100000) installService = serviceinstall.ServiceInstall( rpctransport.get_smb_server(), remcomsvc.RemComSvc()) installService.install() tid = s.tree_connect_andx('\\\\%s\\IPC$' % s.get_remote_name()) fid_main = self.openPipe(s, tid, '\RemCom_communicaton', 0x12019f) packet = RemComMessage() pid = os.getpid() packet['Machine'] = ''.join( [random.choice(string.letters) for i in range(4)]) if self.__path is not None: packet['WorkingDir'] = self.__path packet['Command'] = self.__command packet['ProcessID'] = pid s.write_andx(tid, fid_main, str(packet), write_pipe_mode=True) # Here we'll store the command we type so we don't print it back ;) # ( I know.. globals are nasty :P ) global LastDataSent LastDataSent = '' # Create the pipes threads stdin_pipe = RemoteStdInPipe( rpctransport, '\%s%s%d' % (RemComSTDIN, packet['Machine'], packet['ProcessID']), smb.FILE_WRITE_DATA | smb.FILE_APPEND_DATA, installService.getShare()) stdin_pipe.start() stdout_pipe = RemoteStdOutPipe( rpctransport, '\%s%s%d' % (RemComSTDOUT, packet['Machine'], packet['ProcessID']), smb.FILE_READ_DATA) stdout_pipe.start() stderr_pipe = RemoteStdErrPipe( rpctransport, '\%s%s%d' % (RemComSTDERR, packet['Machine'], packet['ProcessID']), smb.FILE_READ_DATA) stderr_pipe.start() # And we stay here till the end ans = s.read_andx(tid, fid_main, 8, wait_answer=0) readAndXResponse = smb.SMBCommand(ans['Data'][0]) readAndXParameters = smb.SMBReadAndXResponse_Parameters( readAndXResponse['Parameters']) offset = readAndXParameters['DataOffset'] count = readAndXParameters[ 'DataCount'] + 0x10000 * readAndXParameters['DataCount_Hi'] if count > 0: retCode = RemComResponse(str(ans)[offset:offset + count]) print "[*] Process %s finished with ErrorCode: %d, ReturnCode: %d" % ( self.__command, retCode['ErrorCode'], retCode['ReturnCode']) installService.uninstall() unInstalled = True return True sys.exit(retCode['ErrorCode']) except: if unInstalled is False: installService.uninstall() sys.stdout.flush() return False sys.exit(1)