Esempio n. 1
0
File: base.py Progetto: wflk/kitty
 def setup(self):
     '''
     Make sure the monitor is ready for fuzzing
     '''
     self._cleanup()
     self.monitor_thread = LoopFuncThread(self._monitor_func)
     self.monitor_thread.start()
Esempio n. 2
0
 def setup(self):
     '''
     Make sure the monitor is ready for fuzzing
     '''
     super(BaseMonitor, self).setup()
     self.monitor_thread = LoopFuncThread(self._monitor_func)
     self.monitor_thread.start()
Esempio n. 3
0
class BaseMonitor(KittyActorInterface):
    '''
    Base (abstract) monitor class
    '''

    def __init__(self, name, logger=None, victim_alive_check_delay=0.3):
        '''
        :param name: name of the actor
        :param logger: logger for the actor (default: None)
        :param victim_alive_check_delay: delay between checks if alive (default: 0.3)
        '''
        super(BaseMonitor, self).__init__(name, logger, victim_alive_check_delay)
        self.monitor_thread = None

    def setup(self):
        '''
        Make sure the monitor is ready for fuzzing
        '''
        super(BaseMonitor, self).setup()
        self.monitor_thread = LoopFuncThread(self._monitor_func)
        self.monitor_thread.start()

    def teardown(self):
        '''
        cleanup the monitor data and
        '''
        self.monitor_thread.stop()
        self.monitor_thread = None
        super(BaseMonitor, self).teardown()

    def pre_test(self, test_number):
        '''
        Called when a test is started

        :param test_number: current test number
        '''
        if not self._is_alive():
            self.setup()
        super(BaseMonitor, self).pre_test(test_number)

    def _is_alive(self):
        '''
        Check if the monitor is alive
        '''
        if self.monitor_thread is not None:
            if self.monitor_thread.is_alive():
                return True
        return False

    def _monitor_func(self):
        '''
        Called in a loop in a separate thread (self.monitor_thread).
        '''
        self.not_implemented('_monitor_func')
Esempio n. 4
0
class BaseMonitor(KittyActorInterface):
    '''
    Base (abstract) monitor class
    '''
    def __init__(self, name, logger=None, victim_alive_check_delay=0.3):
        '''
        :param name: name of the actor
        :param logger: logger for the actor (default: None)
        :param victim_alive_check_delay: delay between checks if alive (default: 0.3)
        '''
        super(BaseMonitor, self).__init__(name, logger,
                                          victim_alive_check_delay)
        self.monitor_thread = None

    def setup(self):
        '''
        Make sure the monitor is ready for fuzzing
        '''
        super(BaseMonitor, self).setup()
        self.monitor_thread = LoopFuncThread(self._monitor_func)
        self.monitor_thread.start()

    def teardown(self):
        '''
        cleanup the monitor data and
        '''
        self.monitor_thread.stop()
        self.monitor_thread = None
        super(BaseMonitor, self).teardown()

    def pre_test(self, test_number):
        '''
        Called when a test is started

        :param test_number: current test number
        '''
        if not self._is_alive():
            self.setup()
        super(BaseMonitor, self).pre_test(test_number)

    def _is_alive(self):
        '''
        Check if the monitor is alive
        '''
        if self.monitor_thread is not None:
            if self.monitor_thread.is_alive():
                return True
        return False

    def _monitor_func(self):
        '''
        Called in a loop in a separate thread (self.monitor_thread).
        '''
        self.not_implemented('_monitor_func')
Esempio n. 5
0
 def __init__(self, name='ClientFuzzer', logger=None, option_line=None):
     '''
     :param name: name of the object
     :param logger: logger for the object (default: None)
     :param option_line: cmd line options to the fuzzer
     '''
     super(ClientFuzzer, self).__init__(name, logger, option_line)
     self._target_control_thread = LoopFuncThread(self._do_trigger)
     self._trigger_stop_evt = Event()
     self._target_control_thread.set_func_stop_event(self._trigger_stop_evt)
     self._index_in_path = 0
     self._requested_stages = []
     self._report = None
     self._done_evt = Event()
Esempio n. 6
0
 def setup(self):
     '''
     Make sure the monitor is ready for fuzzing
     '''
     super(BaseMonitor, self).setup()
     self.monitor_thread = LoopFuncThread(self._monitor_func)
     self.monitor_thread.start()
