예제 #1
0
파일: player.py 프로젝트: yuraxdrumz/pyrdp
    def writeFileDescription(self, description: PlayerFileDescription,
                             stream: BytesIO):
        path = description.path.encode()

        Uint32LE.pack(len(path), stream)
        stream.write(path)
        Uint8.pack(int(description.isDirectory), stream)
예제 #2
0
    def write(self, pdu):
        """
        Write a negotiation request.
        :param pdu: the request PDU.
        :type pdu: NegotiationRequestPDU
        :return: str
        """
        stream = BytesIO()

        if pdu.cookie is not None:
            stream.write(pdu.cookie + b"\r\n")

        if pdu.flags is not None and pdu.requestedProtocols is not None:
            Uint8.pack(NegotiationType.TYPE_RDP_NEG_REQ, stream)
            Uint8.pack(pdu.flags, stream)
            Uint16LE.pack(8, stream)
            Uint32LE.pack(pdu.requestedProtocols, stream)

            if pdu.correlationFlags is not None and pdu.correlationID is not None:
                Uint8.pack(NegotiationType.TYPE_RDP_CORRELATION_INFO, stream)
                Uint8.pack(pdu.correlationFlags, stream)
                Uint16LE.pack(36, stream)
                stream.write(pdu.correlationID)
                stream.write(b"\x00" * 16)

        return stream.getvalue()
예제 #3
0
 def write(self, pdu):
     """
     :type pdu: VirtualChannelPDU
     :return: A LIST of VirtualChannelPDUs as raw bytes. The first one has the CHANNEL_FLAG_FIRST
              set and the last one has the CHANNEL_FLAG_LAST set.
     """
     rawPacketList = []
     length = pdu.length
     dataStream = BytesIO(pdu.payload)
     while length > 0:
         stream = BytesIO()
         Uint32LE.pack(pdu.length, stream)
         flags = pdu.flags & 0b11111111111111111111111111111100
         if len(rawPacketList) == 0:
             # Means it's the first packet.
             flags |= VirtualChannelPDUFlag.CHANNEL_FLAG_FIRST
         if length <= self.MAX_CHUNK_SIZE:
             # Means it's the last packet.
             flags |= VirtualChannelPDUFlag.CHANNEL_FLAG_LAST
         Uint32LE.pack(flags, stream)
         toWrite = self.MAX_CHUNK_SIZE if length >= self.MAX_CHUNK_SIZE else length
         stream.write(dataStream.read(toWrite))
         rawPacketList.append(stream.getvalue())
         length -= toWrite
     return rawPacketList
예제 #4
0
 def writeHeader(self, stream, pdu):
     """
     Write the PDU header.
     :type stream: BytesIO
     :type pdu: SecurityPDU
     """
     Uint32LE.pack(pdu.header, stream)
예제 #5
0
파일: player.py 프로젝트: yuraxdrumz/pyrdp
    def writeFileDownloadRequest(self, pdu: PlayerFileDownloadRequestPDU,
                                 stream: BytesIO):
        path = pdu.path.encode()

        Uint32LE.pack(pdu.deviceID, stream)
        Uint32LE.pack(len(path), stream)
        stream.write(path)
예제 #6
0
파일: key.py 프로젝트: macdaliot/pyrdp
def macData(macKey, data):
    """
    Generate an unsalted signature.
    See: http://msdn.microsoft.com/en-us/library/cc241995.aspx
    :param macKey: signing key.
    :type macKey: bytes
    :param data: data to sign.
    :type data: bytes
    :return: str
    """
    sha1Digest = hashlib.sha1()
    md5Digest = hashlib.md5()

    dataLength = ByteStream()
    Uint32LE.pack(len(data), dataLength)

    sha1Digest.update(macKey)
    sha1Digest.update(b"\x36" * 40)
    sha1Digest.update(dataLength.getvalue())
    sha1Digest.update(data)

    sha1Sig = sha1Digest.digest()

    md5Digest.update(macKey)
    md5Digest.update(b"\x5c" * 48)
    md5Digest.update(sha1Sig)

    return md5Digest.digest()
