예제 #1
0
파일: MCSMITM.py 프로젝트: wjcxk21/pyrdp
    def onConnectResponse(self, pdu: MCSConnectResponsePDU):
        """
        Parse server connection information. Initialize security settings and map channel IDs to channel names.
        :param pdu: the connect response PDU
        """

        if pdu.result != 0:
            self.client.sendPDU(pdu)
        else:
            # Parse response PDUs
            gccParser = GCCParser()
            rdpParser = ServerConnectionParser()
            gccPDU: GCCConferenceCreateResponsePDU = gccParser.parse(pdu.payload)
            serverData = rdpParser.parse(gccPDU.payload)

            # Save security settings
            self.state.securitySettings.setEncryptionMethod(serverData.securityData.encryptionMethod)
            self.state.securitySettings.setServerRandom(serverData.securityData.serverRandom)

            if serverData.securityData.serverCertificate:
                self.state.securitySettings.setServerPublicKey(serverData.securityData.serverCertificate.publicKey)

            # Map channel names to IDs
            self.state.channelMap[serverData.networkData.mcsChannelID] = MCSChannelName.IO

            for index in range(len(serverData.networkData.channels)):
                channelID = serverData.networkData.channels[index]
                name = self.state.channelDefinitions[index].name
                self.log.info("%(channelName)s <---> Channel #%(channelId)d", {"channelName": name, "channelId": channelID})
                self.state.channelMap[channelID] = name

            # Replace the server's public key with our own key so we can decrypt the incoming client random
            cert = serverData.securityData.serverCertificate
            if cert:
                cert = ProprietaryCertificate(
                    cert.signatureAlgorithmID,
                    cert.keyAlgorithmID,
                    cert.publicKeyType,
                    self.state.rc4RSAKey,
                    cert.signatureType,
                    cert.signature,
                    cert.padding
                )

            # FIPS is not implemented so avoid using that
            security = ServerSecurityData(
                serverData.securityData.encryptionMethod if serverData.securityData.encryptionMethod != EncryptionMethod.ENCRYPTION_FIPS else EncryptionMethod.ENCRYPTION_128BIT,
                serverData.securityData.encryptionLevel if serverData.securityData.encryptionLevel != EncryptionLevel.ENCRYPTION_LEVEL_FIPS else EncryptionLevel.ENCRYPTION_LEVEL_HIGH,
                serverData.securityData.serverRandom,
                cert
            )

            # The clientRequestedProtocols field MUST be the same as the one received in the X224 Connection Request
            serverData.coreData.clientRequestedProtocols = self.state.requestedProtocols

            modifiedServerData = ServerDataPDU(serverData.coreData, security, serverData.networkData)
            modifiedGCCPDU = GCCConferenceCreateResponsePDU(gccPDU.nodeID, gccPDU.tag, gccPDU.result, rdpParser.write(modifiedServerData))
            modifiedMCSPDU = MCSConnectResponsePDU(pdu.result, pdu.calledConnectID, pdu.domainParams, gccParser.write(modifiedGCCPDU))

            self.client.sendPDU(modifiedMCSPDU)
예제 #2
0
파일: server.py 프로젝트: macdaliot/pyrdp
    def onConnectResponse(self, pdu, serverData):
        # MCS Connect Response
        """
        :type pdu: MCSConnectResponsePDU
        :type serverData: ServerDataPDU
        """
        if pdu.result != 0:
            self.mcs.send(pdu)
            return

        # Replace the server's public key with our own key so we can decrypt the incoming client random
        cert = serverData.security.serverCertificate
        if cert:
            cert = ProprietaryCertificate(cert.signatureAlgorithmID,
                                          cert.keyAlgorithmID,
                                          cert.publicKeyType, self.rc4RSAKey,
                                          cert.signatureType, cert.signature,
                                          cert.padding)

        security = ServerSecurityData(
            # FIPS is not implemented so avoid using that
            serverData.security.encryptionMethod
            if serverData.security.encryptionMethod !=
            EncryptionMethod.ENCRYPTION_FIPS else
            EncryptionMethod.ENCRYPTION_128BIT,
            serverData.security.encryptionLevel
            if serverData.security.encryptionLevel !=
            EncryptionLevel.ENCRYPTION_LEVEL_FIPS else
            EncryptionLevel.ENCRYPTION_LEVEL_HIGH,
            serverData.security.serverRandom,
            cert)

        serverData.core.clientRequestedProtocols = self.originalNegotiationPDU.requestedProtocols

        self.securitySettings.serverSecurityReceived(security)
        self.serverData = ServerDataPDU(serverData.core, security,
                                        serverData.network)

        rdpParser = ServerConnectionParser()
        gccParser = GCCParser()

        gcc = self.client.conferenceCreateResponse
        gcc = GCCConferenceCreateResponsePDU(gcc.nodeID, gcc.tag, gcc.result,
                                             rdpParser.write(self.serverData))
        pdu = MCSConnectResponsePDU(pdu.result, pdu.calledConnectID,
                                    pdu.domainParams, gccParser.write(gcc))
        self.mcs.send(pdu)