Esempio n. 7
0
 def setup(self):
     '''
     Make sure the monitor is ready for fuzzing
     '''
     self._cleanup()
     self.monitor_thread = LoopFuncThread(self._monitor_func)
     self.monitor_thread.start()
Esempio n. 8
0
 def __init__(self, name='ClientFuzzer', logger=None, option_line=None):
     '''
     :param name: name of the object
     :param logger: logger for the object (default: None)
     :param option_line: cmd line options to the fuzzer
     '''
     super(ClientFuzzer, self).__init__(name, logger, option_line)
     self._target_control_thread = LoopFuncThread(self._do_trigger)
     self._trigger_stop_evt = Event()
     self._target_control_thread.set_func_stop_event(self._trigger_stop_evt)
     self._index_in_path = 0
Esempio n. 9
0
class ClientFuzzer(BaseFuzzer):
    '''
    ClientFuzzer is designed for fuzzing clients.
    It does not preform an active fuzzing, but rather returns a mutation of a
    response when in the right state.
    It is designed to be a module that is integrated into different stacks.

    You can see its usahe examples in the following places:

        - examples/02_client_fuzzer_browser_remote
        - examples/03_client_fuzzer_browser
    '''

    #  Wild card for matching any stage
    STAGE_ANY = '******************'

    def __init__(self, name='ClientFuzzer', logger=None, option_line=None):
        '''
        :param name: name of the object
        :param logger: logger for the object (default: None)
        :param option_line: cmd line options to the fuzzer
        '''
        super(ClientFuzzer, self).__init__(name, logger, option_line)
        self._target_control_thread = LoopFuncThread(self._do_trigger)
        self._trigger_stop_evt = Event()
        self._target_control_thread.set_func_stop_event(self._trigger_stop_evt)
        self._index_in_path = 0
        self._requested_stages = []
        self._report = None
        self._done_evt = Event()

    def _pre_test(self):
        self._requested_stages = []
        self._report = Report(self.get_name())
        super(ClientFuzzer, self)._pre_test()

    def is_done(self):
        '''
        check if fuzzer is done fuzzing

        :return: True if done
        '''
        return self._done_evt.is_set()

    def wait_until_done(self):
        '''
        wait until fuzzer is done
        '''
        self._done_evt.wait()

    def stop(self):
        '''
        Stop the fuzzing session
        '''
        self.logger.info('Stopping client fuzzer')
        self._target_control_thread.stop()
        self.target.signal_mutated()
        super(ClientFuzzer, self).stop()

    def _do_trigger(self):
        self.logger.debug('_do_trigger called')
        self._check_pause()
        if self._next_mutation():
            self._fuzz_path = self.model.get_sequence()
            self._index_in_path = 0
            self._pre_test()
            self._test_info()
            self.target.trigger()
            self._post_test()
        else:
            self._end_message()
            self._done_evt.set()
            self._trigger_stop_evt.wait()

    def _start(self):
        self._target_control_thread.start()

    def _test_environment(self):
        '''
        .. todo:: can we do that here somehow?
        '''
        pass

    def _should_fuzz_node(self, fuzz_node, stage):
        '''
        The matching stage is either the name of the last node, or ClientFuzzer.STAGE_ANY.

        :return: True if we are in the correct model node
        '''
        if stage == ClientFuzzer.STAGE_ANY:
            return True
        if fuzz_node.name.lower() == stage.lower():
            if self._index_in_path == len(self._fuzz_path) - 1:
                return True
        else:
            return False

    def _update_path_index(self, stage):
        last_index_in_path = len(self._fuzz_path) - 1
        if self._index_in_path < last_index_in_path:
            node = self._fuzz_path[self._index_in_path].dst
            if node.name.lower() == stage.lower():
                self._index_in_path += 1

    def get_mutation(self, stage, data):
        '''
        Get the next mutation, if in the correct stage

        :param stage: current stage of the stack
        :param data: a dictionary of items to pass to the model
        :return: mutated payload if in apropriate stage, None otherwise
        '''
        payload = None
        # Commented out for now: we want to return the same
        # payload - while inside the same test
        # if self._keep_running() and self._do_fuzz.is_set():
        if self._keep_running():
            fuzz_node = self._fuzz_path[self._index_in_path].dst
            if self._should_fuzz_node(fuzz_node, stage):
                fuzz_node.set_session_data(data)
                payload = fuzz_node.render().tobytes()
                self._last_payload = payload
            else:
                self._update_path_index(stage)
        if payload:
            self._notify_mutated()
        self._requested_stages.append((stage, payload))
        return payload

    def _notify_mutated(self):
        self.target.signal_mutated()

    def _get_report(self):
        base_report = super(ClientFuzzer, self)._get_report()
        if len(self._requested_stages):
            stages, payloads = zip(*self._requested_stages)
        else:
            stages = []
            payloads = []
        self._report.add('stages', stages)
        self._report.add('payloads', [
            None if payload is None else hexlify(payload)
            for payload in payloads
        ])
        base_report.add('fuzzer', self._report)
        return base_report
