This commit is contained in:
citronneur
2015-02-16 22:29:42 +01:00
8 changed files with 136 additions and 68 deletions

View File

@@ -257,7 +257,7 @@ class SimpleType(Type, CallableValue):
@raise InvalidSize: if there is not enough data in stream @raise InvalidSize: if there is not enough data in stream
""" """
if s.dataLen() < self._typeSize: if s.dataLen() < self._typeSize:
raise InvalidSize("Stream is too small to read expected Simple") raise InvalidSize("Stream is too small to read expected SimpleType")
self.value = struct.unpack(self._structFormat, s.read(self._typeSize))[0] self.value = struct.unpack(self._structFormat, s.read(self._typeSize))[0]
def mask(self): def mask(self):
@@ -498,6 +498,9 @@ class CompositeType(Type):
@summary: Call sizeof on each sub type @summary: Call sizeof on each sub type
@return: sum of sizeof of each Type attributes @return: sum of sizeof of each Type attributes
""" """
if self._is_readed and not self._readLen is None:
return self._readLen.value
size = 0 size = 0
for name in self._typeName: for name in self._typeName:
size += sizeof(self.__dict__[name]) size += sizeof(self.__dict__[name])
@@ -808,7 +811,7 @@ class String(Type, CallableValue):
self.value = s.getvalue()[s.pos:] self.value = s.getvalue()[s.pos:]
else: else:
self.value = "" self.value = ""
while self.value[-len(self._until):] != self._until or s.dataLen() == 0: while self.value[-len(self._until):] != self._until and s.dataLen() != 0:
self.value += s.read(1) self.value += s.read(1)
else: else:
self.value = s.read(self._readLen.value) self.value = s.read(self._readLen.value)

View File

