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)
def __init__(self, server, fileHandle: BinaryIO, livePlayerSocket: socket, replacementUsername=None, replacementPassword=None): MCSChannelFactory.__init__(self) self.log = getLoggerPassFilters( f"{LOGGER_NAMES.MITM_CONNECTIONS}.{server.getSessionId()}.client") self.log.addFilter(server.metadataFilter) self.replacementUsername = replacementUsername self.replacementPassword = replacementPassword self.server = server self.channelMap: Dict[int, str] = {} self.channelDefinitions = [] self.channelObservers = {} self.deviceRedirectionObserver = None self.useTLS = False self.user = None self.fastPathObserver = None self.conferenceCreateResponse = None self.serverData = None self.crypter = RC4CrypterProxy() rc4Log = getLoggerPassFilters(f"{self.log.name}.rc4") self.securitySettings = SecuritySettings(SecuritySettings.Mode.CLIENT) self.securitySettings.addObserver(self.crypter) self.securitySettings.addObserver(RC4LoggingObserver(rc4Log)) self.tcp = TwistedTCPLayer() self.tcp.createObserver(onConnection=self.startConnection, onDisconnection=self.onDisconnection) self.segmentation = SegmentationLayer() self.segmentation.createObserver( onUnknownHeader=self.onUnknownTPKTHeader) self.tpkt = TPKTLayer() self.x224 = X224Layer() self.x224.createObserver(onConnectionConfirm=self.onConnectionConfirm, onDisconnectRequest=self.onDisconnectRequest) self.mcs = MCSLayer() self.router = MCSClientRouter(self.mcs, self) self.mcs.addObserver(self.router) self.router.createObserver( onConnectResponse=self.onConnectResponse, onDisconnectProviderUltimatum=self.onDisconnectProviderUltimatum) self.mcsConnect = MCSClientConnectionLayer(self.mcs) self.gccConnect = GCCClientConnectionLayer(b"1") self.gccConnect.createObserver( onPDUReceived=self.onConferenceCreateResponse) self.rdpConnect = ClientConnectionLayer() self.rdpConnect.createObserver(onPDUReceived=self.onServerData) 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) Layer.chain(self.mcsConnect, self.gccConnect, self.rdpConnect) record_layers = [FileLayer(fileHandle)] if livePlayerSocket is not None: record_layers.append(SocketLayer(livePlayerSocket)) self.recorder = Recorder(record_layers)
def __init__(self, log: SessionLogger, config: MITMConfig): """ :param log: base logger to use for the connection :param config: the MITM configuration """ self.log = log """Base logger for the connection""" self.clientLog = log.createChild("client") """Base logger for the client side""" self.serverLog = log.createChild("server") """Base logger for the server side""" self.attackerLog = log.createChild("attacker") """Base logger for the attacker side""" self.rc4Log = log.createChild("rc4") """Logger for RC4 secrets""" self.config = config """The MITM configuration""" self.statCounter = StatCounter() """Class to keep track of connection-related statistics such as # of mouse events, # of output events, etc.""" self.state = RDPMITMState() """The MITM state""" self.client = RDPLayerSet() """Layers on the client side""" self.server = RDPLayerSet() """Layers on the server side""" self.player = TwistedPlayerLayerSet() """Layers on the attacker side""" self.recorder = MITMRecorder([], self.state) """Recorder for this connection""" self.channelMITMs = {} """MITM components for virtual channels""" serverConnector = self.connectToServer() self.tcp = TCPMITM(self.client.tcp, self.server.tcp, self.player.tcp, self.getLog("tcp"), self.state, self.recorder, serverConnector, self.statCounter) """TCP MITM component""" self.x224 = X224MITM(self.client.x224, self.server.x224, self.getLog("x224"), self.state, serverConnector, self.startTLS) """X224 MITM component""" self.mcs = MCSMITM(self.client.mcs, self.server.mcs, self.state, self.recorder, self.buildChannel, self.getLog("mcs"), self.statCounter) """MCS MITM component""" self.security: SecurityMITM = None """Security MITM component""" self.slowPath = SlowPathMITM(self.client.slowPath, self.server.slowPath, self.state, self.statCounter) """Slow-path MITM component""" self.fastPath: FastPathMITM = None """Fast-path MITM component""" self.attacker: AttackerMITM = None self.client.x224.addObserver(X224Logger(self.getClientLog("x224"))) self.client.mcs.addObserver(MCSLogger(self.getClientLog("mcs"))) self.client.slowPath.addObserver( SlowPathLogger(self.getClientLog("slowpath"))) self.client.slowPath.addObserver( RecordingSlowPathObserver(self.recorder)) self.server.x224.addObserver(X224Logger(self.getServerLog("x224"))) self.server.mcs.addObserver(MCSLogger(self.getServerLog("mcs"))) self.server.slowPath.addObserver( SlowPathLogger(self.getServerLog("slowpath"))) self.server.slowPath.addObserver( RecordingSlowPathObserver(self.recorder)) self.player.player.addObserver(LayerLogger(self.attackerLog)) self.config.outDir.mkdir(parents=True, exist_ok=True) self.config.replayDir.mkdir(exist_ok=True) self.config.fileDir.mkdir(exist_ok=True) self.state.securitySettings.addObserver(RC4LoggingObserver( self.rc4Log)) if config.recordReplays: date = datetime.datetime.now() replayFileName = "rdp_replay_{}_{}.pyrdp".format( date.strftime('%Y%m%d_%H-%M-%S'), date.microsecond // 1000) self.recorder.addTransport( FileLayer(self.config.replayDir / replayFileName))
def __init__(self, mainLogger: SessionLogger, crawlerLogger: SessionLogger, config: MITMConfig, state: RDPMITMState = None, recorder: Recorder = None): """ :param log: base logger to use for the connection :param config: the MITM configuration """ self.log = mainLogger """Base logger for the connection""" self.clientLog = mainLogger.createChild("client") """Base logger for the client side""" self.serverLog = mainLogger.createChild("server") """Base logger for the server side""" self.attackerLog = mainLogger.createChild("attacker") """Base logger for the attacker side""" self.rc4Log = mainLogger.createChild("rc4") """Logger for RC4 secrets""" self.config = config """The MITM configuration""" self.statCounter = StatCounter() """Class to keep track of connection-related statistics such as # of mouse events, # of output events, etc.""" self.state = state if state is not None else RDPMITMState(self.config) """The MITM state""" self.client = RDPLayerSet() """Layers on the client side""" self.server = RDPLayerSet() """Layers on the server side""" self.player = TwistedPlayerLayerSet() """Layers on the attacker side""" self.recorder = recorder if recorder is not None else MITMRecorder( [], self.state) """Recorder for this connection""" self.channelMITMs = {} """MITM components for virtual channels""" serverConnector = self.connectToServer() self.tcp = TCPMITM(self.client.tcp, self.server.tcp, self.player.tcp, self.getLog("tcp"), self.state, self.recorder, serverConnector, self.statCounter) """TCP MITM component""" self.x224 = X224MITM(self.client.x224, self.server.x224, self.getLog("x224"), self.state, serverConnector, self.startTLS) """X224 MITM component""" self.mcs = MCSMITM(self.client.mcs, self.server.mcs, self.state, self.recorder, self.buildChannel, self.getLog("mcs"), self.statCounter) """MCS MITM component""" self.security: SecurityMITM = None """Security MITM component""" self.slowPath = SlowPathMITM(self.client.slowPath, self.server.slowPath, self.state, self.statCounter) """Slow-path MITM component""" self.fastPath: FastPathMITM = None """Fast-path MITM component""" self.attacker: AttackerMITM = None self.crawler: FileCrawlerMITM = None self.client.x224.addObserver(X224Logger(self.getClientLog("x224"))) self.client.mcs.addObserver(MCSLogger(self.getClientLog("mcs"))) self.client.slowPath.addObserver( SlowPathLogger(self.getClientLog("slowpath"))) self.client.slowPath.addObserver( RecordingSlowPathObserver(self.recorder)) self.server.x224.addObserver(X224Logger(self.getServerLog("x224"))) self.server.mcs.addObserver(MCSLogger(self.getServerLog("mcs"))) self.server.slowPath.addObserver( SlowPathLogger(self.getServerLog("slowpath"))) self.server.slowPath.addObserver( RecordingSlowPathObserver(self.recorder)) self.player.player.addObserver(LayerLogger(self.attackerLog)) self.ensureOutDir() if config.certificateFileName is None: self.certs: CertificateCache = CertificateCache( self.config.certDir, mainLogger.createChild("cert")) else: self.certs = None self.state.securitySettings.addObserver(RC4LoggingObserver( self.rc4Log)) if config.recordReplays: date = datetime.datetime.now() replayFileName = "rdp_replay_{}_{}_{}.pyrdp"\ .format(date.strftime('%Y%m%d_%H-%M-%S'), date.microsecond // 1000, self.log.sessionID) self.recorder.setRecordFilename(replayFileName) self.recorder.addTransport( FileLayer(self.config.replayDir / replayFileName)) if config.enableCrawler: self.crawler: FileCrawlerMITM = FileCrawlerMITM( self.getClientLog( MCSChannelName.DEVICE_REDIRECTION).createChild("crawler"), crawlerLogger, self.config, self.state)