Example #1
0
    def parseBitmapCapability(self, data: bytes) -> BitmapCapability:
        """
        https://msdn.microsoft.com/en-us/library/cc240554.aspx
        :param data: Raw data starting after lengthCapability
        """
        stream = BytesIO(data)
        preferredBitsPerPixel = Uint16LE.unpack(stream.read(2))
        receive1bitPerPixel = Uint16LE.unpack(stream.read(2))
        receive4bitPerPixel = Uint16LE.unpack(stream.read(2))
        receive8bitPerPixel = Uint16LE.unpack(stream.read(2))
        desktopWidth = Uint16LE.unpack(stream.read(2))
        desktopHeight = Uint16LE.unpack(stream.read(2))
        stream.read(2)  # pad2octets
        desktopResizeFlag = Uint16LE.unpack(stream.read(2))
        bitmapCompressionFlag = Uint16LE.unpack(stream.read(2))
        highColorFlags = Uint8.unpack(stream.read(1))
        drawingFlags = Uint8.unpack(stream.read(1))
        multipleRectangleSupport = Uint16LE.unpack(stream.read(2))
        # ignoring pad2octetsB

        capability = BitmapCapability(preferredBitsPerPixel,
                                      receive1bitPerPixel, receive4bitPerPixel,
                                      receive8bitPerPixel, desktopWidth,
                                      desktopHeight, desktopResizeFlag,
                                      bitmapCompressionFlag, highColorFlags,
                                      drawingFlags, multipleRectangleSupport)
        capability.rawData = data
        return capability
Example #2
0
 def sendMessage(self, data: bytes, messageType: PlayerMessageType,
                 timeStamp: int):
     stream = BytesIO()
     Uint8.pack(messageType, stream)
     Uint64LE.pack(timeStamp, stream)
     stream.write(data)
     self.previous.send(stream.getvalue())
Example #3
0
 def writeMouseEvent(self, event):
     rawData = BytesIO()
     Uint8.pack(event.rawHeaderByte, rawData)
     Uint16LE.pack(event.pointerFlags, rawData)
     Uint16LE.pack(event.mouseX, rawData)
     Uint16LE.pack(event.mouseY, rawData)
     return rawData.getvalue()
Example #4
0
    def parse(self, data: bytes) -> FastPathOutputEvent:
        """
        Parse TS_FP_UPDATE.

        https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/a1c4caa8-00ed-45bb-a06e-5177473766d3
        """
        stream = BytesIO(data)
        header = Uint8.unpack(stream)

        # https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/a1c4caa8-00ed-45bb-a06e-5177473766d3
        updateCode = header & 0xf
        # fragmentation = (header & 0b00110000) >> 4
        compressionFlags = Uint8.unpack(stream) if self.isCompressed(
            header) else None
        size = Uint16LE.unpack(stream)

        # Dispatch to the appropriate sub-parser.
        if updateCode == FastPathOutputType.FASTPATH_UPDATETYPE_BITMAP:
            return self.parseBitmapEventRaw(stream, header, compressionFlags,
                                            size)
        elif updateCode == FastPathOutputType.FASTPATH_UPDATETYPE_ORDERS:
            return self.parseOrdersEvent(stream, header, compressionFlags,
                                         size)

        read = stream.read(size)
        return FastPathOutputEvent(header, compressionFlags, read)
Example #5
0
 def parseSecondaryDrawingOrder(self, orderData):
     stream = BytesIO(orderData)
     controlFlags = Uint8.unpack(stream.read(1))
     orderLength = Uint16LE.unpack(stream.read(2))
     extraFlags = Uint16LE.unpack(stream.read(2))
     orderType = Uint8.unpack(stream.read(1))
     return SecondaryDrawingOrder(controlFlags, orderLength, extraFlags, orderType)
Example #6
0
    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)
Example #7
0
    def parseLength(self, stream: BytesIO) -> int:
        length = Uint8.unpack(stream)

        if length & 0x80 != 0:
            length = ((length & 0x7f) << 8) | Uint8.unpack(stream)

        return length
