Exemplo n.º 1
0
 def __init__(self, config_path=None):
     path = os.getenv('FIBRATUS_CONFIG_PATH', __DEFAULT_CONFIG_PATH__)
     path = config_path or path
     try:
         self._yaml = anyconfig.load(path, ignore_missing=False)
     except FileNotFoundError:
         IO.write_console('ERROR - %s configuration file does not exist' %
                          path)
         sys.exit()
Exemplo n.º 2
0
    def __init__(self, filament, **kwargs):

        try:
            log_path = os.path.join(os.path.expanduser('~'), '.fibratus', 'fibratus.log')
            FileHandler(log_path, mode='w+').push_application()
        except PermissionError:
            IO.write_console("ERROR - Unable to open log file for writing due to permission error")
            sys.exit(0)
        self.logger = Logger(Fibratus.__name__)

        self._config = YamlConfig()

        self.logger.info('Starting fibratus...')

        self.kevt_streamc = KEventStreamCollector(etw.KERNEL_LOGGER_NAME.encode())
        self.kcontroller = KTraceController()
        self.ktrace_props = KTraceProps()
        self.ktrace_props.enable_kflags()
        self.ktrace_props.logger_name = etw.KERNEL_LOGGER_NAME

        enum_handles = kwargs.pop('enum_handles', True)

        self.handle_repository = HandleRepository()
        self._handles = []
        # query for handles on the
        # start of the kernel trace
        if enum_handles:
            self.logger.info('Enumerating system handles...')
            self._handles = self.handle_repository.query_handles()
            self.logger.info('%s handles found' % len(self._handles))
            self.handle_repository.free_buffers()
        self.thread_registry = ThreadRegistry(self.handle_repository, self._handles)

        self.kevent = KEvent(self.thread_registry)
        self.keventq = Queue()

        self._adapter_classes = dict(smtp=SmtpAdapter, amqp=AmqpAdapter)
        self._output_adapters = self._construct_adapters()

        if filament:
            filament.keventq = self.keventq
            filament.logger = log_path
            filament.setup_adapters(self._output_adapters)
        self._filament = filament

        self.fsio = FsIO(self.kevent, self._handles)
        self.hive_parser = HiveParser(self.kevent, self.thread_registry)
        self.tcpip_parser = TcpIpParser(self.kevent)
        self.dll_repository = DllRepository(self.kevent)

        self.output_kevents = {}
        self.filters_count = 0
Exemplo n.º 3
0
    def render(self):
        """Renders the kevent to standard output stream.

        Uses the default output format to render the
        kernel event to standard output stream.

        The default output format is as follows:

        id  timestamp  cpu  process  (process id) - kevent (parameters)
        --  ---------  ---  -------  -----------   ------- ------------

        Example:

        160 13:27:27.554 0 wmiprvse.exe (1012) - CloseFile (file=C:\\WINDOWS\\SYSTEM32\\RSAENH.DLL, tid=2668)

        """
        self._thread = self.thread
        if self._thread:
            kevt = RENDER_FORMAT % (self._id,
                                    self._ts.time(),
                                    self._cpuid,
                                    self._thread.name,
                                    self._thread.pid,
                                    self._name,
                                    self._format_params())
        else:
            # figure out the process id from thread
            # if the process can't be found in
            # thread registry
            pid = NA
            if self._pid is None:
                if self._tid:
                    # get the thread handle
                    handle = open_thread(THREAD_QUERY_INFORMATION,
                                         False,
                                         self._tid)
                    if handle:
                        pid = get_process_id_of_thread(handle)
                        close_handle(handle)
            else:
                pid = self._pid
            kevt = RENDER_FORMAT % (self._id,
                                    self._ts.time(),
                                    self._cpuid,
                                    NA,
                                    pid,
                                    self._name,
                                    self._format_params())
        IO.write_console(kevt)
        self._id += 1
Exemplo n.º 4
0
    def render(self):
        """Renders the kevent to standard output stream.

        Uses the default output format to render the
        kernel event to standard output stream.

        The default output format is as follows:

        id  timestamp  cpu  process  (process id) - kevent (parameters)
        --  ---------  ---  -------  -----------   ------- ------------

        Example:

        160 13:27:27.554 0 wmiprvse.exe (1012) - CloseFile (file=C:\\WINDOWS\\SYSTEM32\\RSAENH.DLL, tid=2668)

        """
        self._thread = self.thread
        if self._thread:
            kevt = RENDER_FORMAT % (self._id,
                                    self._ts.time(),
                                    self._cpuid,
                                    self._thread.name,
                                    self._thread.pid,
                                    self._name,
                                    self._format_params())
        else:
            # figure out the process id from thread
            # if the process can't be found in
            # thread registry
            pid = NA
            if self._pid is None:
                if self._tid:
                    # get the thread handle
                    handle = open_thread(THREAD_QUERY_INFORMATION,
                                         False,
                                         self._tid)
                    if handle:
                        pid = get_process_id_of_thread(handle)
                        close_handle(handle)
            else:
                pid = self._pid
            kevt = RENDER_FORMAT % (self._id,
                                    self._ts.time(),
                                    self._cpuid,
                                    NA,
                                    pid,
                                    self._name,
                                    self._format_params())
        IO.write_console(kevt)
        self._id += 1