Esempio n. 10
0
File: base.py Progetto: wflk/kitty
class BaseMonitor(KittyObject):
    '''
    Base (abstract) monitor class
    '''
    def __init__(self, name, logger=None):
        '''
        :param name: name of the monitor
        :param logger: logger for the monitor (default: None)
        '''
        super(BaseMonitor, self).__init__(name, logger)
        self.report = Report(name)
        self.monitor_thread = None
        self.test_number = None

    def setup(self):
        '''
        Make sure the monitor is ready for fuzzing
        '''
        self._cleanup()
        self.monitor_thread = LoopFuncThread(self._monitor_func)
        self.monitor_thread.start()

    def teardown(self):
        '''
        cleanup the monitor data and
        '''
        self.monitor_thread.stop()
        self.monitor_thread = None

    def pre_test(self, test_number):
        '''
        Called when a test is started

        :param test_number: current test number
        '''
        if not self._is_alive():
            self.setup()
        self._cleanup()
        self.test_number = test_number
        self.report.add('state', 'STARTED')
        self.report.add('start_time', time.time())
        self.report.add('name', self.name)

    def post_test(self):
        '''
        Called when a test is completed, prepare the report etc.
        '''
        self.report.add('state', 'STOPPED')
        self.report.add('stop_time', time.time())

    def _is_alive(self):
        '''
        Check if victim/monitor alive
        '''
        if self.monitor_thread is not None:
            if self.monitor_thread.is_alive():
                return True
        return False

    def _cleanup(self):
        '''
        perform a monitor cleanup
        '''
        self.report = Report(self.name)

    def get_report(self):
        '''
        :return: the monitor's report
        '''
        return self.report

    def _monitor_func(self):
        '''
        Called in a loop in a separate thread (self.monitor_thread).
        '''
        self.not_implemented('_monitor_func')