예제 #3
0
 def __init__(self, sendParser = ClientConnectionParser(), recvParser = ServerConnectionParser()):
     """
     :param sendParser: parser to use when sending client PDUs.
     :param recvParser: parser to use when receiving server PDUs.
     """
     Layer.__init__(self, None, hasNext=True)
     self.sendParser = sendParser
     self.recvParser = recvParser
예제 #4
0
파일: server.py 프로젝트: macdaliot/pyrdp
    def __init__(self, friendlyName: str, targetHost: str, targetPort: int,
                 certificateFileName: str, privateKeyFileName: str,
                 recordHost: str, recordPort: int, replacementUsername: str,
                 replacementPassword: str):
        MCSUserObserver.__init__(self)

        self.sessionId = f"{friendlyName}{random.randrange(100000,999999)}"
        self.log = getLoggerPassFilters(
            f"{LOGGER_NAMES.MITM_CONNECTIONS}.{self.sessionId}.server")
        self.metadataFilter = ConnectionMetadataFilter(self, self.sessionId)
        self.log.addFilter(self.metadataFilter)

        self.replacementPassword = replacementPassword
        self.replacementUsername = replacementUsername
        self.targetHost = targetHost
        self.targetPort = targetPort
        self.certificateFileName = certificateFileName
        self.privateKeyFileName = privateKeyFileName
        self.clipboardObserver = None
        self.useTLS = False
        self.client: MITMClient = None
        self.clientConnector = None
        self.originalNegotiationPDU = None
        self.targetNegotiationPDU = None
        self.serverData = None
        self.rc4RSAKey = RSA.generate(2048)
        self.crypter = RC4CrypterProxy()
        self.socket = None
        self.fileHandle = open(
            "out/rdp_replay_{}_{}.pyrdp".format(
                datetime.datetime.now().strftime('%Y%m%d_%H-%M-%S'),
                random.randint(0, 1000)), "wb")

        rc4Log = getLoggerPassFilters(f"{self.log.name}.rc4")
        self.securitySettings = SecuritySettings(SecuritySettings.Mode.SERVER)
        self.securitySettings.addObserver(self.crypter)
        self.securitySettings.addObserver(RC4LoggingObserver(rc4Log))

        self.tcp = TwistedTCPLayer()
        self.tcp.createObserver(onConnection=self.onConnection,
                                onDisconnection=self.onDisconnection)

        self.segmentation = SegmentationLayer()
        self.segmentation.createObserver(
            onUnknownHeader=self.onUnknownTPKTHeader)

        self.tpkt = TPKTLayer()

        self.x224 = X224Layer()
        self.x224.createObserver(onConnectionRequest=self.onConnectionRequest,
                                 onDisconnectRequest=self.onDisconnectRequest)

        self.mcs = MCSLayer()
        self.router = MITMServerRouter(self.mcs, self)
        self.mcs.addObserver(self.router)
        self.router.createObserver(
            onConnectionReceived=self.onConnectInitial,
            onDisconnectProviderUltimatum=self.onDisconnectProviderUltimatum,
            onAttachUserRequest=self.onAttachUserRequest,
            onChannelJoinRequest=self.onChannelJoinRequest)

        self.gcc = GCCParser()

        self.rdpClientInfoParser = ClientInfoParser()
        self.rdpClientConnectionParser = ClientConnectionParser()
        self.rdpServerConnectionParser = ServerConnectionParser()

        self.securityLayer = None
        self.slowPathLayer = SlowPathLayer()
        self.fastPathLayer = None

        self.tcp.setNext(self.segmentation)
        self.segmentation.attachLayer(SegmentationPDUType.TPKT, self.tpkt)
        Layer.chain(self.tpkt, self.x224, self.mcs)

        if recordHost is not None and recordPort is not None:
            self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            try:
                self.socket.connect((recordHost, recordPort))
            except socket.error as e:
                logging.getLogger(LOGGER_NAMES.MITM).error(
                    "Could not connect to liveplayer: %(error)s", {"error": e})
                self.socket.close()
                self.socket = None

        recordingLayers = [FileLayer(self.fileHandle)]
        if self.socket is not None:
            recordingLayers.append(SocketLayer(self.socket))

        # Since we're intercepting communications from the original client (so we're a server),
        # We need to write back the packets as if they came from the client.
        self.recorder = Recorder(recordingLayers)