예제 #1
0
    def parseDomainParams(self, stream):
        """
        Parse a MCSDomainParam from stream
        :param stream: byte stream containing the data
        :type stream: BytesIO
        :return: MCSDomainParam
        """
        if not ber.readUniversalTag(stream, ber.Tag.BER_TAG_SEQUENCE, True):
            raise ParsingError("Invalid BER tag (%d expected)" %
                               ber.Tag.BER_TAG_SEQUENCE)

        length = ber.readLength(stream)
        if length > len(stream.getvalue()):
            raise ParsingError(
                "Invalid size for DomainParameters (got %d, %d bytes left)" %
                (length, len(stream.getvalue())))

        maxChannelIDs = ber.readInteger(stream)
        maxUserIDs = ber.readInteger(stream)
        maxTokenIDs = ber.readInteger(stream)
        numPriorities = ber.readInteger(stream)
        minThroughput = ber.readInteger(stream)
        maxHeight = ber.readInteger(stream)
        maxMCSPDUSize = ber.readInteger(stream)
        protocolVersion = ber.readInteger(stream)
        return MCSDomainParams(maxChannelIDs, maxUserIDs, maxTokenIDs,
                               numPriorities, minThroughput, maxHeight,
                               maxMCSPDUSize, protocolVersion)
예제 #2
0
    def parseConnectionPDU(self, data: bytes, length: int,
                           name: str) -> Tuple[int, int, int, bytes]:
        """
        Parse the provided data to extract common information contained in Connection Request, Connection Confirm and Disconnect Request PDUs.
        :param data: bytes to parse.
        :param length: Length of the Connection PDU.
        :param name: For debugging purposes: the name of the connection PDU (like "Connection Request").
        :return: A tuple of the information we find in both connection PDUs: (source, destination, options, payload)
        """

        if length < 6:
            raise ParsingError(
                "Invalid X244 %s length indicator: indicator = %d, expected at least 6 bytes"
                % (name, 6))

        destination = Uint16BE.unpack(data[2:4])
        source = Uint16BE.unpack(data[4:6])
        options = Uint8.unpack(data[6])
        payload = data[7:]

        if len(payload) != length - 6:
            raise ParsingError(
                "Invalid X224 %s payload length: expected = %d, length = %d" %
                (name, length - 6, len(payload)))

        return source, destination, options, payload
예제 #3
0
    def doParse(self, data: bytes) -> GCCPDU:
        """
        Parses the raw data bytes into a GCCPDU
        :param data: PDU data.
        """
        stream = BytesIO(data)

        tag = per.readChoice(stream)

        if tag != 0:
            raise ParsingError("Expected object tag (0), got %d instead" % tag)

        oid = per.readObjectIdentifier(stream)

        if oid != GCCParser.T124_02_98_OID:
            raise ParsingError("Invalid object identifier: %r, expected %r" %
                               (oid, GCCParser.T124_02_98_OID))

        _length = per.readLength(stream)
        header = per.readChoice(stream)

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

        pdu = self.parsers[header](stream)

        return pdu
예제 #4
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)
예제 #5
0
    def parseConferenceCreateResponse(
            self, stream: BytesIO) -> GCCConferenceCreateResponsePDU:
        """
        Parse ConferenceCreateResponse data into a GCCPDU
        :param stream: byte stream containing the PDU data
        """

        nodeID = Uint16BE.unpack(stream.read(2)) + 1001
        tag = per.readInteger(stream)
        result = per.readEnumeration(stream)

        userDataCount = per.readNumberOfSet(stream)
        if userDataCount != 1:
            raise ParsingError("Expected user data count to be 1, got %d" %
                               userDataCount)

        userDataType = per.readChoice(stream)
        if userDataType != 0xc0:
            raise ParsingError(
                "Expected user data type to be 0xc0 (h221NonStandard), got %d"
                % userDataType)

        key = per.readOctetStream(stream, 4)
        if key != GCCParser.H221_SERVER_KEY:
            raise ParsingError("Expected user data key to be %s, got %s" %
                               (GCCParser.H221_SERVER_KEY, key))

        payload = per.readOctetStream(stream)
        return GCCConferenceCreateResponsePDU(nodeID, tag, result, payload)