Exemplo n.º 5
0
 def render_tabular(self):
     """Renders the table to the console.
     """
     if len(self._cols) > 0:
         tabular = self._tabular.get_string(start=1, end=self._limit)
         if self._sort_by:
             tabular = self._tabular.get_string(start=1,
                                                end=self._limit,
                                                sortby=self._sort_by,
                                                reversesort=self._sort_desc)
         self._tabular.clear_rows()
         if not _ansi_term.term_ready:
             try:
                 _ansi_term.setup_console()
             except TermInitializationError:
                 IO.write_console(
                     'fibratus run: ERROR - console initialization failed')
         _ansi_term.cls()
         _ansi_term.write_output(tabular)
Exemplo n.º 6
0
    def start_ktrace(self, name, kprops):
        """Starts a new trace.

        Parameters
        ---------

        name: str
            the name for the trace session
        kprops: KTraceProps
            an instance of the kernel trace properties
        """
        self._trace_name = name
        handle = TRACEHANDLE()
        kp = kprops.get()
        status = start_trace(byref(handle),
                             self._trace_name,
                             kp)
        self._handle = handle
        if status == ERROR_ALREADY_EXISTS:
            # the kernel logger trace session
            # is already running. Restart the trace.
            self.stop_ktrace()
            status = start_trace(byref(handle),
                                 self._trace_name,
                                 kp)
            if status != ERROR_SUCCESS:
                raise FibratusError('Unable to start fibratus')
            self._handle = handle
        elif status == ERROR_ACCESS_DENIED:
            # insufficient privileges
            IO.write_console("ERROR - You don't have administrative privileges. Stopping fibratus...")
            sys.exit()
        elif status == ERROR_BAD_LENGTH:
            raise FibratusError('Incorrect buffer size for the trace buffer')
        elif status == ERROR_INVALID_PARAMETER:
            raise FibratusError('Invalid trace handle or provider GUID')
        elif status != ERROR_SUCCESS:
            raise FibratusError('Unable to start fibratus')
Exemplo n.º 7
0
    def load_filament(self, name):
        if not os.path.exists(FILAMENTS_DIR):
            IO.write_console('fibratus run: ERROR - filaments path %s does not exist.' % FILAMENTS_DIR)
            sys.exit(0)
        [filament_path] = [os.path.join(FILAMENTS_DIR, filament) for filament in os.listdir(FILAMENTS_DIR)
                           if filament.endswith('.py') and name == filament[:-3]] or [None]
        if filament_path:
            loader = SourceFileLoader(name, filament_path)
            self._filament = loader.load_module()
            # check for required methods
            # on the filament module
            doc = inspect.getdoc(self._filament)
            if not doc:
                raise FilamentError("Please provide a short description for the filament")

            [on_next_kevent] = self._find_func('on_next_kevent')
            if on_next_kevent:
                args_spec = inspect.getargspec(on_next_kevent)
                if len(args_spec.args) != 1:
                    raise FilamentError('Missing one argument on_next_kevent method on filament')
            else:
                raise FilamentError('Missing required on_next_kevent method on filament')
        else:
            raise FilamentError('%s filament not found' % name)
Exemplo n.º 8
0
 def _assert_root_dir(cls):
     if not os.path.exists(FILAMENTS_DIR):
         IO.write_console('fibratus run: ERROR - %s path does not exist.' % FILAMENTS_DIR)
         sys.exit(0)
Exemplo n.º 9
0
 def on_kstream_open():
     if self._filament is None:
         IO.write_console('Done!                               ')
Exemplo n.º 10
0
 def stop_ktrace(self):
     IO.write_console('Stopping fibratus...')
     if self._filament:
         self._filament.close()
     self.kcontroller.stop_ktrace(self.ktrace_props)
     self.kevt_streamc.close_kstream()
Exemplo n.º 11
0
 def test_write_console_same_line(self, byref_mock, write_console_unicode_mock):
     IO._stdout_handle = 10
     IO.write_console('Fibratus', False)
     write_console_unicode_mock.assert_called_with(10, 'Fibratus\r', 9, 8, None)
Exemplo n.º 12
0
def _check_kevent(kevent):
    if not kevent in KEvents.all():
        IO.write_console('fibratus run: ERROR - %s is not a valid kernel event. Run list-kevents to see'
                         ' the available kernel events' % kevent)
        sys.exit()

if __name__ == '__main__':
    if args['run']:
        if len(kevent_filters) > 0 and not filament_name:
            for kfilter in kevent_filters:
                _check_kevent(kfilter)

        filament = None
        filament_filters = []
        if not filament_name:
            IO.write_console('Starting fibratus...', False)
        else:
            if not Filament.exists(filament_name):
                IO.write_console('fibratus run: ERROR - %s filament does not exist. Run list-filaments to see'
                                 ' the availble filaments' % filament_name)
                sys.exit()
            filament = Filament()
            try:
                filament.load_filament(filament_name)
            except FilamentError as e:
                IO.write_console('fibratus run: ERROR - %s' % e)
                sys.exit()

            filament.initialize_filament()
            filament_filters = filament.filters
