diff --git a/rdpy/protocol/rdp/gcc.py b/rdpy/protocol/rdp/gcc.py index 3570e3f..6c6133f 100644 --- a/rdpy/protocol/rdp/gcc.py +++ b/rdpy/protocol/rdp/gcc.py @@ -310,7 +310,7 @@ class ServerCertificate(CompositeType): @summary: Server certificate structure @see: http://msdn.microsoft.com/en-us/library/cc240521.aspx """ - def __init__(self, readLen = None, conditional = lambda:True): + def __init__(self, certData = None, readLen = None, conditional = lambda:True): CompositeType.__init__(self, readLen = readLen, conditional = conditional) self.dwVersion = UInt32Le() @@ -322,7 +322,12 @@ class ServerCertificate(CompositeType): if self.dwVersion.value & 0x7fffffff == c._TYPE_: return c() raise InvalidExpectedDataException("unknown certificate type : %s "%hex(self.dwVersion.value)) - + + if certData is None: + certData = FactoryType(CertificateFactory) + elif not "_TYPE_" in certData.__class__.__dict__: + raise InvalidExpectedDataException("Try to send an invalid Certificate") + self.certData = FactoryType(CertificateFactory) def bin2bn(b): @@ -399,8 +404,8 @@ class RSAPublicKey(CompositeType): CompositeType.__init__(self, readLen = readLen) self.magic = UInt32Le(0x31415352, constant = True) self.keylen = UInt32Le(lambda:sizeof(self.modulus)) - self.bitlen = UInt32Le() - self.datalen = UInt32Le() + self.bitlen = UInt32Le(lambda:((self.keylen.value - 8) * 8)) + self.datalen = UInt32Le(lambda:((self.bitlen.value / 8) - 1)) self.pubExp = UInt32Le() self.modulus = String(readLen = UInt16Le(lambda:(self.keylen.value - 8))) self.padding = String(readLen = UInt8(8)) diff --git a/rdpy/protocol/rdp/mcs.py b/rdpy/protocol/rdp/mcs.py index e7be155..2b465e4 100644 --- a/rdpy/protocol/rdp/mcs.py +++ b/rdpy/protocol/rdp/mcs.py @@ -31,6 +31,7 @@ from rdpy.protocol.rdp.ber import writeLength import rdpy.core.log as log import ber, gcc, per +import rsa class Message(object): """ @@ -487,8 +488,14 @@ class Server(MCSLayer): """ #basic rdp security layer if self._transport._selectedProtocol == 0: + certificate = gcc.ProprietaryServerCertificate() + certificate.PublicKeyBlob.modulus.value = hex(self._presentation._rsaPublicKey.n)[2:-1].decode('hex')[::-1] + certificate.PublicKeyBlob.pubExp.value = self._presentation._rsaPublicKey.e + self._serverSettings.SC_SECURITY.encryptionMethod.value = gcc.EncryptionMethod.ENCRYPTION_FLAG_128BIT - self._serverSettings.SC_SECURITY.encryptionLevel = gcc.EncryptionLevel.ENCRYPTION_LEVEL_HIGH + self._serverSettings.SC_SECURITY.encryptionLevel.value = gcc.EncryptionLevel.ENCRYPTION_LEVEL_HIGH + self._serverSettings.SC_SECURITY.serverRandom.value = rsa.randnum.read_random_bits(256) + self._serverSettings.SC_SECURITY.serverCertificate.certData = certificate self._serverSettings.SC_CORE.clientRequestedProtocol.value = self._transport._requestedProtocol self.setNextState(self.recvConnectInitial) diff --git a/rdpy/protocol/rdp/rdp.py b/rdpy/protocol/rdp/rdp.py index 6aa3aae..375784d 100644 --- a/rdpy/protocol/rdp/rdp.py +++ b/rdpy/protocol/rdp/rdp.py @@ -324,11 +324,10 @@ class RDPServerController(pdu.layer.PDUServerListener): """ @summary: Controller use in server side mode """ - def __init__(self, colorDepth, privateKeyFileName = None, certificateFileName = None, rsaKeys = None): + def __init__(self, colorDepth, privateKeyFileName = None, certificateFileName = None): """ @param privateKeyFileName: file contain server private key @param certficiateFileName: file that contain public key - @param rsaKeys: {Tuple(rsa.PublicKey, rsa.PrivateKey)} rsa crypto @param colorDepth: 15, 16, 24 """ self._isReady = False @@ -337,7 +336,7 @@ class RDPServerController(pdu.layer.PDUServerListener): #build RDP protocol stack self._pduLayer = pdu.layer.Server(self) #secure layer - self._secLayer = sec.Server(self._pduLayer, rsaKeys) + self._secLayer = sec.Server(self._pduLayer) #multi channel service self._mcsLayer = mcs.Server(self._secLayer) #transport pdu layer diff --git a/rdpy/protocol/rdp/sec.py b/rdpy/protocol/rdp/sec.py index 85931d9..35ed65b 100644 --- a/rdpy/protocol/rdp/sec.py +++ b/rdpy/protocol/rdp/sec.py @@ -586,15 +586,13 @@ class Server(SecLayer): """ @summary: Client side of security layer """ - def __init__(self, presentation, rsaKeys = None): + def __init__(self, presentation): """ - @param rsaKeys: {Tuple(rsa.PublicKey, rsa.PrivateKey)} rsa crypto + @param presentation: {Layer} """ SecLayer.__init__(self, presentation) - self._rsaPublicKey, self._rsaPrivateKey = None, None - if not rsaKeys is None: - self._rsaPublicKey, self._rsaPrivateKey = rsaKeys - + self._rsaPublicKey, self._rsaPrivateKey = rsa.newkeys(512) + def connect(self): """ @summary: init automata to wait info packet @@ -612,6 +610,18 @@ class Server(SecLayer): """ message = ClientSecurityExchangePDU() s.readType(message) + clientRandom = rsa.decrypt(message.encryptedClientRandom.value, self._rsaPrivateKey) + + 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) + + self.setNextState(self.recvInfoPkt) def recvInfoPkt(self, s): diff --git a/rdpy/protocol/rdp/x224.py b/rdpy/protocol/rdp/x224.py index 24af912..26409c5 100644 --- a/rdpy/protocol/rdp/x224.py +++ b/rdpy/protocol/rdp/x224.py @@ -256,7 +256,7 @@ class Server(X224Layer): #match best security layer available if not self._serverPrivateKeyFileName is None and not self._serverCertificateFileName is None: - self._selectedProtocol = self._requestedProtocol & Protocols.PROTOCOL_SSL + self._selectedProtocol = self._requestedProtocol & Protocols.PROTOCOL_RDP else: self._selectedProtocol = self._requestedProtocol & Protocols.PROTOCOL_RDP