Example #8
0
    def parse(self, data: bytes) -> X224PDU:
        """
        Read the byte stream and return a corresponding X224PDU
        """
        length = Uint8.unpack(data[0])
        header = Uint8.unpack(data[1]) >> 4

        if header in list(X224PDUType):
            header = X224PDUType(header)

        if length < 2:
            raise ParsingError(
                "Invalid X224 length indicator: indicator = %d, expected at least 2 bytes"
                % length)
        if len(data) < length:
            raise ParsingError(
                "Invalid X224 length indicator: indicator = %d, length = %d" %
                (length, len(data)))

        if header not in self.parsers:
            raise UnknownPDUTypeError(
                "Trying to parse unknown X224 PDU type: %s" %
                (header if header in X224PDUType else hex(header)), header)

        return self.parsers[header](data, length)
Example #9
0
 def writeData(self, stream: BytesIO, pdu: X224DataPDU):
     """
     Write a Data PDU onto the provided stream
     """
     header = (pdu.header << 4) | int(pdu.roa)
     stream.write(Uint8.pack(header))
     stream.write(Uint8.pack(int(pdu.eot) << 7))
Example #10
0
 def writeError(self, stream: BytesIO, pdu: X224ErrorPDU):
     """
     Write an error PDU onto the provided stream
     """
     stream.write(Uint8.pack(pdu.header))
     stream.write(Uint16LE.pack(pdu.destination))
     stream.write(Uint8.pack(pdu.cause))
Example #11
0
    def writeFileBothDirectoryInformation(self, information: List[FileBothDirectoryInformation], stream: BytesIO):
        dataList: [bytes] = []

        for info in information:
            substream = BytesIO()
            fileName = info.fileName.encode("utf-16le")
            shortName = info.shortName.encode("utf-16le")

            Uint32LE.pack(info.fileIndex, substream)
            Uint64LE.pack(info.creationTime, substream)
            Uint64LE.pack(info.lastAccessTime, substream)
            Uint64LE.pack(info.lastWriteTime, substream)
            Uint64LE.pack(info.lastChangeTime, substream)
            Uint64LE.pack(info.endOfFilePosition, substream)
            Uint64LE.pack(info.allocationSize, substream)
            Uint32LE.pack(info.fileAttributes, substream)
            Uint32LE.pack(len(fileName), substream)
            Uint32LE.pack(info.eaSize, substream)
            Uint8.pack(len(shortName), substream)
            # stream.write(b"\x00") # reserved
            substream.write(shortName.ljust(24, b"\x00")[: 24])
            substream.write(fileName)

            dataList.append(substream.getvalue())

        self.writeFileInformationList(dataList, stream)
Example #12
0
    def parse(self, data: bytes) -> NegotiationRequestPDU:
        """
        Parse a negotiation request.
        :param data: the request data.
        """

        cookie = None

        if b"\r\n" in data:
            cookie = data[: data.index(b"\r\n")]
            data = data[data.index(b"\r\n") + 2 :]

        stream = BytesIO(data)

        if len(data) >= 8:
            type = Uint8.unpack(stream)
            requestFlags = Uint8.unpack(stream)
            requestLength = Uint16LE.unpack(stream)
            requestedProtocols = Uint32LE.unpack(stream)

            correlationFlags = None
            correlationID = None

            if requestFlags & NegotiationRequestFlags.CORRELATION_INFO_PRESENT != 0 and len(data) >= 36:
                type = Uint8.unpack(stream)
                correlationFlags = Uint8.unpack(stream)
                correlationLength = Uint16LE.unpack(stream)
                correlationID = stream.read(16)
                stream.read(16)

            return NegotiationRequestPDU(cookie, requestFlags, requestedProtocols, correlationFlags, correlationID)
        else:
            return NegotiationRequestPDU(cookie, None, None, None, None)
Example #13
0
 def writeMouseEvent(self, event: FastPathMouseEvent) -> bytes:
     stream = BytesIO()
     Uint8.pack(event.rawHeaderByte, stream)
     Uint16LE.pack(event.pointerFlags, stream)
     Uint16LE.pack(event.mouseX, stream)
     Uint16LE.pack(event.mouseY, stream)
     return stream.getvalue()