@@ -256,17 +256,17 @@ class ClientCoreData(CompositeType):
self.keyboardType = UInt32Le(KeyboardType.IBM_101_102_KEYS) self.keyboardType = UInt32Le(KeyboardType.IBM_101_102_KEYS)
self.keyboardSubType = UInt32Le(0) self.keyboardSubType = UInt32Le(0)
self.keyboardFnKeys = UInt32Le(12) self.keyboardFnKeys = UInt32Le(12)
self.imeFileName = String("\x00"*64, readLen = UInt8(64)) self.imeFileName = String("\x00"*64, readLen = UInt8(64), optional = True)
self.postBeta2ColorDepth = UInt16Le(ColorDepth.RNS_UD_COLOR_8BPP) self.postBeta2ColorDepth = UInt16Le(ColorDepth.RNS_UD_COLOR_8BPP, optional = True)
self.clientProductId = UInt16Le(1) self.clientProductId = UInt16Le(1, optional = True)
self.serialNumber = UInt32Le(0) self.serialNumber = UInt32Le(0, optional = True)
self.highColorDepth = UInt16Le(HighColor.HIGH_COLOR_24BPP) self.highColorDepth = UInt16Le(HighColor.HIGH_COLOR_24BPP, optional = True)
self.supportedColorDepths = UInt16Le(Support.RNS_UD_15BPP_SUPPORT | Support.RNS_UD_16BPP_SUPPORT | Support.RNS_UD_24BPP_SUPPORT | Support.RNS_UD_32BPP_SUPPORT) self.supportedColorDepths = UInt16Le(Support.RNS_UD_15BPP_SUPPORT | Support.RNS_UD_16BPP_SUPPORT | Support.RNS_UD_24BPP_SUPPORT | Support.RNS_UD_32BPP_SUPPORT, optional = True)
self.earlyCapabilityFlags = UInt16Le(CapabilityFlags.RNS_UD_CS_SUPPORT_ERRINFO_PDU) self.earlyCapabilityFlags = UInt16Le(CapabilityFlags.RNS_UD_CS_SUPPORT_ERRINFO_PDU, optional = True)
self.clientDigProductId = String("\x00"*64, readLen = UInt8(64)) self.clientDigProductId = String("\x00"*64, readLen = UInt8(64), optional = True)
self.connectionType = UInt8() self.connectionType = UInt8(optional = True)
self.pad1octet = UInt8() self.pad1octet = UInt8(optional = True)
self.serverSelectedProtocol = UInt32Le() self.serverSelectedProtocol = UInt32Le(optional = True)
class ServerCoreData(CompositeType): class ServerCoreData(CompositeType):
""" """
@@ -278,7 +278,8 @@ class ServerCoreData(CompositeType):
def __init__(self, readLen = None): def __init__(self, readLen = None):
CompositeType.__init__(self, readLen = readLen) CompositeType.__init__(self, readLen = readLen)
self.rdpVersion = UInt32Le(Version.RDP_VERSION_5_PLUS) self.rdpVersion = UInt32Le(Version.RDP_VERSION_5_PLUS)
self.clientRequestedProtocol = UInt32Le() self.clientRequestedProtocol = UInt32Le(optional = True)
self.earlyCapabilityFlags = UInt32Le(optional = True)
class ClientSecurityData(CompositeType): class ClientSecurityData(CompositeType):
""" """
@@ -353,8 +354,8 @@ class ProprietaryServerCertificate(CompositeType):
self.wPublicKeyBlobLen = UInt16Le(lambda:sizeof(self.PublicKeyBlob)) self.wPublicKeyBlobLen = UInt16Le(lambda:sizeof(self.PublicKeyBlob))
self.PublicKeyBlob = RSAPublicKey(readLen = self.wPublicKeyBlobLen) self.PublicKeyBlob = RSAPublicKey(readLen = self.wPublicKeyBlobLen)
self.wSignatureBlobType = UInt16Le(0x0008, constant = True) self.wSignatureBlobType = UInt16Le(0x0008, constant = True)
self.wSignatureBlobLen = UInt16Le(lambda:(sizeof(self.SignatureBlob) - 8)) self.wSignatureBlobLen = UInt16Le(lambda:(sizeof(self.SignatureBlob) + sizeof(self.padding)))
self.SignatureBlob = String(readLen = self.wSignatureBlobLen) self.SignatureBlob = String(readLen = UInt16Le(lambda:(self.wSignatureBlobLen.value - sizeof(self.padding))))
self.padding = String(b"\x00" * 8, readLen = UInt8(8)) self.padding = String(b"\x00" * 8, readLen = UInt8(8))
def getPublicKey(self): def getPublicKey(self):
@@ -380,7 +381,7 @@ class ProprietaryServerCertificate(CompositeType):
md5Digest = md5.new() md5Digest = md5.new()
md5Digest.update(s.getvalue()) md5Digest.update(s.getvalue())
return md5Digest.digest() + "\x00" + "\xff" * 46 + "\x01" return md5Digest.digest() + "\x00" + "\xff" * 45 + "\x01"
def sign(self): def sign(self):
""" """
@@ -607,6 +608,6 @@ def writeConferenceCreateResponse(serverData):
return (per.writeChoice(0), per.writeObjectIdentifier(t124_02_98_oid), return (per.writeChoice(0), per.writeObjectIdentifier(t124_02_98_oid),
per.writeLength(len(serverDataStream.getvalue()) + 14), per.writeChoice(0x14), per.writeLength(len(serverDataStream.getvalue()) + 14), per.writeChoice(0x14),
per.writeInteger16(0x79F3, 1001), per.writeInteger(1), per.writeEnumerates(16), per.writeInteger16(0x79F3, 1001), per.writeInteger(1), per.writeEnumerates(0),
per.writeNumberOfSet(1), per.writeChoice(0xc0), per.writeNumberOfSet(1), per.writeChoice(0xc0),
per.writeOctetStream(h221_sc_key, 4), per.writeOctetStream(serverDataStream.getvalue())) per.writeOctetStream(h221_sc_key, 4), per.writeOctetStream(serverDataStream.getvalue()))

View File