예제 #7
0
파일: key.py 프로젝트: macdaliot/pyrdp
def macSaltedData(macKey, data, encryptionCount):
    """
    Generate a salted signature.
    See: https://msdn.microsoft.com/en-us/library/cc240789.aspx
    :param macKey: signing key.
    :type macKey: bytes
    :param data: data to sign.
    :type data: bytes
    :param encryptionCount: the number of encrypted packets so far.
    :type encryptionCount: int
    :return: str
    """
    sha1Digest = hashlib.sha1()
    md5Digest = hashlib.md5()

    dataLengthS = ByteStream()
    Uint32LE.pack(len(data), dataLengthS)

    encryptionCountS = ByteStream()
    Uint32LE.pack(encryptionCount, encryptionCountS)

    sha1Digest.update(macKey)
    sha1Digest.update(b"\x36" * 40)
    sha1Digest.update(dataLengthS.getvalue())
    sha1Digest.update(data)
    sha1Digest.update(encryptionCountS.getvalue())

    sha1Sig = sha1Digest.digest()

    md5Digest.update(macKey)
    md5Digest.update(b"\x5c" * 48)
    md5Digest.update(sha1Sig)

    return md5Digest.digest()
예제 #8
0
    def write(self, pdu: VirtualChannelPDU) -> List[bytes]:
        rawPacketList = []
        payloadStream = BytesIO(pdu.payload)
        lengthRemaining = len(pdu.payload)

        while lengthRemaining > 0:
            chunkSize = min(lengthRemaining, self.MAX_CHUNK_SIZE)
            chunk = payloadStream.read(chunkSize)
            flags = pdu.flags & ~(VirtualChannelPDUFlag.CHANNEL_FLAG_FIRST
                                  | VirtualChannelPDUFlag.CHANNEL_FLAG_LAST)

            if len(rawPacketList) == 0:
                # Means it's the first packet.
                flags |= VirtualChannelPDUFlag.CHANNEL_FLAG_FIRST

            if lengthRemaining <= self.MAX_CHUNK_SIZE:
                # Means it's the last packet.
                flags |= VirtualChannelPDUFlag.CHANNEL_FLAG_LAST

            outputStream = BytesIO()
            Uint32LE.pack(len(pdu.payload), outputStream)
            Uint32LE.pack(flags, outputStream)
            outputStream.write(chunk)

            rawPacketList.append(outputStream.getvalue())
            lengthRemaining -= chunkSize

        return rawPacketList
예제 #9
0
파일: slowpath.py 프로젝트: wjcxk21/pyrdp
    def writeMultiFragmentUpdateCapability(self, capability: MultifragmentUpdateCapability, stream: BytesIO):
        substream = BytesIO()
        Uint16LE.pack(capability.capabilityType, stream)

        Uint32LE.pack(capability.maxRequestSize, substream)

        Uint16LE.pack(len(substream.getvalue()) + 4, stream)
        stream.write(substream.getvalue())
예제 #10
0
 def writeFormatDataRequest(self, stream, pdu):
     """
     Write the FormatDataRequestPDU starting at dataLen. Assumes LongFormatNames.
     :type stream: BytesIO
     :type pdu: FormatDataRequestPDU
     """
     Uint32LE.pack(4, stream)  # datalen
     Uint32LE.pack(pdu.requestedFormatId, stream)
예제 #11
0
 def writeFormatDataResponse(self, stream, pdu):
     """
     Write the FormatDataResponsePDU starting at dataLen.
     :type stream: BytesIO
     :type pdu: FormatDataResponsePDU
     """
     Uint32LE.pack(len(pdu.requestedFormatData), stream)
     stream.write(pdu.requestedFormatData)