Example #14
0
    def parse(self, data: bytes) -> FastPathOutputEvent:
        stream = BytesIO(data)
        header = Uint8.unpack(stream)

        compressionFlags = None

        if self.isCompressed(header):
            compressionFlags = Uint8.unpack(stream)

        size = Uint16LE.unpack(stream)

        eventType = header & 0xf
        fragmentation = header & 0b00110000 != 0

        if fragmentation:
            log.debug(
                "Fragmentation is present in output fastpath event packets."
                " Not parsing it and saving to FastPathOutputUpdateEvent.")
            return FastPathOutputEvent(header,
                                       compressionFlags,
                                       payload=stream.read(size))

        if eventType == FastPathOutputType.FASTPATH_UPDATETYPE_BITMAP:
            return self.parseBitmapEventRaw(stream, header, compressionFlags,
                                            size)
        elif eventType == FastPathOutputType.FASTPATH_UPDATETYPE_ORDERS:
            return self.parseOrdersEvent(stream, header, compressionFlags,
                                         size)

        read = stream.read(size)
        return FastPathOutputEvent(header, compressionFlags, read)
Example #15
0
    def write(self, pdu: MCSPDU) -> bytes:
        """
        Encode an MCS PDU into raw bytes
        :param pdu: the MCSPDU to encode
        :return: The raw bytes to send
        """
        if pdu.header not in self.writers:
            raise UnknownPDUTypeError(
                "Trying to write unknown MCS PDU type %s" % pdu.header,
                pdu.header)

        stream = BytesIO()

        if pdu.header in [
                MCSPDUType.CONNECT_INITIAL, MCSPDUType.CONNECT_RESPONSE
        ]:
            stream.write(
                Uint8.pack(ber.Class.BER_CLASS_APPL | ber.PC.BER_CONSTRUCT
                           | ber.Tag.BER_TAG_MASK))
            stream.write(Uint8.pack(pdu.header))
        else:
            stream.write(
                Uint8.pack((pdu.header << 2) | self.headerOptions[pdu.header]))

        self.writers[pdu.header](stream, pdu)
        return stream.getvalue()
Example #16
0
 def writeSuppressOutput(self, stream: BytesIO, pdu):
     Uint8.pack(int(pdu.allowDisplayUpdates), stream)
     stream.write(b"\x00" * 3)
     Uint16LE.pack(pdu.left, stream)
     Uint16LE.pack(pdu.top, stream)
     Uint16LE.pack(pdu.right, stream)
     Uint16LE.pack(pdu.bottom, stream)
Example #17
0
 def writeConnectionPDU(self, stream: BytesIO, header: X224PDUType,
                        destination: int, source: int, options: int):
     """
     Write a connection PDU (connectionRequest/connectionConfirm/disconnectRequest) in the provided byte stream.
     """
     stream.write(Uint8.pack(header))
     stream.write(Uint16BE.pack(destination))
     stream.write(Uint16BE.pack(source))
     stream.write(Uint8.pack(options))
Example #18
0
    def writeBody(self, stream: BytesIO, pdu: FastPathPDU):
        bodyStream = BytesIO()
        SignedFastPathParser.writeBody(self, bodyStream, pdu)
        body = bodyStream.getvalue()

        Uint16LE.pack(0x10, stream)
        Uint8.pack(FIPSVersion.TSFIPS_VERSION1, stream)
        Uint8.pack(self.crypter.getPadLength(self.eventData), stream)
        stream.write(body)
Example #19
0
 def parseShareDataHeader(self, stream: BytesIO, controlHeader: ShareControlHeader):
     shareID = Uint32LE.unpack(stream)
     stream.read(1)
     streamID = Uint8.unpack(stream)
     uncompressedLength = Uint16LE.unpack(stream)
     pduSubtype = Uint8.unpack(stream)
     compressedType = Uint8.unpack(stream)
     compressedLength = Uint16LE.unpack(stream)
     return ShareDataHeader(controlHeader.pduType, controlHeader.version, controlHeader.source, shareID, streamID, uncompressedLength, SlowPathDataType(pduSubtype), compressedType, compressedLength)
Example #20
0
    def writeHeader(self, stream: BytesIO, pdu: FastPathPDU):
        header = (pdu.header & 0xc0) | self.getHeaderFlags()
        eventCount = len(pdu.events)

        if eventCount <= 15 and self.mode == ParserMode.CLIENT:
            header |= eventCount << 2

        Uint8.pack(header, stream)
        self.writeLength(stream, pdu)
Example #21
0
 def write(self, pdu: DynamicChannelPDU) -> bytes:
     stream = BytesIO()
     header = pdu.cbid
     header |= pdu.sp << 2
     header |= pdu.cmd << 4
     Uint8.pack(header, stream)
     if isinstance(pdu, CreateResponsePDU):
         self.writeChannelId(stream, pdu.cbid, pdu.channelId)
         Uint32LE.pack(pdu.creationStatus, stream)
     else:
         raise NotImplementedError()
     return stream.getvalue()
