server side of basic RDP security layer

This commit is contained in:
citronneur
2014-12-16 22:11:48 +01:00
parent a0ae3d97ec
commit 69b3f6befe
5 changed files with 36 additions and 15 deletions

View File

@@ -310,7 +310,7 @@ class ServerCertificate(CompositeType):
@summary: Server certificate structure @summary: Server certificate structure
@see: http://msdn.microsoft.com/en-us/library/cc240521.aspx @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) CompositeType.__init__(self, readLen = readLen, conditional = conditional)
self.dwVersion = UInt32Le() self.dwVersion = UInt32Le()
@@ -322,7 +322,12 @@ class ServerCertificate(CompositeType):
if self.dwVersion.value & 0x7fffffff == c._TYPE_: if self.dwVersion.value & 0x7fffffff == c._TYPE_:
return c() return c()
raise InvalidExpectedDataException("unknown certificate type : %s "%hex(self.dwVersion.value)) 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) self.certData = FactoryType(CertificateFactory)
def bin2bn(b): def bin2bn(b):
@@ -399,8 +404,8 @@ class RSAPublicKey(CompositeType):
CompositeType.__init__(self, readLen = readLen) CompositeType.__init__(self, readLen = readLen)
self.magic = UInt32Le(0x31415352, constant = True) self.magic = UInt32Le(0x31415352, constant = True)
self.keylen = UInt32Le(lambda:sizeof(self.modulus)) self.keylen = UInt32Le(lambda:sizeof(self.modulus))
self.bitlen = UInt32Le() self.bitlen = UInt32Le(lambda:((self.keylen.value - 8) * 8))
self.datalen = UInt32Le() self.datalen = UInt32Le(lambda:((self.bitlen.value / 8) - 1))
self.pubExp = UInt32Le() self.pubExp = UInt32Le()
self.modulus = String(readLen = UInt16Le(lambda:(self.keylen.value - 8))) self.modulus = String(readLen = UInt16Le(lambda:(self.keylen.value - 8)))
self.padding = String(readLen = UInt8(8)) self.padding = String(readLen = UInt8(8))

View File

@@ -31,6 +31,7 @@ from rdpy.protocol.rdp.ber import writeLength
import rdpy.core.log as log import rdpy.core.log as log
import ber, gcc, per import ber, gcc, per
import rsa
class Message(object): class Message(object):
""" """
@@ -487,8 +488,14 @@ class Server(MCSLayer):
""" """
#basic rdp security layer #basic rdp security layer
if self._transport._selectedProtocol == 0: 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.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._serverSettings.SC_CORE.clientRequestedProtocol.value = self._transport._requestedProtocol
self.setNextState(self.recvConnectInitial) self.setNextState(self.recvConnectInitial)

View File

@@ -324,11 +324,10 @@ class RDPServerController(pdu.layer.PDUServerListener):
""" """
@summary: Controller use in server side mode @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 privateKeyFileName: file contain server private key
@param certficiateFileName: file that contain public key @param certficiateFileName: file that contain public key
@param rsaKeys: {Tuple(rsa.PublicKey, rsa.PrivateKey)} rsa crypto
@param colorDepth: 15, 16, 24 @param colorDepth: 15, 16, 24
""" """
self._isReady = False self._isReady = False
@@ -337,7 +336,7 @@ class RDPServerController(pdu.layer.PDUServerListener):
#build RDP protocol stack #build RDP protocol stack
self._pduLayer = pdu.layer.Server(self) self._pduLayer = pdu.layer.Server(self)
#secure layer #secure layer
self._secLayer = sec.Server(self._pduLayer, rsaKeys) self._secLayer = sec.Server(self._pduLayer)
#multi channel service #multi channel service
self._mcsLayer = mcs.Server(self._secLayer) self._mcsLayer = mcs.Server(self._secLayer)
#transport pdu layer #transport pdu layer

View File

@@ -586,15 +586,13 @@ class Server(SecLayer):
""" """
@summary: Client side of security layer @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) SecLayer.__init__(self, presentation)
self._rsaPublicKey, self._rsaPrivateKey = None, None self._rsaPublicKey, self._rsaPrivateKey = rsa.newkeys(512)
if not rsaKeys is None:
self._rsaPublicKey, self._rsaPrivateKey = rsaKeys
def connect(self): def connect(self):
""" """
@summary: init automata to wait info packet @summary: init automata to wait info packet
@@ -612,6 +610,18 @@ class Server(SecLayer):
""" """
message = ClientSecurityExchangePDU() message = ClientSecurityExchangePDU()
s.readType(message) 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): def recvInfoPkt(self, s):

View File

@@ -256,7 +256,7 @@ class Server(X224Layer):
#match best security layer available #match best security layer available
if not self._serverPrivateKeyFileName is None and not self._serverCertificateFileName is None: 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: else:
self._selectedProtocol = self._requestedProtocol & Protocols.PROTOCOL_RDP self._selectedProtocol = self._requestedProtocol & Protocols.PROTOCOL_RDP