コード例 #1
0
    def do_process(self, analysis_context):
        """Process the next request, if any."""
        request_data = self.do_get()
        if request_data is None:
            return
        request_type = request_data[4:8]
        if request_type == b'EEEE':
            json_remote_control_response = None
            exception_data = None
            try:
                json_request_data = (json.loads(request_data[8:].decode()))
                json_request_data = JsonUtil.decode_object(json_request_data)
                if (json_request_data is None) or (not isinstance(json_request_data, list)) or (len(json_request_data) != 2):
                    msg = 'Invalid request data'
                    logging.getLogger(AMinerConfig.DEBUG_LOG_NAME).error(msg)
                    raise Exception(msg)
                if json_request_data[0] and isinstance(json_request_data[0], bytes):
                    json_request_data[0] = json_request_data[0].decode()
                if json_request_data[1]:
                    if isinstance(json_request_data[1], list):
                        new_list = []
                        for item in json_request_data[1]:
                            if isinstance(item, bytes):
                                new_list.append(item.decode())
                            else:
                                new_list.append(item)
                        json_request_data[1] = new_list
                    else:
                        json_request_data[1] = json_request_data[1].decode()
                methods = AMinerRemoteControlExecutionMethods()
                import aminer.analysis
                exec_locals = {
                    'analysis_context': analysis_context, 'remote_control_data': json_request_data[1],
                    'print_current_config': methods.print_current_config, 'print_config_property': methods.print_config_property,
                    'print_attribute_of_registered_analysis_component': methods.print_attribute_of_registered_analysis_component,
                    'change_config_property': methods.change_config_property,
                    'change_attribute_of_registered_analysis_component': methods.change_attribute_of_registered_analysis_component,
                    'rename_registered_analysis_component': methods.rename_registered_analysis_component,
                    'add_handler_to_atom_filter_and_register_analysis_component':
                        methods.add_handler_to_atom_filter_and_register_analysis_component,
                    'save_current_config': methods.save_current_config,
                    'allowlist_event_in_component': methods.allowlist_event_in_component,
                    'blocklist_event_in_component': methods.blocklist_event_in_component,
                    'dump_events_from_history': methods.dump_events_from_history,
                    'ignore_events_from_history': methods.ignore_events_from_history,
                    'list_events_from_history': methods.list_events_from_history,
                    'allowlist_events_from_history': methods.allowlist_events_from_history,
                    'persist_all': methods.persist_all,
                    'list_backups': methods.list_backups,
                    'create_backup': methods.create_backup,
                    'EnhancedNewMatchPathValueComboDetector': aminer.analysis.EnhancedNewMatchPathValueComboDetector,
                    'EventCorrelationDetector': aminer.analysis.EventCorrelationDetector,
                    'EventTypeDetector': aminer.analysis.EventTypeDetector,
                    'HistogramAnalysis': aminer.analysis.HistogramAnalysis,
                    'PathDependentHistogramAnalysis': aminer.analysis.PathDependentHistogramAnalysis,
                    'MatchFilter': aminer.analysis.MatchFilter,
                    'MatchValueAverageChangeDetector': aminer.analysis.MatchValueAverageChangeDetector,
                    'MatchValueStreamWriter': aminer.analysis.MatchValueStreamWriter,
                    'MissingMatchPathValueDetector': aminer.analysis.MissingMatchPathValueDetector,
                    'NewMatchIdValueComboDetector': aminer.analysis.NewMatchIdValueComboDetector,
                    'NewMatchPathDetector': aminer.analysis.NewMatchPathDetector,
                    'NewMatchPathValueComboDetector': aminer.analysis.NewMatchPathValueComboDetector,
                    'NewMatchPathValueDetector': aminer.analysis.NewMatchPathValueDetector,
                    'ParserCount': aminer.analysis.ParserCount,
                    'Rules': aminer.analysis.Rules,
                    'TimeCorrelationDetector': aminer.analysis.TimeCorrelationDetector,
                    'TimeCorrelationViolationDetector': aminer.analysis.TimeCorrelationViolationDetector,
                    'TimestampCorrectionFilters': aminer.analysis.TimestampCorrectionFilters,
                    'TimestampsUnsortedDetector': aminer.analysis.TimestampsUnsortedDetector,
                    'VariableTypeDetector': aminer.analysis.VariableTypeDetector,
                    'AllowlistViolationDetector': aminer.analysis.AllowlistViolationDetector
                }
                logging.getLogger(AMinerConfig.REMOTE_CONTROL_LOG_NAME).log(15, json_request_data[0])
                logging.getLogger(AMinerConfig.DEBUG_LOG_NAME).debug('Remote control: %s', json_request_data[0])

                # skipcq: PYL-W0603
                global suspended_flag
                if json_request_data[0] in ('suspend_aminer()', 'suspend_aminer', 'suspend'):
                    suspended_flag = True
                    msg = methods.REMOTE_CONTROL_RESPONSE + 'OK. aminer is suspended now.'
                    json_remote_control_response = json.dumps(msg)
                    logging.getLogger(AMinerConfig.DEBUG_LOG_NAME).info(msg)
                elif json_request_data[0] in ('activate_aminer()', 'activate_aminer', 'activate'):
                    suspended_flag = False
                    msg = methods.REMOTE_CONTROL_RESPONSE + 'OK. aminer is activated now.'
                    json_remote_control_response = json.dumps(msg)
                    logging.getLogger(AMinerConfig.DEBUG_LOG_NAME).info(msg)
                else:
                    # skipcq: PYL-W0122
                    exec(json_request_data[0], {'__builtins__': None}, exec_locals)
                    json_remote_control_response = json.dumps(exec_locals.get('remoteControlResponse'))
                    if methods.REMOTE_CONTROL_RESPONSE == '':
                        methods.REMOTE_CONTROL_RESPONSE = None
                    if exec_locals.get('remoteControlResponse') is None:
                        json_remote_control_response = json.dumps(methods.REMOTE_CONTROL_RESPONSE)
                    else:
                        json_remote_control_response = json.dumps(
                            exec_locals.get('remoteControlResponse') + methods.REMOTE_CONTROL_RESPONSE)
            # skipcq: FLK-E722
            except:
                exception_data = traceback.format_exc()
                logging.getLogger(AMinerConfig.DEBUG_LOG_NAME).debug('Remote control exception data: %s', str(exception_data))
            # This is little dirty but avoids having to pass over remoteControlResponse dumping again.
            if json_remote_control_response is None:
                json_remote_control_response = 'null'
            json_response = '[%s, %s]' % (json.dumps(exception_data), json_remote_control_response)
            if len(json_response) + 8 > self.max_control_packet_size:
                # Damn: the response would be larger than packet size. Fake a secondary exception and return part of the json string
                # included. Binary search of size could be more efficient, knowing the maximal size increase a string could have in json.
                max_include_size = len(json_response)
                min_include_size = 0
                min_include_response_data = None
                while True:
                    test_size = (max_include_size + min_include_size) >> 1
                    if test_size == min_include_size:
                        break
                    emergency_response_data = json.dumps(
                        ['Exception: Response too large\nPartial response data: %s...' % json_response[:test_size], None])
                    if len(emergency_response_data) + 8 > self.max_control_packet_size:
                        max_include_size = test_size - 1
                    else:
                        min_include_size = test_size
                        min_include_response_data = emergency_response_data
                json_response = min_include_response_data
            # Now size is OK, send the data
            json_response = json_response.encode()
            self.output_buffer += struct.pack("!I", len(json_response) + 8) + b'RRRR' + json_response
        else:
            msg = 'Invalid request type %s' % repr(request_type)
            logging.getLogger(AMinerConfig.DEBUG_LOG_NAME).error(msg)
            raise Exception(msg)