예제 #12
0
파일: player.py 프로젝트: yuraxdrumz/pyrdp
    def writeDirectoryListingRequest(self,
                                     pdu: PlayerDirectoryListingRequestPDU,
                                     stream: BytesIO):
        path = pdu.path.encode()

        Uint32LE.pack(pdu.deviceID, stream)
        Uint32LE.pack(len(path), stream)
        stream.write(path)
예제 #13
0
파일: player.py 프로젝트: yuraxdrumz/pyrdp
    def writeDirectoryListingResponse(self,
                                      pdu: PlayerDirectoryListingResponsePDU,
                                      stream: BytesIO):
        Uint32LE.pack(pdu.deviceID, stream)
        Uint32LE.pack(len(pdu.fileDescriptions), stream)

        for description in pdu.fileDescriptions:
            self.writeFileDescription(description, stream)
예제 #14
0
    def write(self, pdu):
        """
        Encode a Client Info PDU to bytes.
        :param pdu: the Client Info PDU.
        :type pdu: ClientInfoPDU
        :return: str
        """
        stream = BytesIO()
        stream.write(Uint32LE.pack(pdu.codePage))
        stream.write(Uint32LE.pack(pdu.flags))

        isUnicode = pdu.flags & ClientInfoFlags.INFO_UNICODE != 0
        hasNullBytes = pdu.codePage == 1252 or isUnicode
        nullByteCount = 1 if hasNullBytes else 0
        unicodeMultiplier = 2 if isUnicode else 0

        domain = pdu.domain + "\x00" * nullByteCount
        username = pdu.username + "\x00" * nullByteCount
        password = pdu.password + "\x00" * nullByteCount
        alternateShell = pdu.alternateShell + "\x00" * nullByteCount
        workingDir = pdu.workingDir + "\x00" * nullByteCount

        if isUnicode:
            domain = encodeUTF16LE(domain)
            username = encodeUTF16LE(username)
            password = encodeUTF16LE(password)
            alternateShell = encodeUTF16LE(alternateShell)
            workingDir = encodeUTF16LE(workingDir)
        else:
            domain = domain.encode()
            username = username.encode()
            password = password.encode()
            alternateShell = alternateShell.encode()
            workingDir = workingDir.encode()

        domainLength = len(domain) - nullByteCount * unicodeMultiplier
        usernameLength = len(username) - nullByteCount * unicodeMultiplier
        passwordLength = len(password) - nullByteCount * unicodeMultiplier
        alternateShellLength = len(
            alternateShell) - nullByteCount * unicodeMultiplier
        workingDirLength = len(workingDir) - nullByteCount * unicodeMultiplier

        stream.write(Uint16LE.pack(domainLength))
        stream.write(Uint16LE.pack(usernameLength))
        stream.write(Uint16LE.pack(passwordLength))
        stream.write(Uint16LE.pack(alternateShellLength))
        stream.write(Uint16LE.pack(workingDirLength))
        stream.write(domain)
        stream.write(username)
        stream.write(password)
        stream.write(alternateShell)
        stream.write(workingDir)

        if pdu.extraInfo is not None:
            extraInfoBytes = self.writeExtraInfo(pdu.extraInfo)
            stream.write(extraInfoBytes)

        return stream.getvalue()
예제 #15
0
    def writeClientNetworkData(self, stream: BytesIO, network: ClientNetworkData):
        stream.write(Uint32LE.pack(len(network.channelDefinitions)))

        for channel in network.channelDefinitions:
            if len(channel.name) > 8:
                raise ParsingError("Channel name must have 8 characters maximum")

            stream.write(channel.name.encode().ljust(8, b"\x00")[: 8])
            stream.write(Uint32LE.pack(channel.options))