Esempio n. 11
0
class ClientFuzzer(BaseFuzzer):
    '''
    ClientFuzzer is designed for fuzzing clients.
    It does not preform an active fuzzing, but rather returns a mutation of a
    response when in the right state.
    It is designed to be a module that is integrated into different stacks.
    See its usage example in the file examples/client_fuzzer_example.py which
    designed to fuzz a browser.
    '''

    #  Wild card for matching any stage
    STAGE_ANY = '******************'

    def __init__(self, name='ClientFuzzer', logger=None, option_line=None):
        '''
        :param name: name of the object
        :param logger: logger for the object (default: None)
        :param option_line: cmd line options to the fuzzer
        '''
        super(ClientFuzzer, self).__init__(name, logger, option_line)
        self._target_control_thread = LoopFuncThread(self._do_trigger)
        self._trigger_stop_evt = Event()
        self._target_control_thread.set_func_stop_event(self._trigger_stop_evt)
        self._index_in_path = 0
        self._requested_stages = []
        self._report = None
        self._done_evt = Event()

    def _pre_test(self):
        self._requested_stages = []
        self._report = Report(self.get_name())
        super(ClientFuzzer, self)._pre_test()

    def is_done(self):
        '''
        check if fuzzer is done fuzzing

        :return: True if done
        '''
        return self._done_evt.is_set()

    def wait_until_done(self):
        '''
        wait until fuzzer is done
        '''
        self._done_evt.wait()

    def stop(self):
        '''
        Stop the fuzzing session
        '''
        self.logger.info('Stopping client fuzzer')
        self._target_control_thread.stop()
        self.target.signal_mutated()
        super(ClientFuzzer, self).stop()

    def _do_trigger(self):
        self.logger.debug('_do_trigger called')
        self._check_pause()
        if self._keep_running() and self.model.mutate():
            self._fuzz_path = self.model.get_sequence()
            self._index_in_path = 0
            self._pre_test()
            self._test_info()
            self.target.trigger()
            self._post_test()
        else:
            self._end_message()
            self._done_evt.set()
            self._trigger_stop_evt.wait()

    def _start(self):
        self._start_message()
        self.target.setup()
        self._target_control_thread.start()

    def _should_fuzz_node(self, fuzz_node, stage):
        '''
        The matching stage is either the name of the last node, or ClientFuzzer.STAGE_ANY.

        :return: True if we are in the correct model node
        '''
        if stage == ClientFuzzer.STAGE_ANY:
            return True
        if fuzz_node.name.lower() == stage.lower():
            if self._index_in_path == len(self._fuzz_path) - 1:
                return True
        else:
            return False

    def get_mutation(self, stage, data):
        '''
        Get the next mutation, if in the correct stage

        :param stage: current stage of the stack
        :param data: a dictionary of items to pass to the model
        :return: mutated payload if in apropriate stage, None otherwise
        '''
        payload = None
        # Commented out for now: we want to return the same
        # payload - while inside the same test
        # if self._keep_running() and self._do_fuzz.is_set():
        if self._keep_running():
            fuzz_node = self._fuzz_path[self._index_in_path].dst
            if self._should_fuzz_node(fuzz_node, stage):
                fuzz_node.set_session_data(data)
                payload = fuzz_node.render().tobytes()
                self._last_payload = payload
            else:
                self._index_in_path += 1
                if self._index_in_path >= len(self._fuzz_path):
                    self._index_in_path = 0
        if payload:
            self._notify_mutated()
        self._requested_stages.append((stage, payload))
        return payload

    def _notify_mutated(self):
        self.target.signal_mutated()

    def _get_report(self):
        base_report = super(ClientFuzzer, self)._get_report()
        stages, payloads = zip(*self._requested_stages)
        self._report.add('stages', stages)
        self._report.add('payloads', [None if payload is None else hexlify(payload) for payload in payloads])
        base_report.add('fuzzer', self._report)
        return base_report
Esempio n. 12
0
class BaseMonitor(KittyObject):
    '''
    Base (abstract) monitor class
    '''

    def __init__(self, name, logger=None):
        '''
        :param name: name of the monitor
        :param logger: logger for the monitor (default: None)
        '''
        super(BaseMonitor, self).__init__(name, logger)
        self.report = Report(name)
        self.monitor_thread = None
        self.test_number = None

    def setup(self):
        '''
        Make sure the monitor is ready for fuzzing
        '''
        self._cleanup()
        self.monitor_thread = LoopFuncThread(self._monitor_func)
        self.monitor_thread.start()

    def teardown(self):
        '''
        cleanup the monitor data and
        '''
        self.monitor_thread.stop()
        self.monitor_thread = None

    def pre_test(self, test_number):
        '''
        Called when a test is started

        :param test_number: current test number
        '''
        if not self._is_alive():
            self.setup()
        self._cleanup()
        self.test_number = test_number
        self.report.add('state', 'STARTED')
        self.report.add('start_time', time.time())
        self.report.add('name', self.name)

    def post_test(self):
        '''
        Called when a test is completed, prepare the report etc.
        '''
        self.report.add('state', 'STOPPED')
        self.report.add('stop_time', time.time())

    def _is_alive(self):
        '''
        Check if victim/monitor alive
        '''
        if self.monitor_thread is not None:
            if self.monitor_thread.is_alive():
                return True
        return False

    def _cleanup(self):
        '''
        perform a monitor cleanup
        '''
        self.report = Report(self.name)

    def get_report(self):
        '''
        :return: the monitor's report
        '''
        return self.report

    def _monitor_func(self):
        '''
        Called in a loop in a separate thread (self.monitor_thread).
        '''
        self.not_implemented('_monitor_func')