@@ -97,8 +97,8 @@ class LicenseBinaryBlob(CompositeType):
@summary: Blob use by license manager to exchange security data @summary: Blob use by license manager to exchange security data
@see: http://msdn.microsoft.com/en-us/library/cc240481.aspx @see: http://msdn.microsoft.com/en-us/library/cc240481.aspx
""" """
def __init__(self, blobType = BinaryBlobType.BB_ANY_BLOB): def __init__(self, blobType = BinaryBlobType.BB_ANY_BLOB, optional = False):
CompositeType.__init__(self) CompositeType.__init__(self, optional = optional)
self.wBlobType = UInt16Le(blobType, constant = True if blobType != BinaryBlobType.BB_ANY_BLOB else False) self.wBlobType = UInt16Le(blobType, constant = True if blobType != BinaryBlobType.BB_ANY_BLOB else False)
self.wBlobLen = UInt16Le(lambda:sizeof(self.blobData)) self.wBlobLen = UInt16Le(lambda:sizeof(self.blobData))
self.blobData = String(readLen = self.wBlobLen) self.blobData = String(readLen = self.wBlobLen)
@@ -110,11 +110,11 @@ class LicensingErrorMessage(CompositeType):
""" """
_MESSAGE_TYPE_ = MessageType.ERROR_ALERT _MESSAGE_TYPE_ = MessageType.ERROR_ALERT
def __init__(self): def __init__(self, readLen = None):
CompositeType.__init__(self) CompositeType.__init__(self, readLen = readLen)
self.dwErrorCode = UInt32Le() self.dwErrorCode = UInt32Le()
self.dwStateTransition = UInt32Le() self.dwStateTransition = UInt32Le()
self.blob = LicenseBinaryBlob(BinaryBlobType.BB_ERROR_BLOB) self.blob = LicenseBinaryBlob(BinaryBlobType.BB_ANY_BLOB)
class ProductInformation(CompositeType): class ProductInformation(CompositeType):
""" """
@@ -159,8 +159,8 @@ class ServerLicenseRequest(CompositeType):
""" """
_MESSAGE_TYPE_ = MessageType.LICENSE_REQUEST _MESSAGE_TYPE_ = MessageType.LICENSE_REQUEST
def __init__(self): def __init__(self, readLen = None):
CompositeType.__init__(self) CompositeType.__init__(self, readLen = readLen)
self.serverRandom = String("\x00" * 32, readLen = UInt8(32)) self.serverRandom = String("\x00" * 32, readLen = UInt8(32))
self.productInfo = ProductInformation() self.productInfo = ProductInformation()
self.keyExchangeList = LicenseBinaryBlob(BinaryBlobType.BB_KEY_EXCHG_ALG_BLOB) self.keyExchangeList = LicenseBinaryBlob(BinaryBlobType.BB_KEY_EXCHG_ALG_BLOB)
@@ -175,8 +175,8 @@ class ClientNewLicenseRequest(CompositeType):
""" """
_MESSAGE_TYPE_ = MessageType.NEW_LICENSE_REQUEST _MESSAGE_TYPE_ = MessageType.NEW_LICENSE_REQUEST
def __init__(self): def __init__(self, readLen = None):
CompositeType.__init__(self) CompositeType.__init__(self, readLen = readLen)
#RSA and must be only RSA #RSA and must be only RSA
self.preferredKeyExchangeAlg = UInt32Le(0x00000001, constant = True) self.preferredKeyExchangeAlg = UInt32Le(0x00000001, constant = True)
#pure microsoft client ;-) #pure microsoft client ;-)
@@ -194,8 +194,8 @@ class ServerPlatformChallenge(CompositeType):
""" """
_MESSAGE_TYPE_ = MessageType.PLATFORM_CHALLENGE _MESSAGE_TYPE_ = MessageType.PLATFORM_CHALLENGE
def __init__(self): def __init__(self, readLen = None):
CompositeType.__init__(self) CompositeType.__init__(self, readLen = readLen)
self.connectFlags = UInt32Le() self.connectFlags = UInt32Le()
self.encryptedPlatformChallenge = LicenseBinaryBlob(BinaryBlobType.BB_ANY_BLOB) self.encryptedPlatformChallenge = LicenseBinaryBlob(BinaryBlobType.BB_ANY_BLOB)
self.MACData = String(readLen = UInt8(16)) self.MACData = String(readLen = UInt8(16))
@@ -207,8 +207,8 @@ class ClientPLatformChallengeResponse(CompositeType):
""" """
_MESSAGE_TYPE_ = MessageType.PLATFORM_CHALLENGE_RESPONSE _MESSAGE_TYPE_ = MessageType.PLATFORM_CHALLENGE_RESPONSE
def __init__(self): def __init__(self, readLen = None):
CompositeType.__init__(self) CompositeType.__init__(self, readLen = readLen)
self.encryptedPlatformChallengeResponse = LicenseBinaryBlob(BinaryBlobType.BB_DATA_BLOB) self.encryptedPlatformChallengeResponse = LicenseBinaryBlob(BinaryBlobType.BB_DATA_BLOB)
self.encryptedHWID = LicenseBinaryBlob(BinaryBlobType.BB_DATA_BLOB) self.encryptedHWID = LicenseBinaryBlob(BinaryBlobType.BB_DATA_BLOB)
self.MACData = String(readLen = UInt8(16)) self.MACData = String(readLen = UInt8(16))
@@ -231,7 +231,7 @@ class LicPacket(CompositeType):
""" """
for c in [LicensingErrorMessage, ServerLicenseRequest, ClientNewLicenseRequest, ServerPlatformChallenge, ClientPLatformChallengeResponse]: for c in [LicensingErrorMessage, ServerLicenseRequest, ClientNewLicenseRequest, ServerPlatformChallenge, ClientPLatformChallengeResponse]:
if self.bMsgtype.value == c._MESSAGE_TYPE_: if self.bMsgtype.value == c._MESSAGE_TYPE_:
return c() return c(readLen = self.wMsgSize - 4)
log.debug("unknown license message : %s"%self.bMsgtype.value) log.debug("unknown license message : %s"%self.bMsgtype.value)
return String() return String()