예제 #6
0
    def parseConferenceCreateRequest(
            self, stream: BytesIO) -> GCCConferenceCreateRequestPDU:
        """
        Parse ConferenceCreateRequest data into a GCCPDU
        :param stream: byte stream containing the PDU data
        """
        prop = per.readSelection(stream)

        if prop != 8:
            raise ParsingError(
                "Expected property to be 8 (conference name), got %d" % prop)

        conferenceName = per.readNumericString(stream, 1)
        stream.read(1)

        userDataCount = per.readNumberOfSet(stream)
        if userDataCount != 1:
            raise ParsingError("Expected user data count to be 1, got %d" %
                               userDataCount)

        userDataType = per.readChoice(stream)
        if userDataType != 0xc0:
            raise ParsingError(
                "Expected user data type to be 0xc0 (h221NonStandard), got %d"
                % userDataType)

        key = per.readOctetStream(stream, 4)
        if key != GCCParser.H221_CLIENT_KEY:
            raise ParsingError("Expected user data key to be %s, got %s" %
                               (GCCParser.H221_CLIENT_KEY, key))

        payload = per.readOctetStream(stream)
        return GCCConferenceCreateRequestPDU(conferenceName, payload)
예제 #7
0
    def doParse(self, stream):
        messageType = Uint16LE.unpack(stream)
        stream.read(2)

        if messageType not in self.parsers:
            raise ParsingError("Trying to parse invalid pointer event type")

        return self.parsers[messageType](stream)
예제 #8
0
파일: input.py 프로젝트: yuraxdrumz/pyrdp
    def parse(self, stream):
        eventTime = Uint32LE.unpack(stream)
        messageType = Uint16LE.unpack(stream)

        if messageType not in self.parsers:
            raise ParsingError("Invalid input message type")

        return self.parsers[messageType](stream, eventTime)
예제 #9
0
    def parseAttachUserRequest(self, stream: BytesIO) -> MCSAttachUserRequestPDU:
        """
        Parse an Attach User Request PDU
        :param stream: stream containing the data
        """
        if len(stream.read()) > 0:
            raise ParsingError("Unexpected payload")

        return MCSAttachUserRequestPDU()
예제 #10
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))
예제 #11
0
    def parseError(self, data, length):
        """
        Parse a Error PDU from the raw bytes
        :type data: bytes
        :param length: The length in bytes of the Error PDU.
        :return: X224ErrorPDU
        """

        if length < 4:
            raise ParsingError("Invalid X224 Error PDU length indicator: indicator = %d, expected at least 4 bytes")

        destination = Uint16BE.unpack(data[2 : 4])
        cause = Uint8.unpack(data[4])
        payload = data[5 :]

        if len(payload) != length - 4:
            raise ParsingError("Invalid X224 Error PDU payload length: expected = %d, length = %d" % (length - 4, len(payload)))

        return X224ErrorPDU(destination, cause, payload)
예제 #12
0
    def write(self, event):
        stream = BytesIO()
        Uint16LE.pack(event.messageType, stream)
        stream.write(b"\x00" * 2)

        if event.messageType not in self.writers:
            raise ParsingError("Trying to write invalid pointer event type")

        self.writers[event.messageType](stream, event)
        return stream.getvalue()
예제 #13
0
    def parseDisconnectProviderUltimatum(self, stream: BytesIO) -> MCSDisconnectProviderUltimatumPDU:
        """
        Parse a Disconnect Provider Ultimatum PDU
        :param stream: stream containing the data
        """
        reason = per.readEnumeration(stream)

        if len(stream.read()) > 0:
            raise ParsingError("Unexpected payload")

        return MCSDisconnectProviderUltimatumPDU(reason)
예제 #14
0
    def parseStructure(self, stream: BytesIO) -> typing.Union[ClientCoreData, ClientNetworkData, ClientSecurityData, ClientClusterData]:
        header = Uint16LE.unpack(stream)
        length = Uint16LE.unpack(stream) - 4
        data = stream.read(length)

        if len(data) != length:
            raise ParsingError("Client Data length field does not match actual size")

        substream = BytesIO(data)

        if header not in self.parsers:
            raise UnknownPDUTypeError("Trying to parse unknown client data structure %s" % header, header)

        return self.parsers[header](substream)
예제 #15
0
    def parseStructure(self, stream):
        header = Uint16LE.unpack(stream)
        length = Uint16LE.unpack(stream) - 4
        data = stream.read(length)

        if len(data) != length:
            raise ParsingError("Client Data length field does not match actual size")

        substream = BytesIO(data)

        if header not in self.parsers:
            raise UnknownPDUTypeError("Trying to parse unknown client data structure %s" % header, header)

        return self.parsers[header](substream)