예제 #16
0
파일: slowpath.py 프로젝트: wjcxk21/pyrdp
    def writeSurfaceCommandsCapability(self, capability: SurfaceCommandsCapability, stream: BytesIO):
        substream = BytesIO()
        Uint16LE.pack(capability.capabilityType, stream)

        Uint32LE.pack(capability.cmdFlags, substream)
        Uint32LE.pack(capability.reserved, substream)

        Uint16LE.pack(len(substream.getvalue()) + 4, stream)
        stream.write(substream.getvalue())
예제 #17
0
 def writeSingleCapability(self, capability: DeviceRedirectionCapability, stream: BytesIO):
     Uint16LE.pack(capability.capabilityType, stream)
     substream = BytesIO()
     if isinstance(capability, DeviceRedirectionGeneralCapability):
         self.writeGeneralCapability(capability, substream)
     else:
         substream.write(capability.payload)
     Uint16LE.pack(len(substream.getvalue()) + 8, stream)
     Uint32LE.pack(capability.version, stream)
     stream.write(substream.getvalue())
예제 #18
0
 def writeErrorAlert(self, stream, pdu):
     """
     Writes LicenceErrorAlertPDU-specific fields to stream
     :type stream: BytesIO
     :type pdu: LicenseErrorAlertPDU
     """
     stream.write(Uint32LE.pack(pdu.errorCode))
     stream.write(Uint32LE.pack(pdu.stateTransition))
     stream.write(Uint16LE.pack(pdu.blob.type))
     stream.write(Uint16LE.pack(0))
예제 #19
0
 def writeColorEvent(self, stream, event):
     Uint16LE.pack(event.cacheIndex, stream)
     Uint32LE.pack(event.hotSpot, stream)
     Uint16LE.pack(event.width, stream)
     Uint16LE.pack(event.height, stream)
     Uint16LE.pack(len(event.andMask), stream)
     Uint16LE.pack(len(event.xorMask), stream)
     stream.write(event.xorMask)
     stream.write(event.andMask)
     stream.write(b"\x00")
예제 #20
0
    def writeServerCertificate(self, certificate: ProprietaryCertificate) -> bytes:
        stream = BytesIO()

        if certificate.type == ServerCertificateType.PROPRIETARY:
            Uint32LE.pack(ServerCertificateType.PROPRIETARY, stream)
            self.writeProprietaryCertificate(stream, certificate)
        else:
            raise NotImplementedError("Unhandled certificate type")

        return stream.getvalue()
예제 #21
0
    def writeServerSecurityData(self, stream: BytesIO, data: ServerSecurityData):
        stream.write(Uint32LE.pack(data.encryptionMethod))
        stream.write(Uint32LE.pack(data.encryptionLevel))
        if data.serverRandom is not None:
            serverCertificate = self.writeServerCertificate(data.serverCertificate)

            stream.write(Uint32LE.pack(len(data.serverRandom)))
            stream.write(Uint32LE.pack(len(serverCertificate)))
            stream.write(data.serverRandom)
            stream.write(serverCertificate)
예제 #22
0
파일: slowpath.py 프로젝트: wjcxk21/pyrdp
    def writeOffscreenCacheCapability(self, capability: OffscreenBitmapCacheCapability, stream: BytesIO):
        substream = BytesIO()
        Uint16LE.pack(capability.capabilityType, stream)

        Uint32LE.pack(capability.offscreenSupportLevel, substream)
        Uint16LE.pack(capability.offscreenCacheSize, substream)
        Uint16LE.pack(capability.offscreenCacheEntries, substream)

        Uint16LE.pack(len(substream.getvalue()) + 4, stream)
        stream.write(substream.getvalue())
예제 #23
0
 def writeDeviceIORequest(self, pdu: DeviceIORequestPDU, stream: BytesIO):
     Uint32LE.pack(pdu.deviceId, stream)
     Uint32LE.pack(pdu.fileId, stream)
     Uint32LE.pack(pdu.completionId, stream)
     Uint32LE.pack(pdu.majorFunction, stream)
     Uint32LE.pack(pdu.minorFunction, stream)
     if pdu.majorFunction in self.ioRequestWriters.keys():
         self.ioRequestWriters[pdu.majorFunction](pdu, stream)
     else:
         stream.write(pdu.payload)