View File

@@ -515,15 +515,16 @@ class Server(MCSLayer):
self.readDomainParams(data) self.readDomainParams(data)
self.readDomainParams(data) self.readDomainParams(data)
self._clientSettings = gcc.readConferenceCreateRequest(Stream(ber.readOctetString(data))) self._clientSettings = gcc.readConferenceCreateRequest(Stream(ber.readOctetString(data)))
i = 1 if not self._clientSettings.CS_NET is None:
for channelDef in self._clientSettings.getBlock(gcc.MessageType.CS_NET).channelDefArray._array: i = 1
self._serverSettings.getBlock(gcc.MessageType.SC_NET).channelIdArray._array.append(UInt16Le(i + Channel.MCS_GLOBAL_CHANNEL)) for channelDef in self._clientSettings.CS_NET.channelDefArray._array:
#if channel can be handle by serve add it self._serverSettings.SC_NET.channelIdArray._array.append(UInt16Le(i + Channel.MCS_GLOBAL_CHANNEL))
for serverChannelDef, layer in self._virtualChannels: #if channel can be handle by serve add it
if channelDef.name == serverChannelDef.name: for serverChannelDef, layer in self._virtualChannels:
self._channels[i + Channel.MCS_GLOBAL_CHANNEL] = layer if channelDef.name == serverChannelDef.name:
i += 1 self._channels[i + Channel.MCS_GLOBAL_CHANNEL] = layer
i += 1
self.sendConnectResponse() self.sendConnectResponse()
self.setNextState(self.recvErectDomainRequest) self.setNextState(self.recvErectDomainRequest)

View File