Example #22
0
    def parse(self, data: bytes) -> FastPathPDU:
        stream = BytesIO(data)
        header = Uint8.unpack(stream)
        eventCount = self.parseEventCount(header)
        pduLength = self.parseLength(stream)

        if eventCount == 0:
            eventCount = Uint8.unpack(stream)

        data = stream.read(pduLength - stream.tell())
        events = self.parseEvents(data)
        return FastPathPDU(header, events)
Example #23
0
    def writeUnicodeEvent(self, event: FastPathUnicodeEvent):
        stream = BytesIO()
        Uint8.pack(
            int(event.released) |
            (FastPathInputType.FASTPATH_INPUT_EVENT_UNICODE << 5), stream)

        if isinstance(event.text, bytes):
            stream.write(event.text[:2].ljust(2, b"\x00"))
        elif isinstance(event.text, str):
            stream.write(event.text[:1].ljust(1, "\x00").encode("utf-16le"))

        return stream.getvalue()
Example #24
0
    def writeShareDataHeader(self, stream: BytesIO, header, dataLength):
        substream = BytesIO()
        substream.write(Uint32LE.pack(header.shareID))
        substream.write(b"\x00")
        substream.write(Uint8.pack(header.streamID))
        substream.write(Uint16LE.pack(header.uncompressedLength))
        substream.write(Uint8.pack(header.subtype))
        substream.write(Uint8.pack(header.compressedType))
        substream.write(Uint16LE.pack(header.compressedLength))
        substream = substream.getvalue()

        self.writeShareControlHeader(stream, header, dataLength + len(substream))
        stream.write(substream)
Example #25
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()
Example #26
0
    def parseLengthWithSocket(self, socket):
        """
        Same as parseLength, but with a network socket.
        :type socket: socket.socket
        """
        data = socket.recv(1)
        length = Uint8.unpack(data)

        if length & 0x80 != 0:
            data2 = socket.recv(1)
            data += data2
            length = ((length & 0x7f) << 8) | Uint8.unpack(data2)

        return data, length
Example #27
0
    def writeDirectoryControlRequest(self, pdu: Union[DeviceIORequestPDU, DeviceQueryDirectoryRequestPDU], stream: BytesIO):
        self.minorFunctionsForParsingResponse[pdu.completionID] = pdu.minorFunction

        if pdu.minorFunction == MinorFunction.IRP_MN_NOTIFY_CHANGE_DIRECTORY:
            stream.write(pdu.payload)
        else:
            self.informationClassForParsingResponse[pdu.completionID] = pdu.informationClass
            path = (pdu.path + "\x00").encode("utf-16le")

            Uint32LE.pack(pdu.informationClass, stream)
            Uint8.pack(pdu.initialQuery, stream)
            Uint32LE.pack(len(path), stream)
            stream.write(b"\x00" * 23)
            stream.write(path)
Example #28
0
    def parse(self, data: bytes) -> TPKTPDU:
        """
        Read the byte stream and return a TPKTPDU
        """

        _version = Uint8.unpack(data[0:1])
        _padding = Uint8.unpack(data[1:2])
        length = Uint16BE.unpack(data[2:4])
        payload = data[4:length]

        if len(payload) != length - 4:
            raise ParsingError("Payload is too short for TPKT length field")

        return TPKTPDU(payload)
Example #29
0
    def parse(self, data: bytes) -> NegotiationResponsePDU:
        """
        Parse a negotiation response.
        :param data: the response data.
        """
        stream = BytesIO(data)

        if len(data) == 8:
            type = Uint8.unpack(stream)
            flags = Uint8.unpack(stream)
            length = Uint16LE.unpack(stream)
            selectedProtocols = Uint32LE.unpack(stream)
            return NegotiationResponsePDU(type, flags, selectedProtocols)
        else:
            return NegotiationResponsePDU(None, None, None)
Example #30
0
    def write(self, pdu):
        """
        Write a negotiation response.
        :param pdu: the response PDU.
        :type pdu: NegotiationResponsePDU
        :return: str
        """
        stream = BytesIO()

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

        return stream.getvalue()