예제 #24
0
파일: input.py 프로젝트: yuraxdrumz/pyrdp
    def write(self, input):
        stream = BytesIO()
        Uint32LE.pack(input.eventTime, stream)
        Uint16LE.pack(input.messageType, stream)

        if input.messageType not in self.writers:
            raise WritingError("Invalid input message type")

        self.writers[input.messageType](stream, input)
        return stream.getvalue()
예제 #25
0
    def writeDirectoryControlResponse(self, pdu: Union[DeviceDirectoryControlResponsePDU, DeviceQueryDirectoryResponsePDU], stream: BytesIO):
        if not hasattr(pdu, "minorFunction") or pdu.minorFunction == MinorFunction.IRP_MN_NOTIFY_CHANGE_DIRECTORY:
            stream.write(pdu.payload)
            return

        substream = BytesIO()
        self.fileInformationWriters[pdu.informationClass](pdu.fileInformation, substream)

        Uint32LE.pack(len(substream.getvalue()), stream)
        stream.write(substream.getvalue())
        stream.write(pdu.endByte)
예제 #26
0
 def writeSecurityExchange(self, pdu):
     """
     Encode a RDPSecurityExchangePDU to bytes.
     :type pdu: SecurityExchangePDU
     :return: str
     """
     stream = BytesIO()
     Uint32LE.pack(SecurityFlags.SEC_EXCHANGE_PKT | SecurityFlags.SEC_LICENSE_ENCRYPT_SC, stream)
     Uint32LE.pack(len(pdu.clientRandom), stream)
     stream.write(pdu.clientRandom)
     return stream.getvalue()
예제 #27
0
파일: slowpath.py 프로젝트: wjcxk21/pyrdp
    def writeVirtualChannelCapability(self, capability: VirtualChannelCapability, stream: BytesIO):
        substream = BytesIO()
        Uint16LE.pack(capability.capabilityType, stream)

        Uint32LE.pack(capability.flags, substream)

        if capability.vcChunkSize is not None:
            Uint32LE.pack(capability.vcChunkSize, substream)

        Uint16LE.pack(len(substream.getvalue()) + 4, stream)
        stream.write(substream.getvalue())
예제 #28
0
    def writeServerCoreData(self, stream, data):
        """
        :type stream: BytesIO
        :type data: ServerCoreData
        """
        stream.write(Uint32LE.pack(data.version))

        if data.clientRequestedProtocols is not None:
            stream.write(Uint32LE.pack(data.clientRequestedProtocols))

        if data.earlyCapabilityFlags is not None:
            stream.write(Uint32LE.pack(data.earlyCapabilityFlags))
예제 #29
0
    def writeServerCoreData(self, stream: BytesIO, data: ServerCoreData):
        stream.write(Uint32LE.pack(data.version))

        requestedProtocols = data.clientRequestedProtocols

        if requestedProtocols is None:
            requestedProtocols = 0

        stream.write(Uint32LE.pack(requestedProtocols))

        if data.earlyCapabilityFlags is not None:
            stream.write(Uint32LE.pack(data.earlyCapabilityFlags))
예제 #30
0
    def writeProprietaryCertificate(self, stream: BytesIO, cert: ProprietaryCertificate):
        keyBytes = self.writePublicKey(cert.publicKey)

        Uint32LE.pack(cert.signatureAlgorithmID, stream)
        Uint32LE.pack(cert.keyAlgorithmID, stream)
        Uint16LE.pack(cert.publicKeyType, stream)
        Uint16LE.pack(len(keyBytes), stream)
        stream.write(keyBytes)
        Uint16LE.pack(cert.signatureType, stream)
        Uint16LE.pack(len(cert.signature) + 8, stream)
        stream.write(cert.signature)
        stream.write(b"\x00" * 8)