@@ -429,7 +429,8 @@ class ShareControlHeader(CompositeType):
#share control header #share control header
self.totalLength = UInt16Le(totalLength) self.totalLength = UInt16Le(totalLength)
self.pduType = UInt16Le(pduType) self.pduType = UInt16Le(pduType)
self.PDUSource = UInt16Le(userId) #for xp sp3 and deactiveallpdu PDUSource may not be present
self.PDUSource = UInt16Le(userId, optional = True)
class ShareDataHeader(CompositeType): class ShareDataHeader(CompositeType):
""" """
@@ -519,7 +520,9 @@ class DeactiveAllPDU(CompositeType):
_PDUTYPE_ = PDUType.PDUTYPE_DEACTIVATEALLPDU _PDUTYPE_ = PDUType.PDUTYPE_DEACTIVATEALLPDU
def __init__(self): def __init__(self):
CompositeType.__init__(self) #in old version this packet is empty i don't know
#and not specified
CompositeType.__init__(self, optional = True)
self.shareId = UInt32Le() self.shareId = UInt32Le()
self.lengthSourceDescriptor = UInt16Le(lambda:sizeof(self.sourceDescriptor)) self.lengthSourceDescriptor = UInt16Le(lambda:sizeof(self.sourceDescriptor))
self.sourceDescriptor = String("rdpy", readLen = self.lengthSourceDescriptor) self.sourceDescriptor = String("rdpy", readLen = self.lengthSourceDescriptor)

View File

@@ -179,6 +179,9 @@ class Client(PDULayer):
for cap in pdu.pduMessage.capabilitySets._array: for cap in pdu.pduMessage.capabilitySets._array:
self._serverCapabilities[cap.capabilitySetType] = cap 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() self.sendConfirmActivePDU()
#send synchronize #send synchronize
@@ -312,7 +315,7 @@ class Client(PDULayer):
generalCapability = self._clientCapabilities[caps.CapsType.CAPSTYPE_GENERAL].capability generalCapability = self._clientCapabilities[caps.CapsType.CAPSTYPE_GENERAL].capability
generalCapability.osMajorType.value = caps.MajorType.OSMAJORTYPE_WINDOWS generalCapability.osMajorType.value = caps.MajorType.OSMAJORTYPE_WINDOWS
generalCapability.osMinorType.value = caps.MinorType.OSMINORTYPE_WINDOWS_NT generalCapability.osMinorType.value = caps.MinorType.OSMINORTYPE_WINDOWS_NT
generalCapability.extraFlags.value = caps.GeneralExtraFlag.LONG_CREDENTIALS_SUPPORTED | caps.GeneralExtraFlag.NO_BITMAP_COMPRESSION_HDR generalCapability.extraFlags.value = caps.GeneralExtraFlag.LONG_CREDENTIALS_SUPPORTED | caps.GeneralExtraFlag.NO_BITMAP_COMPRESSION_HDR | caps.GeneralExtraFlag.ENC_SALTED_CHECKSUM
if not self._fastPathSender is None: if not self._fastPathSender is None:
generalCapability.extraFlags.value |= caps.GeneralExtraFlag.FASTPATH_OUTPUT_SUPPORTED generalCapability.extraFlags.value |= caps.GeneralExtraFlag.FASTPATH_OUTPUT_SUPPORTED
@@ -413,6 +416,9 @@ class Server(PDULayer):
#find use full flag #find use full flag
self._clientFastPathSupported = bool(self._clientCapabilities[caps.CapsType.CAPSTYPE_GENERAL].capability.extraFlags.value & caps.GeneralExtraFlag.FASTPATH_OUTPUT_SUPPORTED) 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) self.setNextState(self.recvClientSynchronizePDU)
def recvClientSynchronizePDU(self, s): def recvClientSynchronizePDU(self, s):
@@ -525,7 +531,7 @@ class Server(PDULayer):
generalCapability = self._serverCapabilities[caps.CapsType.CAPSTYPE_GENERAL].capability generalCapability = self._serverCapabilities[caps.CapsType.CAPSTYPE_GENERAL].capability
generalCapability.osMajorType.value = caps.MajorType.OSMAJORTYPE_WINDOWS generalCapability.osMajorType.value = caps.MajorType.OSMAJORTYPE_WINDOWS
generalCapability.osMinorType.value = caps.MinorType.OSMINORTYPE_WINDOWS_NT generalCapability.osMinorType.value = caps.MinorType.OSMINORTYPE_WINDOWS_NT
generalCapability.extraFlags.value = caps.GeneralExtraFlag.LONG_CREDENTIALS_SUPPORTED | caps.GeneralExtraFlag.NO_BITMAP_COMPRESSION_HDR | caps.GeneralExtraFlag.FASTPATH_OUTPUT_SUPPORTED generalCapability.extraFlags.value = caps.GeneralExtraFlag.LONG_CREDENTIALS_SUPPORTED | caps.GeneralExtraFlag.NO_BITMAP_COMPRESSION_HDR | caps.GeneralExtraFlag.FASTPATH_OUTPUT_SUPPORTED | caps.GeneralExtraFlag.ENC_SALTED_CHECKSUM
inputCapability = self._serverCapabilities[caps.CapsType.CAPSTYPE_INPUT].capability inputCapability = self._serverCapabilities[caps.CapsType.CAPSTYPE_INPUT].capability
inputCapability.inputFlags.value = caps.InputFlags.INPUT_FLAG_SCANCODES | caps.InputFlags.INPUT_FLAG_MOUSEX inputCapability.inputFlags.value = caps.InputFlags.INPUT_FLAG_SCANCODES | caps.InputFlags.INPUT_FLAG_MOUSEX