コード例 #2
0
    def do_process(self, analysis_context):
        """Process the next request, if any."""
        request_data = self.do_get()
        if request_data is None:
            return
        request_type = request_data[4:8]
        if request_type == b'EEEE':
            json_remote_control_response = None
            exception_data = None
            try:
                json_request_data = (json.loads(request_data[8:].decode()))
                json_request_data = JsonUtil.decode_object(json_request_data)
                if (json_request_data is None) or (not isinstance(
                        json_request_data,
                        list)) or (len(json_request_data) != 2):
                    raise Exception('Invalid request data')
                json_request_data[0] = shlex.quote(json_request_data[0])
                json_request_data[1] = shlex.quote(json_request_data[1])
                methods = AMinerRemoteControlExecutionMethods()
                import aminer.analysis
                exec_locals = {
                    'analysis_context':
                    analysis_context,
                    'remote_control_data':
                    json_request_data[1],
                    'print_current_config':
                    methods.print_current_config,
                    'print_config_property':
                    methods.print_config_property,
                    'print_attribute_of_registered_analysis_component':
                    methods.print_attribute_of_registered_analysis_component,
                    'change_config_property':
                    methods.change_config_property,
                    'change_attribute_of_registered_analysis_component':
                    methods.change_attribute_of_registered_analysis_component,
                    'rename_registered_analysis_component':
                    methods.rename_registered_analysis_component,
                    'add_handler_to_atom_filter_and_register_analysis_component':
                    methods.
                    add_handler_to_atom_filter_and_register_analysis_component,
                    'save_current_config':
                    methods.save_current_config,
                    'whitelist_event_in_component':
                    methods.whitelist_event_in_component,
                    'dump_events_from_history':
                    methods.dump_events_from_history,
                    'ignore_events_from_history':
                    methods.ignore_events_from_history,
                    'list_events_from_history':
                    methods.list_events_from_history,
                    'whitelist_events_from_history':
                    methods.whitelist_events_from_history,
                    'HistogramAnalysis':
                    aminer.analysis.HistogramAnalysis,
                    'MatchValueAverageChangeDetector':
                    aminer.analysis.MatchValueAverageChangeDetector,
                    'MatchValueStreamWriter':
                    aminer.analysis.MatchValueStreamWriter,
                    'MissingMatchPathValueDetector':
                    aminer.analysis.MissingMatchPathValueDetector,
                    'NewMatchPathDetector':
                    aminer.analysis.NewMatchPathDetector,
                    'NewMatchPathValueComboDetector':
                    aminer.analysis.NewMatchPathValueComboDetector,
                    'Rules':
                    aminer.analysis.Rules,
                    'TimeCorrelationDetector':
                    aminer.analysis.TimeCorrelationDetector,
                    'TimeCorrelationViolationDetector':
                    aminer.analysis.TimeCorrelationViolationDetector,
                    'TimestampCorrectionFilters':
                    aminer.analysis.TimestampCorrectionFilters,
                    'TimestampsUnsortedDetector':
                    aminer.analysis.TimestampsUnsortedDetector,
                    'WhitelistViolationDetector':
                    aminer.analysis.WhitelistViolationDetector
                }
                # write this to the log file!
                logging.basicConfig(
                    filename=AMinerConfig.LOG_FILE,
                    level=logging.DEBUG,
                    format='%(asctime)s %(levelname)s %(message)s',
                    datefmt='%d.%m.%Y %H:%M:%S')
                logging.addLevelName(15, "REMOTECONTROL")
                logging.log(15, json_request_data[0].decode())

                # skipcq: PYL-W0122
                exec(json_request_data[0], {'__builtins__': None}, exec_locals)
                json_remote_control_response = json.dumps(
                    exec_locals.get('remoteControlResponse', None))
                if methods.REMOTE_CONTROL_RESPONSE == '':
                    methods.REMOTE_CONTROL_RESPONSE = None
                if exec_locals.get('remoteControlResponse', None) is None:
                    json_remote_control_response = json.dumps(
                        methods.REMOTE_CONTROL_RESPONSE)
                else:
                    json_remote_control_response = json.dumps(
                        exec_locals.get('remoteControlResponse', None) +
                        methods.REMOTE_CONTROL_RESPONSE)
            # skipcq: FLK-E722
            except:
                exception_data = traceback.format_exc()
            # This is little dirty but avoids having to pass over remoteControlResponse dumping again.
            if json_remote_control_response is None:
                json_remote_control_response = 'null'
            json_response = '[%s, %s]' % (json.dumps(exception_data),
                                          json_remote_control_response)
            if len(json_response) + 8 > self.max_control_packet_size:
                # Damn: the response would be larger than packet size. Fake a secondary exception and return part of the json string
                # included. Binary search of size could be more efficient, knowing the maximal size increase a string could have in json.
                max_include_size = len(json_response)
                min_include_size = 0
                min_include_response_data = None
                while True:
                    test_size = (max_include_size + min_include_size) >> 1
                    if test_size == min_include_size:
                        break
                    emergency_response_data = json.dumps([
                        'Exception: Response too large\nPartial response data: %s...'
                        % json_response[:test_size], None
                    ])
                    if len(emergency_response_data
                           ) + 8 > self.max_control_packet_size:
                        max_include_size = test_size - 1
                    else:
                        min_include_size = test_size
                        min_include_response_data = emergency_response_data
                json_response = min_include_response_data
            # Now size is OK, send the data
            json_response = json_response.encode()
            self.output_buffer += struct.pack(
                "!I",
                len(json_response) + 8) + b'RRRR' + json_response
        else:
            raise Exception('Invalid request type %s' % repr(request_type))