Exemplo n.º 13
0
 def stop_ktrace(self):
     IO.write_console('Stopping fibratus...')
     if self._filament:
         self._filament.close()
     self.kcontroller.stop_ktrace(self.ktrace_props)
     self.kevt_streamc.close_kstream()
Exemplo n.º 14
0
 def _assert_root_dir(cls):
     if not os.path.exists(FILAMENTS_DIR):
         IO.write_console('fibratus run: ERROR - %s path does not exist.' %
                          FILAMENTS_DIR)
         sys.exit(0)
Exemplo n.º 15
0
def main():
    if args['run']:
        if len(kevent_filters) > 0 and not filament_name:
            for kfilter in kevent_filters:
                _check_kevent(kfilter)

        enum_handles = False if args['--no-enum-handles'] else True
        cswitch = True if args['--cswitch'] else False

        filament = None
        filament_filters = []

        if not filament_name:
            IO.write_console('Starting fibratus...', False)
        else:
            if not Filament.exists(filament_name):
                IO.write_console(
                    'fibratus run: ERROR - %s filament does not exist. Run list-filaments to see '
                    'the availble filaments' % filament_name)
                sys.exit()
            filament = Filament()
            try:
                filament.load_filament(filament_name)
            except FilamentError as e:
                IO.write_console('fibratus run: ERROR - %s' % e)
                sys.exit()

            filament_filters = filament.filters

            if len(filament_filters) > 0:
                for kfilter in filament_filters:
                    _check_kevent(kfilter)

            filament.render_tabular()

        try:
            fibratus = Fibratus(filament,
                                enum_handles=enum_handles,
                                cswitch=cswitch)
        except KeyboardInterrupt:
            # the user has stopped command execution
            # before opening the kernel event stream
            sys.exit(0)

        @PHANDLER_ROUTINE
        def handle_ctrl_c(event):
            if event == 0:
                fibratus.stop_ktrace()
            return 0

        set_console_ctrl_handler(handle_ctrl_c, True)

        if not filament:
            if len(kevent_filters) > 0:
                fibratus.add_filters(kevent_filters)
        else:
            if len(filament_filters) > 0:
                fibratus.add_filters(filament_filters)
            else:
                fibratus.add_filters([])
        try:
            fibratus.run()
        except KeyboardInterrupt:
            set_console_ctrl_handler(handle_ctrl_c, False)

    elif args['list-filaments']:
        filaments = Tabular(['Filament', 'Description'],
                            'Description',
                            sort_by='Filament')
        for filament, desc in Filament.list_filaments().items():
            filaments.add_row([filament, desc])
        filaments.draw()

    elif args['list-kevents']:
        kevents = Tabular(['KEvent', 'Category', 'Description'],
                          'Description',
                          sort_by='Category')
        for kevent, meta in KEvents.meta_info().items():
            kevents.add_row([kevent, meta[0].name, meta[1]])
        kevents.draw()
Exemplo n.º 16
0
def _check_kevent(kevent):
    if kevent not in KEvents.all():
        IO.write_console(
            'fibratus run: ERROR - %s is not a valid kernel event. Run list-kevents to see'
            ' the available kernel events' % kevent)
        sys.exit()
Exemplo n.º 17
0
 def test_write_console_unicode(self):
     IO.write_console('aaaàçççñññ skräms inför på fédéra')
Exemplo n.º 18
0
 def on_kstream_open():
     if self._filament is None:
         IO.write_console('Done!                               ')
Exemplo n.º 19
0
 def draw(self):
     IO.write_console(self.get_string())
Exemplo n.º 20
0
def _check_kevent(kevent):
    if not kevent in KEvents.all():
        IO.write_console('fibratus run: ERROR - %s is not a valid kernel event. Run list-kevents to see'
                         ' the available kernel events' % kevent)
        sys.exit()
Exemplo n.º 21
0
        IO.write_console(
            'fibratus run: ERROR - %s is not a valid kernel event. Run list-kevents to see'
            ' the available kernel events' % kevent)
        sys.exit()


if __name__ == '__main__':
    if args['run']:
        if len(kevent_filters) > 0 and not filament_name:
            for kfilter in kevent_filters:
                _check_kevent(kfilter)

        filament = None
        filament_filters = []
        if not filament_name:
            IO.write_console('Starting fibratus...', False)
        else:
            if not Filament.exists(filament_name):
                IO.write_console(
                    'fibratus run: ERROR - %s filament does not exist. Run list-filaments to see'
                    ' the availble filaments' % filament_name)
                sys.exit()
            filament = Filament()
            try:
                filament.load_filament(filament_name)
            except FilamentError as e:
                IO.write_console('fibratus run: ERROR - %s' % e)
                sys.exit()

            filament.initialize_filament()
            filament_filters = filament.filters