View File

@@ -164,12 +164,12 @@ def macData(macSaltKey, data):
md5Digest = md5.new() md5Digest = md5.new()
#encode length #encode length
s = Stream() dataLength = Stream()
s.writeType(UInt32Le(len(data))) dataLength.writeType(UInt32Le(len(data)))
sha1Digest.update(macSaltKey) sha1Digest.update(macSaltKey)
sha1Digest.update("\x36" * 40) sha1Digest.update("\x36" * 40)
sha1Digest.update(s.getvalue()) sha1Digest.update(dataLength.getvalue())
sha1Digest.update(data) sha1Digest.update(data)
sha1Sig = sha1Digest.digest() sha1Sig = sha1Digest.digest()
@@ -180,6 +180,38 @@ def macData(macSaltKey, data):
return md5Digest.digest() return md5Digest.digest()
def macSaltedData(macSaltKey, data, encryptionCount):
"""
@see: https://msdn.microsoft.com/en-us/library/cc240789.aspx
@param macSaltKey: {str} mac key
@param data: {str} data to sign
@param encryptionCount: nb encrypted packet
@return: {str} signature
"""
sha1Digest = sha.new()
md5Digest = md5.new()
#encode length
dataLengthS = Stream()
dataLengthS.writeType(UInt32Le(len(data)))
encryptionCountS = Stream()
encryptionCountS.writeType(UInt32Le(encryptionCount))
sha1Digest.update(macSaltKey)
sha1Digest.update("\x36" * 40)
sha1Digest.update(dataLengthS.getvalue())
sha1Digest.update(data)
sha1Digest.update(encryptionCountS.getvalue())
sha1Sig = sha1Digest.digest()
md5Digest.update(macSaltKey)
md5Digest.update("\x5c" * 48)
md5Digest.update(sha1Sig)
return md5Digest.digest()
def tempKey(initialKey, currentKey): def tempKey(initialKey, currentKey):
""" """
@see: http://msdn.microsoft.com/en-us/library/cc240792.aspx @see: http://msdn.microsoft.com/en-us/library/cc240792.aspx
@@ -342,6 +374,9 @@ class SecLayer(LayerAutomata, IStreamSender, tpkt.IFastPathListener, tpkt.IFastP
#True if classic encryption is enable #True if classic encryption is enable
self._enableEncryption = False self._enableEncryption = False
#Enable Secure Mac generation
self._enableSecureCheckSum = False
#initialise decrypt and encrypt keys #initialise decrypt and encrypt keys
self._macKey = None self._macKey = None
self._initialDecrytKey = None self._initialDecrytKey = None
@@ -358,10 +393,11 @@ class SecLayer(LayerAutomata, IStreamSender, tpkt.IFastPathListener, tpkt.IFastP
self._encryptRc4 = None self._encryptRc4 = None
def readEncryptedPayload(self, s): def readEncryptedPayload(self, s, saltedMacGeneration):
""" """
@summary: decrypt basic RDP security payload @summary: decrypt basic RDP security payload
@param s: {Stream} encrypted stream @param s: {Stream} encrypted stream
@param saltedMacGeneration: {bool} use salted mac generation
@return: {Stream} decrypted @return: {Stream} decrypted
""" """
#if update is needed #if update is needed
@@ -378,18 +414,22 @@ class SecLayer(LayerAutomata, IStreamSender, tpkt.IFastPathListener, tpkt.IFastP
decrypted = rc4.crypt(self._decryptRc4, encryptedPayload.value) decrypted = rc4.crypt(self._decryptRc4, encryptedPayload.value)
#ckeck signature #ckeck signature
if macData(self._macKey, decrypted)[:8] != signature.value: if not saltedMacGeneration and macData(self._macKey, decrypted)[:8] != signature.value:
raise InvalidExpectedDataException("Bad packet signature") raise InvalidExpectedDataException("bad signature")
if saltedMacGeneration and macSaltedData(self._macKey, decrypted, self._nbDecryptedPacket)[:8] != signature.value:
raise InvalidExpectedDataException("bad signature")
#count #count
self._nbDecryptedPacket += 1 self._nbDecryptedPacket += 1
return Stream(decrypted) return Stream(decrypted)
def writeEncryptedPayload(self, data): def writeEncryptedPayload(self, data, saltedMacGeneration):
""" """
@summary: sign and crypt data @summary: sign and crypt data
@param s: {Stream} raw stream @param data: {Type} raw stream
@param saltedMacGeneration: {bool} use salted mac generation
@return: {Tuple} (signature, encryptedData) @return: {Tuple} (signature, encryptedData)
""" """
if self._nbEncryptedPacket == 4096: if self._nbEncryptedPacket == 4096:
@@ -400,9 +440,14 @@ class SecLayer(LayerAutomata, IStreamSender, tpkt.IFastPathListener, tpkt.IFastP
self._nbEncryptedPacket = 0 self._nbEncryptedPacket = 0
self._nbEncryptedPacket += 1 self._nbEncryptedPacket += 1
s = Stream() s = Stream()
s.writeType(data) s.writeType(data)
return (String(macData(self._macKey, s.getvalue())[:8]), String(rc4.crypt(self._encryptRc4, s.getvalue())))
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 recv(self, data): def recv(self, data):
""" """
@@ -419,7 +464,7 @@ class SecLayer(LayerAutomata, IStreamSender, tpkt.IFastPathListener, tpkt.IFastP
data.readType((securityFlag, securityFlagHi)) data.readType((securityFlag, securityFlagHi))
if securityFlag.value & SecurityFlag.SEC_ENCRYPT: if securityFlag.value & SecurityFlag.SEC_ENCRYPT:
data = self.readEncryptedPayload(data) data = self.readEncryptedPayload(data, securityFlag.value & SecurityFlag.SEC_SECURE_CHECKSUM)
self._presentation.recv(data) self._presentation.recv(data)
@@ -433,7 +478,12 @@ class SecLayer(LayerAutomata, IStreamSender, tpkt.IFastPathListener, tpkt.IFastP
self._transport.send(data) self._transport.send(data)
return return
self.sendFlagged(SecurityFlag.SEC_ENCRYPT, data) flag = SecurityFlag.SEC_ENCRYPT
if self._enableSecureCheckSum:
flag |= SecurityFlag.SEC_SECURE_CHECKSUM
self.sendFlagged(flag, data)
def sendFlagged(self, flag, data): def sendFlagged(self, flag, data):
""" """
@@ -444,7 +494,7 @@ class SecLayer(LayerAutomata, IStreamSender, tpkt.IFastPathListener, tpkt.IFastP
@param data: {Type | Tuple} @param data: {Type | Tuple}
""" """
if flag & SecurityFlag.SEC_ENCRYPT: if flag & SecurityFlag.SEC_ENCRYPT:
data = self.writeEncryptedPayload(data) data = self.writeEncryptedPayload(data, flag & SecurityFlag.SEC_SECURE_CHECKSUM)
self._transport.send((UInt16Le(flag), UInt16Le(), data)) self._transport.send((UInt16Le(flag), UInt16Le(), data))
def recvFastPath(self, secFlag, fastPathS): def recvFastPath(self, secFlag, fastPathS):
@@ -454,7 +504,7 @@ class SecLayer(LayerAutomata, IStreamSender, tpkt.IFastPathListener, tpkt.IFastP
@param fastPathS: {Stream} @param fastPathS: {Stream}
""" """
if self._enableEncryption and secFlag & tpkt.SecFlags.FASTPATH_OUTPUT_ENCRYPTED: if self._enableEncryption and secFlag & tpkt.SecFlags.FASTPATH_OUTPUT_ENCRYPTED:
fastPathS = self.readEncryptedPayload(fastPathS) fastPathS = self.readEncryptedPayload(fastPathS, secFlag & tpkt.SecFlags.FASTPATH_OUTPUT_SECURE_CHECKSUM)
self._fastPathPresentation.recvFastPath(secFlag, fastPathS) self._fastPathPresentation.recvFastPath(secFlag, fastPathS)
@@ -472,7 +522,11 @@ class SecLayer(LayerAutomata, IStreamSender, tpkt.IFastPathListener, tpkt.IFastP
""" """
if self._enableEncryption: if self._enableEncryption:
secFlag |= tpkt.SecFlags.FASTPATH_OUTPUT_ENCRYPTED secFlag |= tpkt.SecFlags.FASTPATH_OUTPUT_ENCRYPTED
fastPathS = self.writeEncryptedPayload(fastPathS)
if self._enableSecureCheckSum:
secFlag |= tpkt.SecFlags.FASTPATH_OUTPUT_SECURE_CHECKSUM
fastPathS = self.writeEncryptedPayload(fastPathS, self._enableSecureCheckSum)
self._fastPathTransport.sendFastPath(secFlag, fastPathS) self._fastPathTransport.sendFastPath(secFlag, fastPathS)
@@ -661,7 +715,7 @@ class Server(SecLayer):
raise InvalidExpectedDataException("Waiting info packet") raise InvalidExpectedDataException("Waiting info packet")
if securityFlag.value & SecurityFlag.SEC_ENCRYPT: if securityFlag.value & SecurityFlag.SEC_ENCRYPT:
s = self.readEncryptedPayload(s) s = self.readEncryptedPayload(s, securityFlag.value & SecurityFlag.SEC_SECURE_CHECKSUM)
s.readType(self._info) s.readType(self._info)
#next state send error license #next state send error license

View File

@@ -4,20 +4,20 @@ import setuptools
from distutils.core import setup, Extension from distutils.core import setup, Extension
setup(name='rdpy', setup(name='rdpy',
version='1.2.1', version='1.2.2',
description='Remote Desktop Protocol in Python', description='Remote Desktop Protocol in Python',
long_description=""" long_description="""
RDPY is a pure Python implementation of the Microsoft RDP (Remote Desktop Protocol) protocol (Client and Server side). RDPY is a pure Python implementation of the Microsoft RDP (Remote Desktop Protocol) protocol (Client and Server side).
RDPY is built over the event driven network engine Twisted. RDPY is built over the event driven network engine Twisted.
RDPY provide RDP and VNC binaries : RDPY provide RDP and VNC binaries :
\t-RDP Man In The Middle proxy which record session - RDP Man In The Middle proxy which record session
\t-RDP Honeypot - RDP Honeypot
\t-RDP screenshoter - RDP screenshoter
\t-RDP client - RDP client
\t-VNC client - VNC client
\t-VNC screenshoter - VNC screenshoter
\t-RSS Player - RSS Player
""", """,
author='Sylvain Peyrefitte', author='Sylvain Peyrefitte',
author_email='citronneur@gmail.com', author_email='citronneur@gmail.com',