def _ReportEventError(self, event, error_message): """Reports an event related error. Args: event (EventObject): event. error_message (str): error message. """ event_identifier = event.GetIdentifier() event_identifier_string = event_identifier.CopyToString() error_message = ('Event: {0!s} data type: {1:s} display name: {2:s} ' 'parser chain: {3:s} with error: {4:s}').format( event_identifier_string, event.data_type, event.display_name, event.parser, error_message) logger.error(error_message)
def _ReportEventError(self, event, error_message): """Reports an event related error. Args: event (EventObject): event. error_message (str): error message. """ event_identifier = event.GetIdentifier() event_identifier_string = event_identifier.CopyToString() error_message = ( 'Event: {0!s} data type: {1:s} display name: {2:s} ' 'parser chain: {3:s} with error: {4:s}').format( event_identifier_string, event.data_type, event.display_name, event.parser, error_message) logger.error(error_message)
def _ReportEventError(self, event, event_data, error_message): """Reports an event related error. Args: event (EventObject): event. event_data (EventData): event data. error_message (str): error message. """ event_identifier = event.GetIdentifier() event_identifier_string = event_identifier.CopyToString() display_name = getattr(event_data, 'display_name', None) or 'N/A' parser_chain = getattr(event_data, 'parser', None) or 'N/A' error_message = ('Event: {0!s} data type: {1:s} display name: {2:s} ' 'parser chain: {3:s} with error: {4:s}').format( event_identifier_string, event_data.data_type, display_name, parser_chain, error_message) logger.error(error_message)
def _ReportEventError(self, event, event_data, error_message): """Reports an event related error. Args: event (EventObject): event. event_data (EventData): event data. error_message (str): error message. """ event_identifier = event.GetIdentifier() event_identifier_string = event_identifier.CopyToString() display_name = getattr(event_data, 'display_name', None) or 'N/A' parser_chain = getattr(event_data, 'parser', None) or 'N/A' error_message = ( 'Event: {0!s} data type: {1:s} display name: {2:s} ' 'parser chain: {3:s} with error: {4:s}').format( event_identifier_string, event_data.data_type, display_name, parser_chain, error_message) logger.error(error_message)
def _ReadSourceMappings(self): """Reads the source mappings from the sources.config data file.""" self._source_mappings = {} try: sources_data_file = os.path.join( self._output_mediator.data_location, 'sources.config') with open(sources_data_file, encoding='utf8') as file_object: csv_reader = csv.reader(file_object, delimiter='\t') # Note that csv.reader returns a list per row. header_row = next(csv_reader) if header_row == ['data_type', 'short_source', 'source']: for row in csv_reader: try: self._source_mappings[row[0]] = (row[1], row[2]) except IndexError: logger.error( 'Invalid source mapping: {0!s}'.format(row)) except (IOError, TypeError, csv.Error): pass
def _FormatWindowsEventLogMessage(self, event, event_data, event_data_stream): """Formats a Windows Event Log message field. Args: event (EventObject): event. event_data (EventData): event data. event_data_stream (EventDataStream): event data stream. Returns: str: Windows Event Log message field or None if not available. """ if not self._winevt_resources_helper: self._winevt_resources_helper = ( self._output_mediator.GetWinevtResourcesHelper()) message_string = None source_name = getattr(event_data, 'source_name', None) message_identifier = getattr(event_data, 'message_identifier', None) if source_name and message_identifier: message_string_template = self._winevt_resources_helper.GetMessageString( source_name, message_identifier) if message_string_template: string_values = [string or '' for string in event_data.strings] try: message_string = message_string_template.format( *string_values) except (IndexError, TypeError) as exception: logger.error(( 'Unable to format message string: "{0:s}" and strings: "{1:s}" ' 'with error: {2!s}').format(message_string_template, ', '.join(string_values), exception)) # Unable to create the message string. # TODO: consider returning the unformatted message string. return message_string
def _GetOutputValues(self, event, event_data, event_tag): """Retrieves output values. Args: event (EventObject): event. event_data (EventData): event data. event_tag (EventTag): event tag. Returns: list[str]: output values or None if no timestamp was present in the event. Raises: NoFormatterFound: If no event formatter can be found to match the data type in the event data. """ if not hasattr(event, 'timestamp'): logger.error('Unable to output event without timestamp.') return None # TODO: add function to pass event_values to GetFormattedMessages. message, message_short = self._output_mediator.GetFormattedMessages( event_data) if message is None or message_short is None: data_type = getattr(event_data, 'data_type', 'UNKNOWN') raise errors.NoFormatterFound( 'Unable to find event formatter for: {0:s}.'.format(data_type)) # TODO: add function to pass event_values to GetFormattedSources. source_short, source = self._output_mediator.GetFormattedSources( event, event_data) if source is None or source_short is None: data_type = getattr(event_data, 'data_type', 'UNKNOWN') raise errors.NoFormatterFound( 'Unable to find event formatter for: {0:s}.'.format(data_type)) # TODO: preserve dfdatetime as an object. # TODO: add support for self._output_mediator.timezone date_time = dfdatetime_posix_time.PosixTimeInMicroseconds( timestamp=event.timestamp) format_variables = self._output_mediator.GetFormatStringAttributeNames( event_data) if format_variables is None: data_type = getattr(event_data, 'data_type', 'UNKNOWN') raise errors.NoFormatterFound( 'Unable to find event formatter for: {0:s}.'.format(data_type)) extra_attributes = [] for attribute_name, attribute_value in sorted(event_data.GetAttributes()): if (attribute_name in definitions.RESERVED_VARIABLE_NAMES or attribute_name in format_variables): continue # TODO: some pyparsing based parsers can generate empty bytes values # in Python 3. if (isinstance(attribute_value, py2to3.BYTES_TYPE) and attribute_value == b''): logging.debug(( 'attribute: {0:s} of data type: {1:s} contains an empty bytes ' 'value').format(attribute_name, event_data.data_type)) attribute_value = '' # With ! in {1!s} we force a string conversion since some of # the extra attributes values can be integer, float point or # boolean values. extra_attributes.append( '{0:s}: {1!s}'.format(attribute_name, attribute_value)) extra_attributes = '; '.join(extra_attributes) extra_attributes = extra_attributes.replace('\n', '-').replace('\r', '') inode = self._FormatInode(event_data) hostname = self._FormatHostname(event_data) username = self._FormatUsername(event_data) notes = [] note_string = getattr(event_data, 'notes', None) if note_string: notes.append(note_string) if event_tag: notes.extend(event_tag.labels) if not notes: notes.append('-') year, month, day_of_month = date_time.GetDate() hours, minutes, seconds = date_time.GetTimeOfDay() try: date_string = '{0:02d}/{1:02d}/{2:04d}'.format(month, day_of_month, year) time_string = '{0:02d}:{1:02d}:{2:02d}'.format(hours, minutes, seconds) except (TypeError, ValueError): self._ReportEventError(event, event_data, ( 'unable to copy timestamp: {0!s} to a human readable date and time. ' 'Defaulting to: "00/00/0000" "--:--:--"').format(event.timestamp)) date_string = '00/00/0000' time_string = '--:--:--' output_values = [ date_string, time_string, '{0!s}'.format(self._output_mediator.timezone), '....', source_short, source, '-', username, hostname, message_short, message, '2', getattr(event_data, 'display_name', '-'), '{0!s}'.format(inode), ' '.join(notes), getattr(event_data, 'parser', '-'), extra_attributes] return output_values
def _GetOutputValues(self, event): """Retrieves output values. Args: event (EventObject): event. Returns: list[str]: output values or None if no timestamp was present in the event. Raises: NoFormatterFound: If no event formatter can be found to match the data type in the event. """ if not hasattr(event, 'timestamp'): logger.error('Unable to output event without timestamp.') return None # TODO: add function to pass event_values to GetFormattedMessages. message, message_short = self._output_mediator.GetFormattedMessages( event) if message is None or message_short is None: data_type = getattr(event, 'data_type', 'UNKNOWN') raise errors.NoFormatterFound( 'Unable to find event formatter for: {0:s}.'.format(data_type)) # TODO: add function to pass event_values to GetFormattedSources. source_short, source = self._output_mediator.GetFormattedSources(event) if source is None or source_short is None: data_type = getattr(event, 'data_type', 'UNKNOWN') raise errors.NoFormatterFound( 'Unable to find event formatter for: {0:s}.'.format(data_type)) # TODO: preserve dfdatetime as an object. # TODO: add support for self._output_mediator.timezone date_time = dfdatetime_posix_time.PosixTimeInMicroseconds( timestamp=event.timestamp) format_variables = self._output_mediator.GetFormatStringAttributeNames( event) if format_variables is None: data_type = getattr(event, 'data_type', 'UNKNOWN') raise errors.NoFormatterFound( 'Unable to find event formatter for: {0:s}.'.format(data_type)) extra_attributes = [] for attribute_name, attribute_value in sorted(event.GetAttributes()): if (attribute_name in definitions.RESERVED_VARIABLE_NAMES or attribute_name in format_variables): continue # With ! in {1!s} we force a string conversion since some of # the extra attributes values can be integer, float point or # boolean values. extra_attributes.append('{0:s}: {1!s}'.format( attribute_name, attribute_value)) extra_attributes = '; '.join(extra_attributes) extra_attributes = extra_attributes.replace('\n', '-').replace('\r', '') inode = getattr(event, 'inode', None) if inode is None: if hasattr(event, 'pathspec') and hasattr(event.pathspec, 'image_inode'): inode = event.pathspec.image_inode if inode is None: inode = '-' hostname = self._FormatHostname(event) username = self._FormatUsername(event) notes = [] note_string = getattr(event, 'notes', None) if note_string: notes.append(note_string) tag = getattr(event, 'tag', None) if tag: notes.extend(tag.labels) if not notes: notes.append('-') year, month, day_of_month = date_time.GetDate() hours, minutes, seconds = date_time.GetTimeOfDay() try: date_string = '{0:02d}/{1:02d}/{2:04d}'.format( month, day_of_month, year) time_string = '{0:02d}:{1:02d}:{2:02d}'.format( hours, minutes, seconds) except (TypeError, ValueError): self._ReportEventError(event, ( 'unable to copy timestamp: {0!s} to a human readable date and time. ' 'Defaulting to: "00/00/0000" "--:--:--"').format( event.timestamp)) date_string = '00/00/0000' time_string = '--:--:--' output_values = [ date_string, time_string, '{0!s}'.format(self._output_mediator.timezone), '....', source_short, source, '-', username, hostname, message_short, message, '2', getattr(event, 'display_name', '-'), '{0!s}'.format(inode), ' '.join(notes), getattr(event, 'parser', '-'), extra_attributes ] return output_values
def _ReadWindowsEventLogMessageString( self, storage_reader, log_source, message_identifier): """Reads an Windows EventLog message string. Args: storage_reader (StorageReader): storage reader. log_source (str): EventLog source, such as "Application Error". message_identifier (int): message identifier. Returns: str: message string or None if not available. """ if self._environment_variables is None: self._ReadEnvironmentVariables(storage_reader) if self._windows_eventlog_providers is None: self._ReadWindowsEventLogProviders(storage_reader) if self._windows_eventlog_message_files is None: self._ReadWindowsEventLogMessageFiles(storage_reader) provider = self._windows_eventlog_providers.get( log_source.lower(), None) if not provider: return None if not storage_reader.HasAttributeContainers( 'windows_eventlog_message_string'): return None message_file_identifiers = [] for windows_path in provider.event_message_files or []: path, filename = path_helper.PathHelper.GetWindowsSystemPath( windows_path, self._environment_variables) lookup_path = '\\'.join([path.lower(), filename.lower()]) message_file_identifier = self._windows_eventlog_message_files.get( lookup_path, None) if message_file_identifier: message_file_identifier = message_file_identifier.CopyToString() message_file_identifiers.append(message_file_identifier) message_strings = [] if message_file_identifiers: filter_expression = ( 'language_identifier == {0:d} and ' 'message_identifier == {1:d}').format( self._lcid, message_identifier) # TODO: add message_file_identifiers to filter_expression for message_string in storage_reader.GetAttributeContainers( 'windows_eventlog_message_string', filter_expression=filter_expression): identifier = message_string.GetMessageFileIdentifier() identifier = identifier.CopyToString() if identifier in message_file_identifiers: message_strings.append(message_string) if not message_strings: logger.error( 'No match for message: 0x{0:08x} of source: {1:s}'.format( message_identifier, log_source)) # TODO: add support for mappings in the WEVT_TEMPLATE PE/COFF resource if message_strings: return message_strings[0].string return None
def _GetOutputValues(self, event): """Retrieves output values. Args: event (EventObject): event. Returns: list[str]: output values or None if no timestamp was present in the event. Raises: NoFormatterFound: If no event formatter can be found to match the data type in the event. """ if not hasattr(event, 'timestamp'): logger.error('Unable to output event without timestamp.') return None # TODO: add function to pass event_values to GetFormattedMessages. message, message_short = self._output_mediator.GetFormattedMessages(event) if message is None or message_short is None: data_type = getattr(event, 'data_type', 'UNKNOWN') raise errors.NoFormatterFound( 'Unable to find event formatter for: {0:s}.'.format(data_type)) # TODO: add function to pass event_values to GetFormattedSources. source_short, source = self._output_mediator.GetFormattedSources(event) if source is None or source_short is None: data_type = getattr(event, 'data_type', 'UNKNOWN') raise errors.NoFormatterFound( 'Unable to find event formatter for: {0:s}.'.format(data_type)) date_use = timelib.Timestamp.CopyToDatetime( event.timestamp, self._output_mediator.timezone) format_variables = self._output_mediator.GetFormatStringAttributeNames( event) if format_variables is None: data_type = getattr(event, 'data_type', 'UNKNOWN') raise errors.NoFormatterFound( 'Unable to find event formatter for: {0:s}.'.format(data_type)) extra_attributes = [] for attribute_name, attribute_value in sorted(event.GetAttributes()): if (attribute_name in definitions.RESERVED_VARIABLE_NAMES or attribute_name in format_variables): continue # With ! in {1!s} we force a string conversion since some of # the extra attributes values can be integer, float point or # boolean values. extra_attributes.append( '{0:s}: {1!s}'.format(attribute_name, attribute_value)) extra_attributes = '; '.join(extra_attributes) extra_attributes = extra_attributes.replace('\n', '-').replace('\r', '') inode = getattr(event, 'inode', None) if inode is None: if hasattr(event, 'pathspec') and hasattr( event.pathspec, 'image_inode'): inode = event.pathspec.image_inode if inode is None: inode = '-' hostname = self._FormatHostname(event) username = self._FormatUsername(event) notes = [] note_string = getattr(event, 'notes', None) if note_string: notes.append(note_string) tag = getattr(event, 'tag', None) if tag: notes.extend(tag.labels) if not notes: notes.append('-') date_string = '{0:02d}/{1:02d}/{2:04d}'.format( date_use.month, date_use.day, date_use.year) time_string = '{0:02d}:{1:02d}:{2:02d}'.format( date_use.hour, date_use.minute, date_use.second) output_values = [ date_string, time_string, '{0!s}'.format(self._output_mediator.timezone), '....', source_short, source, '-', username, hostname, message_short, message, '2', getattr(event, 'display_name', '-'), '{0!s}'.format(inode), ' '.join(notes), getattr(event, 'parser', '-'), extra_attributes] return output_values
def _GetOutputValues(self, event, event_data, event_tag): """Retrieves output values. Args: event (EventObject): event. event_data (EventData): event data. event_tag (EventTag): event tag. Returns: list[str]: output values or None if no timestamp was present in the event. Raises: NoFormatterFound: If no event formatter can be found to match the data type in the event data. """ if not hasattr(event, 'timestamp'): logger.error('Unable to output event without timestamp.') return None data_type = getattr(event_data, 'data_type', 'UNKNOWN') # TODO: add function to pass event_values to GetFormattedMessages. message, message_short = self._output_mediator.GetFormattedMessages( event_data) if message is None or message_short is None: raise errors.NoFormatterFound( 'Unable to find event formatter for: {0:s}.'.format(data_type)) # TODO: add function to pass event_values to GetFormattedSources. source_short, source = self._output_mediator.GetFormattedSources( event, event_data) if source is None or source_short is None: raise errors.NoFormatterFound( 'Unable to find event formatter for: {0:s}.'.format(data_type)) # TODO: preserve dfdatetime as an object. # TODO: add support for self._output_mediator.timezone date_time = dfdatetime_posix_time.PosixTimeInMicroseconds( timestamp=event.timestamp) unformatted_attributes = ( formatters_manager.FormattersManager.GetUnformattedAttributes( event_data)) if unformatted_attributes is None: raise errors.NoFormatterFound( 'Unable to find event formatter for: {0:s}.'.format(data_type)) extra_attributes = [] for attribute_name, attribute_value in sorted(event_data.GetAttributes()): if attribute_name in unformatted_attributes: # Some parsers have written bytes values to storage. if isinstance(attribute_value, bytes): attribute_value = attribute_value.decode('utf-8', 'replace') logger.warning( 'Found bytes value for attribute "{0:s}" for data type: ' '{1!s}. Value was converted to UTF-8: "{2:s}"'.format( attribute_name, event_data.data_type, attribute_value)) # With ! in {1!s} we force a string conversion since some of # the extra attributes values can be integer, float point or # boolean values. extra_attributes.append('{0:s}: {1!s}'.format( attribute_name, attribute_value)) extra_attributes = '; '.join(extra_attributes) extra_attributes = extra_attributes.replace('\n', '-').replace('\r', '') inode = self._FormatInode(event_data) hostname = self._FormatHostname(event_data) username = self._FormatUsername(event_data) if event_tag: notes = ' '.join(event_tag.labels) or '-' else: notes = '-' year, month, day_of_month = date_time.GetDate() hours, minutes, seconds = date_time.GetTimeOfDay() try: date_string = '{0:02d}/{1:02d}/{2:04d}'.format(month, day_of_month, year) time_string = '{0:02d}:{1:02d}:{2:02d}'.format(hours, minutes, seconds) except (TypeError, ValueError): self._ReportEventError(event, event_data, ( 'unable to copy timestamp: {0!s} to a human readable date and time. ' 'Defaulting to: "00/00/0000" "--:--:--"').format(event.timestamp)) date_string = '00/00/0000' time_string = '--:--:--' output_values = [ date_string, time_string, '{0!s}'.format(self._output_mediator.timezone), '....', source_short, source, '-', username, hostname, message_short, message, '2', getattr(event_data, 'display_name', '-'), '{0!s}'.format(inode), notes, getattr(event_data, 'parser', '-'), extra_attributes] return output_values