def recvDemandActivePDU(self, s): """ @summary: Receive demand active PDU which contains Server capabilities. In this version of RDPY only Restricted group of capabilities are used. Send Confirm Active PDU Send Finalize PDU Wait Server Synchronize PDU @param s: Stream """ pdu = data.PDU() s.readType(pdu) if pdu.shareControlHeader.pduType.value != data.PDUType.PDUTYPE_DEMANDACTIVEPDU: #not a blocking error because in deactive reactive sequence #input can be send too but ignored log.debug("Ignore message type %s during connection sequence" % hex(pdu.shareControlHeader.pduType.value)) return self._shareId = pdu.pduMessage.shareId.value for cap in pdu.pduMessage.capabilitySets._array: self._serverCapabilities[cap.capabilitySetType] = cap #secure checksum cap here maybe protocol (another) design error self._transport._enableSecureCheckSum = bool( self._serverCapabilities[ caps.CapsType.CAPSTYPE_GENERAL].capability.extraFlags & caps.GeneralExtraFlag.ENC_SALTED_CHECKSUM) self.sendConfirmActivePDU() #send synchronize self.sendClientFinalizeSynchronizePDU() self.setNextState(self.recvServerSynchronizePDU)
def readEncryptedPayload(self, s, saltedMacGeneration): """ @summary: decrypt basic RDP security payload @param s: {Stream} encrypted stream @param saltedMacGeneration: {bool} use salted mac generation @return: {Stream} decrypted """ #if update is needed if self._nbDecryptedPacket == 4096: log.debug("update decrypt key") self._currentDecrytKey = updateKey( self._initialDecrytKey, self._currentDecrytKey, self.getGCCServerSettings().SC_SECURITY.encryptionMethod.value) self._decryptRc4 = rc4.RC4Key(self._currentDecrytKey) self._nbDecryptedPacket = 0 signature = String(readLen = CallableValue(8)) encryptedPayload = String() s.readType((signature, encryptedPayload)) decrypted = rc4.crypt(self._decryptRc4, encryptedPayload.value) #ckeck signature if not saltedMacGeneration and macData(self._macKey, decrypted)[:8] != signature.value: raise InvalidExpectedDataException("bad signature") if saltedMacGeneration and macSaltedData(self._macKey, decrypted, self._nbDecryptedPacket)[:8] != signature.value: raise InvalidExpectedDataException("bad signature") #count self._nbDecryptedPacket += 1 return Stream(decrypted)
def sendConnectionConfirm(self): """ @summary: Write connection confirm message Start TLS connection Next state is recvData @see : http://msdn.microsoft.com/en-us/library/cc240501.aspx """ message = ServerConnectionConfirm( ) # flags should be 0xf and result should be 0x8 message.protocolNeg.flag.value = 0xf message.protocolNeg.code.value = NegociationType.TYPE_RDP_NEG_RSP message.protocolNeg.selectedProtocol.value = self._selectedProtocol self._transport.send(message) if self._selectedProtocol == Protocols.PROTOCOL_SSL: log.error('error in protocol selection.SSL chosen') return if self._selectedProtocol == Protocols.PROTOCOL_HYBRID: log.debug('hybrid chosen') else: log.error('selected protocol ', self._selectedProtocol) #_transport is TPKT and transport is TCP layer of twisted ctx = (ServerTLSContext(self._serverPrivateKeyFileName, self._serverCertificateFileName)) self._transport.startTLS(ctx) #connection is done send to presentation self.setNextState(self.recvData) self._presentation.connect()
def getPublicKey(self): """ @return: {Tuple} (modulus, publicExponent) """ log.debug("read RSA public key from proprietary certificate") #reverse because bignum in little endian return rsa.PublicKey(self.PublicKeyBlob.pubExp.value, self.PublicKeyBlob.modulus.value[::-1])
def writeEncryptedPayload(self, data, saltedMacGeneration): """ @summary: sign and crypt data @param data: {Type} raw stream @param saltedMacGeneration: {bool} use salted mac generation @return: {Tuple} (signature, encryptedData) """ if self._nbEncryptedPacket == 4096: log.debug("update encrypt key") self._currentEncryptKey = updateKey( self._initialEncryptKey, self._currentEncryptKey, self.getGCCServerSettings().SC_SECURITY.encryptionMethod.value) self._encryptRc4 = rc4.RC4Key(self._currentEncryptKey) self._nbEncryptedPacket = 0 self._nbEncryptedPacket += 1 s = Stream() s.writeType(data) if saltedMacGeneration: return (String( macSaltedData(self._macKey, s.getvalue(), self._nbEncryptedPacket - 1)[:8]), String(rc4.crypt(self._encryptRc4, s.getvalue()))) else: return (String(macData(self._macKey, s.getvalue())[:8]), String(rc4.crypt(self._encryptRc4, s.getvalue())))
def __read__(self, s): """ @summary: Read composite type Call read on each ordered sub-type And check read length parameter If an error occurred rollback type already read @param s: Stream @raise InvalidSize: if stream is greater than readLen parameter """ readLen = 0 for name in self._typeName: try: s.readType(self.__dict__[name]) readLen += sizeof(self.__dict__[name]) #read is ok but read out of bound if not self._readLen is None and readLen > self._readLen.value: #roll back s.pos -= sizeof(self.__dict__[name]) #and notify if not optional if not self.__dict__[name]._optional: raise InvalidSize("Impossible to read type %s : read length is too small"%(self.__class__)) except Exception as e: log.error("Error during read %s::%s"%(self.__class__, name)) #roll back already read for tmpName in self._typeName: if tmpName == name: break s.pos -= sizeof(self.__dict__[tmpName]) raise e if not self._readLen is None and readLen < self._readLen.value: log.debug("Still have correct data in packet %s, read %s bytes as padding"%(self.__class__, self._readLen.value - readLen)) s.read(self._readLen.value - readLen)
def recvDemandActivePDU(self, s): """ @summary: Receive demand active PDU which contains Server capabilities. In this version of RDPY only Restricted group of capabilities are used. Send Confirm Active PDU Send Finalize PDU Wait Server Synchronize PDU @param s: Stream """ pdu = data.PDU() s.readType(pdu) if pdu.shareControlHeader.pduType.value != data.PDUType.PDUTYPE_DEMANDACTIVEPDU: #not a blocking error because in deactive reactive sequence #input can be send too but ignored log.debug("Ignore message type %s during connection sequence"%hex(pdu.shareControlHeader.pduType.value)) return self._shareId = pdu.pduMessage.shareId.value for cap in pdu.pduMessage.capabilitySets._array: self._serverCapabilities[cap.capabilitySetType] = cap #secure checksum cap here maybe protocol (another) design error self._transport._enableSecureCheckSum = bool(self._serverCapabilities[caps.CapsType.CAPSTYPE_GENERAL].capability.extraFlags & caps.GeneralExtraFlag.ENC_SALTED_CHECKSUM) self.sendConfirmActivePDU() #send synchronize self.sendClientFinalizeSynchronizePDU() self.setNextState(self.recvServerSynchronizePDU)
def recvInfoPkt(self, s): """ @summary: receive info packet from client Client credentials Send License valid error message Send Demand Active PDU Wait Confirm Active PDU @param s: {Stream} """ securityFlag = UInt16Le() securityFlagHi = UInt16Le() s.readType((securityFlag, securityFlagHi)) log.debug("SEC_FLAG_INFO:" + str((securityFlag.value, SecurityFlag.SEC_INFO_PKT))) if not (securityFlag.value & SecurityFlag.SEC_INFO_PKT): raise InvalidExpectedDataException("Waiting info packet") if securityFlag.value & SecurityFlag.SEC_ENCRYPT: s = self.readEncryptedPayload( s, securityFlag.value & SecurityFlag.SEC_SECURE_CHECKSUM) _stream_data = s.getvalue() log.debug("S_DATA:" + (_stream_data)) s.readType(self._info) #next state send error license self.sendLicensingErrorMessage() #reinit state self.setNextState() self._presentation.connect()
def recvConfirmActivePDU(self, s): """ @summary: Receive confirm active PDU from client Capabilities exchange Wait Client Synchronize PDU @param s: Stream """ pdu = data.PDU() s.readType(pdu) if pdu.shareControlHeader.pduType.value != data.PDUType.PDUTYPE_CONFIRMACTIVEPDU: #not a blocking error because in deactive reactive sequence #input can be send too but ignored log.debug("Ignore message type %s during connection sequence"%hex(pdu.shareControlHeader.pduType.value)) return for cap in pdu.pduMessage.capabilitySets._array: self._clientCapabilities[cap.capabilitySetType] = cap #find use full flag self._clientFastPathSupported = bool(self._clientCapabilities[caps.CapsType.CAPSTYPE_GENERAL].capability.extraFlags.value & caps.GeneralExtraFlag.FASTPATH_OUTPUT_SUPPORTED) #secure checksum cap here maybe protocol (another) design error self._transport._enableSecureCheckSum = bool(self._clientCapabilities[caps.CapsType.CAPSTYPE_GENERAL].capability.extraFlags & caps.GeneralExtraFlag.ENC_SALTED_CHECKSUM) self.setNextState(self.recvClientSynchronizePDU)
def SlowPathInputDataFactory(): for c in [PointerEvent, ScancodeKeyEvent, UnicodeKeyEvent]: if self.messageType.value == c._INPUT_MESSAGE_TYPE_: return c() log.debug("unknown slow path input : %s" % hex(self.messageType.value)) return String()
def recvClientRandom(self, s): """ @summary: receive client random and generate session keys @param s: {Stream} """ #packet preambule securityFlag = UInt16Le() securityFlagHi = UInt16Le() s.readType((securityFlag, securityFlagHi)) log.debug("SEC_CLIENT_RANDOM:" + str((securityFlag.value, SecurityFlag.SEC_EXCHANGE_PKT))) if not (securityFlag.value & SecurityFlag.SEC_EXCHANGE_PKT): raise InvalidExpectedDataException("waiting client random") message = ClientSecurityExchangePDU() s.readType(message) clientRandom = rsa.decrypt(message.encryptedClientRandom.value[::-1], self._rsaPrivateKey)[::-1] self._macKey, self._initialEncryptKey, self._initialDecrytKey = generateKeys( clientRandom, self.getGCCServerSettings().SC_SECURITY.serverRandom.value, self.getGCCServerSettings().SC_SECURITY.encryptionMethod.value) #initialize keys self._currentDecrytKey = self._initialDecrytKey self._currentEncryptKey = self._initialEncryptKey self._decryptRc4 = rc4.RC4Key(self._currentDecrytKey) self._encryptRc4 = rc4.RC4Key(self._currentEncryptKey) self.setNextState(self.recvInfoPkt)
def checkPrompt(self): prompt = False binitial = self.countColor(self.initial, (0, 0, 0)) bfinal = self.countColor(self.final, (0, 0, 0)) winitial = self.countColor(self.initial, (255, 255, 255)) wfinal = self.countColor(self.final, (255, 255, 255)) # this is "good enough" if wfinal == winitial: # unlikely, but possible ratio = (bfinal - binitial) / float(wfinal) else: ratio = (bfinal - binitial) / float(wfinal - winitial) # bi: 108, bf: 1431, wi: 753, wf: 74051 # bi: 108, bf: 191513, wi: 753, wf: 3094 log.debug("bi: {}, bf: {}, wi: {}, wf: {}".format( binitial, bfinal, winitial, wfinal)) if ratio > 10: prompt = True log.info("Prompt detected") self.sendCommand(self.commands) else: log.warning("No prompt") if not self.methods or prompt: self.reactor.callLater(.5, self._controller.close) return log.debug("Trying next method: " + self.methods[-1].__name__) self.inittimer = None self.lastUpdate = None self.do_final = False self.initial = self.final.copy() del self.final self._scDownUp(0x01)
def recvConfirmActivePDU(self, s): """ @summary: Receive confirm active PDU from client Capabilities exchange Wait Client Synchronize PDU @param s: Stream """ pdu = data.PDU() s.readType(pdu) if pdu.shareControlHeader.pduType.value != data.PDUType.PDUTYPE_CONFIRMACTIVEPDU: #not a blocking error because in deactive reactive sequence #input can be send too but ignored log.debug("Ignore message type %s during connection sequence" % hex(pdu.shareControlHeader.pduType.value)) return for cap in pdu.pduMessage.capabilitySets._array: self._clientCapabilities[cap.capabilitySetType] = cap #find use full flag self._clientFastPathSupported = bool( self._clientCapabilities[ caps.CapsType.CAPSTYPE_GENERAL].capability.extraFlags.value & caps.GeneralExtraFlag.FASTPATH_OUTPUT_SUPPORTED) #secure checksum cap here maybe protocol (another) design error self._transport._enableSecureCheckSum = bool( self._clientCapabilities[ caps.CapsType.CAPSTYPE_GENERAL].capability.extraFlags & caps.GeneralExtraFlag.ENC_SALTED_CHECKSUM) self.setNextState(self.recvClientSynchronizePDU)
def __init__(self, name="", options=0): CompositeType.__init__(self) #name of channel self.name = String(name[0:8] + "\x00" * (8 - len(name)), readLen=CallableValue(8)) #unknown self.options = UInt32Le() log.debug("I AM USED ** %s" % (self.__class__))
def sendRegister(self, pubkeyauth): req = str(pubkeyauth) log.debug('request len ' + str(len(req) - 16 - 44)) self.signature = req[:60] resp = self.call(1, req[60:], None) #1 is opnum log.debug(str(resp)) answer = self.recv() #it will be ''
def getPublicKey(self): """ @return: {Tuple} (modulus, publicExponent) """ log.debug("read RSA public key from x509 certificate") #last certifcate contain public key n, e = x509.extractRSAKey(x509.load(self.CertBlobArray[-1].abCert.value)) return rsa.PublicKey(e, n)
def onClose(self): """ @summary: Call when stack is close """ if self.save: self.initial.save("initial.bmp") self.final.save("final.bmp") log.debug("closed")
def PDUDataFactory(): """ @summary: Create object in accordance self.shareDataHeader.pduType2 value """ for c in [UpdateDataPDU, SynchronizeDataPDU, ControlDataPDU, ErrorInfoDataPDU, FontListDataPDU, FontMapDataPDU, PersistentListPDU, ClientInputEventPDU, ShutdownDeniedPDU, ShutdownRequestPDU, SupressOutputDataPDU]: if self.shareDataHeader.pduType2.value == c._PDUTYPE2_: return c() log.debug("unknown PDU data type : %s"%hex(self.shareDataHeader.pduType2.value)) return String()
def UpdateDataFactory(): """ @summary: Create object in accordance self.updateType value """ for c in [BitmapUpdateDataPDU]: if self.updateType.value == c._UPDATE_TYPE_: return c() log.debug("unknown PDU update data type : %s"%hex(self.updateType.value)) return String()
def UpdateDataFactory(): """ @summary: Create correct object in accordance to self.updateHeader field """ for c in [FastPathBitmapUpdateDataPDU]: if (self.updateHeader.value & 0xf) == c._FASTPATH_UPDATE_TYPE_: return c() log.debug("unknown Fast Path PDU update data type : %s"%hex(self.updateHeader.value & 0xf)) return String()
def onClose(self): """ @summary: handle on close events """ if not self._isReady: log.debug("Close on non ready layer means authentication error") return for observer in self._clientObservers: observer.onClose()
def getPublicKey(self): """ @return: {Tuple} (modulus, publicExponent) """ log.debug("read RSA public key from x509 certificate") #last certifcate contain public key n, e = x509.extractRSAKey( x509.load(self.CertBlobArray[-1].abCert.value)) return rsa.PublicKey(e, n)
def CapabilityFactory(): """ Closure for capability factory """ for c in [GeneralCapability, BitmapCapability, OrderCapability, BitmapCacheCapability, PointerCapability, InputCapability, BrushCapability, GlyphCapability, OffscreenBitmapCacheCapability, VirtualChannelCapability, SoundCapability, ControlCapability, WindowActivationCapability, FontCapability, ColorCacheCapability, ShareCapability, MultiFragmentUpdate]: if self.capabilitySetType.value == c._TYPE_ and (self.lengthCapability.value - 4) > 0: return c(readLen = self.lengthCapability - 4) log.debug("unknown Capability type : %s"%hex(self.capabilitySetType.value)) #read entire packet return String(readLen = self.lengthCapability - 4)
def OrderFactory(): """ Closure for capability factory """ for c in [DstBltOrder]: if self.orderType.value == c._ORDER_TYPE_: return c(self.controlFlags) log.debug("unknown Order type : %s"%hex(self.orderType.value)) #read entire packet return String()
def EventFactory(): """ @summary: Closure for event factory """ for c in [UpdateEvent, ScreenEvent, InfoEvent, CloseEvent]: if self.type.value == c._TYPE_: return c(readLen = self.length) log.debug("unknown event type : %s"%hex(self.type.value)) #read entire packet return String(readLen = self.length)
def OrderFactory(): """ Closure for capability factory """ for c in [DstBltOrder]: if self.orderType.value == c._ORDER_TYPE_: return c(self.controlFlags) log.debug("unknown Order type : %s" % hex(self.orderType.value)) #read entire packet return String()
def PDUMessageFactory(): """ @summary: build message in accordance of type self.shareControlHeader.pduType.value """ for c in [DemandActivePDU, ConfirmActivePDU, DataPDU, DeactiveAllPDU]: if self.shareControlHeader.pduType.value == c._PDUTYPE_: return c() log.debug("unknown PDU type : %s"%hex(self.shareControlHeader.pduType.value)) #read entire packet return String()
def UpdateDataFactory(): """ @summary: Create object in accordance self.updateType value """ for c in [BitmapUpdateDataPDU]: if self.updateType.value == c._UPDATE_TYPE_: return c() log.debug("unknown PDU update data type : %s" % hex(self.updateType.value)) return String()
def UpdateDataFactory(): """ @summary: Create correct object in accordance to self.updateHeader field """ for c in [FastPathBitmapUpdateDataPDU]: if (self.updateHeader.value & 0xf) == c._FASTPATH_UPDATE_TYPE_: return c() log.debug("unknown Fast Path PDU update data type : %s" % hex(self.updateHeader.value & 0xf)) return String()
def LicensingMessageFactory(): """ @summary: factory for message nego Use in read mode """ for c in [LicensingErrorMessage, ServerLicenseRequest, ClientNewLicenseRequest, ServerPlatformChallenge, ClientPLatformChallengeResponse]: if self.bMsgtype.value == c._MESSAGE_TYPE_: return c(readLen = self.wMsgSize - 4) log.debug("unknown license message : %s"%self.bMsgtype.value) return String(readLen = self.wMsgSize - 4)
def DataBlockFactory(): """ @summary: build settings in accordance of type self.type.value """ for c in [ClientCoreData, ClientSecurityData, ClientNetworkData, ServerCoreData, ServerNetworkData, ServerSecurityData]: if self.type.value == c._TYPE_: return c(readLen = self.length - 4) log.debug("unknown GCC block type : %s"%hex(self.type.value)) #read entire packet return String(readLen = self.length - 4)
def DataBlockFactory(): """ @summary: build settings in accordance of type self.type.value """ for c in [ ClientCoreData, ClientSecurityData, ClientNetworkData, ServerCoreData, ServerNetworkData, ServerSecurityData ]: if self.type.value == c._TYPE_: return c(readLen=self.length - 4) log.debug("unknown GCC block type : %s" % hex(self.type.value)) #read entire packet return String(readLen=self.length - 4)
def PDUMessageFactory(): """ @summary: build message in accordance of type self.shareControlHeader.pduType.value """ for c in [ DemandActivePDU, ConfirmActivePDU, DataPDU, DeactiveAllPDU ]: if self.shareControlHeader.pduType.value == c._PDUTYPE_: return c() log.debug("unknown PDU type : %s" % hex(self.shareControlHeader.pduType.value)) #read entire packet return String()
def recvClientControlRequestPDU(self, s): """ @summary: Receive last control PDU the request control PDU from client Wait Font List PDU @param s: Stream from transport layer """ pdu = data.PDU() s.readType(pdu) if pdu.shareControlHeader.pduType.value != data.PDUType.PDUTYPE_DATAPDU or pdu.pduMessage.shareDataHeader.pduType2.value != data.PDUType2.PDUTYPE2_CONTROL or pdu.pduMessage.pduData.action.value != data.Action.CTRLACTION_REQUEST_CONTROL: #not a blocking error because in deactive reactive sequence #input can be send too but ignored log.debug("Ignore message type %s during connection sequence"%hex(pdu.shareControlHeader.pduType.value)) return self.setNextState(self.recvClientFontListPDU)
def recvClientSynchronizePDU(self, s): """ @summary: Receive from client Wait Control Cooperate PDU @param s: Stream from transport layer """ pdu = data.PDU() s.readType(pdu) if pdu.shareControlHeader.pduType.value != data.PDUType.PDUTYPE_DATAPDU or pdu.pduMessage.shareDataHeader.pduType2.value != data.PDUType2.PDUTYPE2_SYNCHRONIZE: #not a blocking error because in deactive reactive sequence #input can be send too but ignored log.debug("Ignore message type %s during connection sequence"%hex(pdu.shareControlHeader.pduType.value)) return self.setNextState(self.recvClientControlCooperatePDU)
def recvClientControlRequestPDU(self, s): """ @summary: Receive last control PDU the request control PDU from client Wait Font List PDU @param s: Stream from transport layer """ pdu = data.PDU() s.readType(pdu) if pdu.shareControlHeader.pduType.value != data.PDUType.PDUTYPE_DATAPDU or pdu.pduMessage.shareDataHeader.pduType2.value != data.PDUType2.PDUTYPE2_CONTROL or pdu.pduMessage.pduData.action.value != data.Action.CTRLACTION_REQUEST_CONTROL: #not a blocking error because in deactive reactive sequence #input can be send too but ignored log.debug("Ignore message type %s during connection sequence" % hex(pdu.shareControlHeader.pduType.value)) return self.setNextState(self.recvClientFontListPDU)
def recvClientSynchronizePDU(self, s): """ @summary: Receive from client Wait Control Cooperate PDU @param s: Stream from transport layer """ pdu = data.PDU() s.readType(pdu) if pdu.shareControlHeader.pduType.value != data.PDUType.PDUTYPE_DATAPDU or pdu.pduMessage.shareDataHeader.pduType2.value != data.PDUType2.PDUTYPE2_SYNCHRONIZE: #not a blocking error because in deactive reactive sequence #input can be send too but ignored log.debug("Ignore message type %s during connection sequence" % hex(pdu.shareControlHeader.pduType.value)) return self.setNextState(self.recvClientControlCooperatePDU)
def recvSecurityResult(self, data): """ Read security result packet Use by server to inform connection status of client @param data: Stream that contain well formed packet """ result = UInt32Be() data.readType(result) if result == UInt32Be(1): log.info("Authentification failed") if self._version.value == ProtocolVersion.RFB003008: self.expectWithHeader(4, self.recvSecurityFailed) else: log.debug("Authentification OK") self.sendClientInit()
def PDUDataFactory(): """ @summary: Create object in accordance self.shareDataHeader.pduType2 value """ for c in [ UpdateDataPDU, SynchronizeDataPDU, ControlDataPDU, ErrorInfoDataPDU, FontListDataPDU, FontMapDataPDU, PersistentListPDU, ClientInputEventPDU, ShutdownDeniedPDU, ShutdownRequestPDU, SupressOutputDataPDU ]: if self.shareDataHeader.pduType2.value == c._PDUTYPE2_: return c() log.debug("unknown PDU data type : %s" % hex(self.shareDataHeader.pduType2.value)) return String()
def recvServerControlCooperatePDU(self, s): """ @summary: Receive control cooperate PDU from server Wait Control Granted PDU @param s: Stream from transport layer """ pdu = data.PDU() s.readType(pdu) if pdu.shareControlHeader.pduType.value != data.PDUType.PDUTYPE_DATAPDU or pdu.pduMessage.shareDataHeader.pduType2.value != data.PDUType2.PDUTYPE2_CONTROL or pdu.pduMessage.pduData.action.value != data.Action.CTRLACTION_COOPERATE: #not a blocking error because in deactive reactive sequence #input can be send too but ignored log.debug("Ignore message type %s during connection sequence"%hex(pdu.shareControlHeader.pduType.value)) return self.setNextState(self.recvServerControlGrantedPDU)
def recvServerControlCooperatePDU(self, s): """ @summary: Receive control cooperate PDU from server Wait Control Granted PDU @param s: Stream from transport layer """ pdu = data.PDU() s.readType(pdu) if pdu.shareControlHeader.pduType.value != data.PDUType.PDUTYPE_DATAPDU or pdu.pduMessage.shareDataHeader.pduType2.value != data.PDUType2.PDUTYPE2_CONTROL or pdu.pduMessage.pduData.action.value != data.Action.CTRLACTION_COOPERATE: #not a blocking error because in deactive reactive sequence #input can be send too but ignored log.debug("Ignore message type %s during connection sequence" % hex(pdu.shareControlHeader.pduType.value)) return self.setNextState(self.recvServerControlGrantedPDU)
def sendKeyEvent(self, isDown, key): """ @summary: Send a key event throw RFB protocol @param isDown: boolean notify if key is pressed or not (True if key is pressed) @param key: ASCII code of key """ if not self._isReady: log.info("Try to send key event on non ready layer") return try: event = KeyEvent() event.downFlag.value = isDown event.key.value = key self._rfbLayer.sendKeyEvent(event) except InvalidValue: log.debug("Try to send an invalid key event")
def readDataPDU(self, dataPDU): """ @summary: read a data PDU object @param dataPDU: DataPDU object """ if dataPDU.shareDataHeader.pduType2.value == data.PDUType2.PDUTYPE2_SET_ERROR_INFO_PDU: errorMessage = "Unknown code %s"%hex(dataPDU.pduData.errorInfo.value) if data.ErrorInfo._MESSAGES_.has_key(dataPDU.pduData.errorInfo): errorMessage = data.ErrorInfo._MESSAGES_[dataPDU.pduData.errorInfo] log.error("INFO PDU : %s"%errorMessage) elif dataPDU.shareDataHeader.pduType2.value == data.PDUType2.PDUTYPE2_INPUT: self._listener.onSlowPathInput(dataPDU.pduData.slowPathInputEvents._array) elif dataPDU.shareDataHeader.pduType2.value == data.PDUType2.PDUTYPE2_SHUTDOWN_REQUEST: log.debug("Receive Shutdown Request") self._transport.close()
def recvServerFontMapPDU(self, s): """ @summary: Last useless connection packet from server to client Wait any PDU @param s: Stream from transport layer """ pdu = data.PDU() s.readType(pdu) if pdu.shareControlHeader.pduType.value != data.PDUType.PDUTYPE_DATAPDU or pdu.pduMessage.shareDataHeader.pduType2.value != data.PDUType2.PDUTYPE2_FONTMAP: #not a blocking error because in deactive reactive sequence #input can be send too but ignored log.debug("Ignore message type %s during connection sequence"%hex(pdu.shareControlHeader.pduType.value)) return self.setNextState(self.recvPDU) #here i'm connected self._listener.onReady()
def sendPointerEvent(self, mask, x, y): """ @summary: Send a pointer event throw RFB protocol @param mask: mask of button if button 1 and 3 are pressed then mask is 00000101 @param x: x coordinate of mouse pointer @param y: y pointer of mouse pointer """ if not self._isReady: log.info("Try to send pointer event on non ready layer") return try: event = PointerEvent() event.mask.value = mask event.x.value = x event.y.value = y self._rfbLayer.sendPointerEvent(event) except InvalidValue: log.debug("Try to send an invalid pointer event")
def sendConnectionConfirm(self): """ @summary: Write connection confirm message Start TLS connection Next state is recvData @see : http://msdn.microsoft.com/en-us/library/cc240501.aspx """ message = ServerConnectionConfirm() message.protocolNeg.code.value = NegociationType.TYPE_RDP_NEG_RSP message.protocolNeg.selectedProtocol.value = self._selectedProtocol self._transport.send(message) if self._selectedProtocol == Protocols.PROTOCOL_SSL: log.debug("*" * 10 + " select SSL layer " + "*" * 10) #_transport is TPKT and transport is TCP layer of twisted self._transport.startTLS(ServerTLSContext(self._serverPrivateKeyFileName, self._serverCertificateFileName)) #connection is done send to presentation self.setNextState(self.recvData) self._presentation.connect()
def recvClientFontListPDU(self, s): """ @summary: Last synchronize packet from client to server Send Server Finalize PDUs Wait any PDU @param s: Stream from transport layer """ pdu = data.PDU() s.readType(pdu) if pdu.shareControlHeader.pduType.value != data.PDUType.PDUTYPE_DATAPDU or pdu.pduMessage.shareDataHeader.pduType2.value != data.PDUType2.PDUTYPE2_FONTLIST: #not a blocking error because in deactive reactive sequence #input can be send but ignored log.debug("Ignore message type %s during connection sequence"%hex(pdu.shareControlHeader.pduType.value)) return #finalize server self.sendServerFinalizeSynchronizePDU() self.setNextState(self.recvPDU) #now i'm ready self._listener.onReady()
def writeEncryptedPayload(self, data, saltedMacGeneration): """ @summary: sign and crypt data @param data: {Type} raw stream @param saltedMacGeneration: {bool} use salted mac generation @return: {Tuple} (signature, encryptedData) """ if self._nbEncryptedPacket == 4096: log.debug("update encrypt key") self._currentEncryptKey = updateKey( self._initialEncryptKey, self._currentEncryptKey, self.getGCCServerSettings().SC_SECURITY.encryptionMethod.value) self._encryptRc4 = rc4.RC4Key(self._currentEncryptKey) self._nbEncryptedPacket = 0 self._nbEncryptedPacket += 1 s = Stream() s.writeType(data) if saltedMacGeneration: return (String(macSaltedData(self._macKey, s.getvalue(), self._nbEncryptedPacket - 1)[:8]), String(rc4.crypt(self._encryptRc4, s.getvalue()))) else: return (String(macData(self._macKey, s.getvalue())[:8]), String(rc4.crypt(self._encryptRc4, s.getvalue())))
def SlowPathInputDataFactory(): for c in [PointerEvent, ScancodeKeyEvent, UnicodeKeyEvent]: if self.messageType.value == c._INPUT_MESSAGE_TYPE_: return c() log.debug("unknown slow path input : %s"%hex(self.messageType.value)) return String()