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 recvConnectionRequest(self, data): """ @summary: Read connection confirm packet Next state is send connection confirm @param data: {Stream} @see : http://msdn.microsoft.com/en-us/library/cc240470.aspx """ message = ClientConnectionRequestPDU() data.readType(message) if not message.protocolNeg._is_readed: self._requestedProtocol = Protocols.PROTOCOL_RDP else: self._requestedProtocol = message.protocolNeg.selectedProtocol.value #match best security layer available if not self._serverPrivateKeyFileName is None and not self._serverCertificateFileName is None: self._selectedProtocol = self._requestedProtocol & Protocols.PROTOCOL_SSL else: self._selectedProtocol = self._requestedProtocol & Protocols.PROTOCOL_RDP #if force ssl is enable if not self._selectedProtocol & Protocols.PROTOCOL_SSL and self._forceSSL: log.warning("server reject client because doesn't support SSL") #send error message and quit message = ServerConnectionConfirm() message.protocolNeg.code.value = NegociationType.TYPE_RDP_NEG_FAILURE message.protocolNeg.failureCode.value = NegotiationFailureCode.SSL_REQUIRED_BY_SERVER self._transport.send(message) self.close() return self.sendConnectionConfirm()
def sendClientRandom(self): """ @summary: generate and send client random and init session keys """ #generate client random clientRandom = rsa.random(256) self._macKey, self._initialDecrytKey, self._initialEncryptKey = 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) #verify certificate if not self.getGCCServerSettings( ).SC_SECURITY.serverCertificate.certData.verify(): log.warning("cannot verify server identity") #send client random encrypted with serverPublicKey = self.getGCCServerSettings( ).SC_SECURITY.serverCertificate.certData.getPublicKey() message = ClientSecurityExchangePDU() #reverse because bignum in little endian message.encryptedClientRandom.value = rsa.encrypt( clientRandom[::-1], serverPublicKey)[::-1] self.sendFlagged(SecurityFlag.SEC_EXCHANGE_PKT, message)
def sendClientRandom(self): """ @summary: generate and send client random and init session keys """ #generate client random clientRandom = rsa.random(256) self._macKey, self._initialDecrytKey, self._initialEncryptKey = 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) #verify certificate if not self.getGCCServerSettings().SC_SECURITY.serverCertificate.certData.verify(): log.warning("cannot verify server identity") #send client random encrypted with serverPublicKey = self.getGCCServerSettings().SC_SECURITY.serverCertificate.certData.getPublicKey() message = ClientSecurityExchangePDU() #reverse because bignum in little endian message.encryptedClientRandom.value = rsa.encrypt(clientRandom[::-1], serverPublicKey)[::-1] self.sendFlagged(SecurityFlag.SEC_EXCHANGE_PKT, message)
def recvConnectionConfirm(self, data): """ @summary: Receive connection confirm message Next state is recvData Call connect on presentation layer if all is good @param data: Stream that contain connection confirm @see: response -> http://msdn.microsoft.com/en-us/library/cc240506.aspx @see: failure ->http://msdn.microsoft.com/en-us/library/cc240507.aspx """ message = ServerConnectionConfirm() data.readType(message) if message.protocolNeg.failureCode._is_readed: pass #check presence of negotiation response if message.protocolNeg._is_readed: self._selectedProtocol = message.protocolNeg.selectedProtocol.value else: self._selectedProtocol = Protocols.PROTOCOL_RDP #NLA protocol doesn't support in actual version of RDPY if self._selectedProtocol in [Protocols.PROTOCOL_HYBRID_EX]: raise InvalidExpectedDataException( "RDPY doesn't support PROTOCOL_HYBRID_EX security Layer") #now i'm ready to receive data self.setNextState(self.recvData) if self._selectedProtocol == Protocols.PROTOCOL_RDP: log.warning('Client connected using RDP Security') # log.warning("*" * 43) # log.warning("*" + " " * 10 + "RDP Security selected" + " " * 10 + "*") # log.warning("*" * 43) #connection is done send to presentation self._presentation.connect() elif self._selectedProtocol == Protocols.PROTOCOL_SSL: log.warning('Client connected using SSL Security') # log.info("*" * 43) # log.info("*" + " " * 10 + "SSL Security selected" + " " * 10 + "*") # log.info("*" * 43) self._transport.startTLS(ClientTLSContext()) #connection is done send to presentation self._presentation.connect() elif self._selectedProtocol == Protocols.PROTOCOL_HYBRID: log.warning('Client connected using NLA Security') # log.info("*" * 43) # log.info("*" + " " * 10 + "NLA Security selected" + " " * 10 + "*") # log.info("*" * 43) self._transport.startNLA(ClientTLSContext(), lambda: self._presentation.connect())
def recvConnectionConfirm(self, data): """ @summary: Receive connection confirm message Next state is recvData Call connect on presentation layer if all is good @param data: Stream that contain connection confirm @see: response -> http://msdn.microsoft.com/en-us/library/cc240506.aspx @see: failure ->http://msdn.microsoft.com/en-us/library/cc240507.aspx """ message = ServerConnectionConfirm() data.readType(message) if message.protocolNeg.failureCode._is_readed: pass #check presence of negotiation response if message.protocolNeg._is_readed: self._selectedProtocol = message.protocolNeg.selectedProtocol.value else: self._selectedProtocol = Protocols.PROTOCOL_RDP #NLA protocol doesn't support in actual version of RDPY if self._selectedProtocol in [ Protocols.PROTOCOL_HYBRID_EX ]: raise InvalidExpectedDataException("RDPY doesn't support PROTOCOL_HYBRID_EX security Layer") #now i'm ready to receive data self.setNextState(self.recvData) if self._selectedProtocol == Protocols.PROTOCOL_RDP: log.warning("*" * 43) log.warning("*" + " " * 10 + "RDP Security selected" + " " * 10 + "*") log.warning("*" * 43) #connection is done send to presentation self._presentation.connect() elif self._selectedProtocol == Protocols.PROTOCOL_SSL: log.info("*" * 43) log.info("*" + " " * 10 + "SSL Security selected" + " " * 10 + "*") log.info("*" * 43) self._transport.startTLS(ClientTLSContext()) #connection is done send to presentation self._presentation.connect() elif self._selectedProtocol == Protocols.PROTOCOL_HYBRID: log.info("*" * 43) log.info("*" + " " * 10 + "NLA Security selected" + " " * 10 + "*") log.info("*" * 43) self._transport.startNLA(ClientTLSContext(), lambda:self._presentation.connect())