예제 #16
0
    def parseChannelJoinRequest(self, stream: BytesIO) -> MCSChannelJoinRequestPDU:
        """
        Parse a Channel Join Request PDU
        :param stream: stream containing the data
        """
        data = stream.read()
        if len(data) < 4:
            raise ParsingError("Invalid Channel Join Request PDU received")

        initiator = Uint16BE.unpack(data[0 : 2]) + MCSChannelID.USERCHANNEL_BASE
        channelID = Uint16BE.unpack(data[2 : 4])
        payload = data[4 :]

        return MCSChannelJoinRequestPDU(initiator, channelID, payload)
예제 #17
0
파일: tpkt.py 프로젝트: yuraxdrumz/pyrdp
    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)
예제 #18
0
    def parseClientNetworkData(self, stream):
        channelCount = Uint32LE.unpack(stream)
        data = stream.getvalue()[4:]

        if len(data) != channelCount * 12:
            raise ParsingError("Invalid channel array size")

        channelDefinitions = []

        for _ in range(channelCount):
            name = stream.read(8).strip(b"\x00").decode()
            options = Uint32LE.unpack(stream)
            channelDefinitions.append(ClientChannelDefinition(name, options))

        return ClientNetworkData(channelDefinitions)
예제 #19
0
    def parseAttachUserConfirm(self, stream: BytesIO) -> MCSAttachUserConfirmPDU:
        """
        Parse an Attach User Confirm PDU
        :param stream: stream containing the data
        """
        result = per.readEnumeration(stream)
        data = stream.read()

        initiator = None
        if len(data) == 2:
            initiator = Uint16BE.unpack(data) + MCSChannelID.USERCHANNEL_BASE
        elif len(data) > 2:
            raise ParsingError("Unexpected payload")

        return MCSAttachUserConfirmPDU(result, initiator)
예제 #20
0
    def parseData(self, data, length):
        """
        Parse a Data PDU from the raw bytes
        :type data: bytes
        :param length: The length in bytes of the Data PDU.
        :return: X224DataPDU
        """

        if length != 2:
            raise ParsingError("Invalid X224 Data PDU length indicator: expected = 2, indicator = %d" % length)

        code = Uint8.unpack(data[1]) & 0xf
        sequence = Uint8.unpack(data[2])
        payload = data[3 :]

        return X224DataPDU(code & 1 == 1, sequence & 0x80 == 0x80, payload)
예제 #21
0
    def parseClientNetworkData(self, stream: BytesIO) -> ClientNetworkData:
        if self.detectBlueKeepScan(stream.getvalue()):
            raise ExploitError("BlueKeep scan or exploit attempted")

        channelCount = Uint32LE.unpack(stream)
        data = stream.getvalue()[4 :]

        if len(data) != channelCount * 12:
            raise ParsingError("Invalid channel array size")

        channelDefinitions = []

        for _ in range(channelCount):
            name = stream.read(8).strip(b"\x00").decode()
            options = Uint32LE.unpack(stream)
            channelDefinitions.append(ClientChannelDefinition(name, options))

        return ClientNetworkData(channelDefinitions)
예제 #22
0
    def parseChannelJoinConfirm(self, stream: BytesIO) -> MCSChannelJoinConfirmPDU:
        """
        Parse a Channel Join Confirm PDU
        :param stream: stream containing the data
        """
        result = per.readEnumeration(stream)
        data = stream.read()

        if len(data) < 4 or len(data) == 5:
            raise ParsingError("Invalid Channel Join Confirm PDU received")
        elif len(data) >= 6:
            channelID = Uint16BE.unpack(data[4 : 6])
            payload = data[6 :]
        else:
            channelID = None
            payload = b""

        initiator = Uint16BE.unpack(data[0 : 2]) + MCSChannelID.USERCHANNEL_BASE
        requested = Uint16BE.unpack(data[2 : 4])
        return MCSChannelJoinConfirmPDU(result, initiator, requested, channelID, payload)
예제 #23
0
 def handleParsingError(self, e: ParsingError, stream: BytesIO):
     with FilePositionGuard(stream):
         e.addLayer(self, stream.read())
예제 #24
0
 def handleParsingError(self, e: ParsingError, data: bytes):
     e.addLayer(self, data)