Source code for plaso.parsers.mcafeeav

# -*- coding: utf-8 -*-
"""Parser for McAfee Anti-Virus Logs.

McAfee AV uses 4 logs to track when scans were run, when virus databases were
updated, and when files match the virus database."""

from __future__ import unicode_literals

import codecs

from plaso.containers import events
from plaso.containers import time_events
from plaso.lib import errors
from plaso.lib import definitions
from plaso.lib import timelib
from plaso.parsers import dsv_parser
from plaso.parsers import manager


[docs]class McafeeAVEventData(events.EventData): """McAfee AV Log event data. Attributes: action (str): action. filename (str): filename. rule (str): rule. status (str): status. trigger_location (str): trigger location. username (str): username. """ DATA_TYPE = 'av:mcafee:accessprotectionlog' def __init__(self): """Initializes event data.""" super(McafeeAVEventData, self).__init__(data_type=self.DATA_TYPE) self.action = None self.filename = None self.rule = None self.status = None self.trigger_location = None self.username = None
[docs]class McafeeAccessProtectionParser(dsv_parser.DSVParser): """Parses the McAfee AV Access Protection Log.""" NAME = 'mcafee_protection' DESCRIPTION = 'Parser for McAfee AV Access Protection log files.' DELIMITER = b'\t' COLUMNS = [ 'date', 'time', 'status', 'username', 'filename', 'trigger_location', 'rule', 'action'] def _ConvertToTimestamp(self, date, time, timezone): """Converts date and time values into a timestamp. The date and time are made up of two strings, the date and the time, separated by a tab. The time is in local time. The month and day can be either 1 or 2 characters long, e.g.: 7/30/2013\\t10:22:48 AM Args: date (str): date. time (str): time. timezone (pytz.timezone): timezone of the date and time. Returns: int: a timestamp integer containing the number of micro seconds since January 1, 1970, 00:00:00 UTC. Raises: TimestampError: if the timestamp is badly formed or unable to transfer the supplied date and time into a timestamp. """ # TODO: check if this is correct, likely not date or not time # is more accurate. if not date and not time: raise errors.TimestampError( 'Unable to extract timestamp from McAfee AV logline.') # TODO: Figure out how McAfee sets Day First and use that here. # The in-file time format is '07/30/2013\t10:22:48 AM'. try: time_string = '{0:s} {1:s}'.format(date, time) except UnicodeDecodeError: raise errors.TimestampError('Unable to form a timestamp string.') return timelib.Timestamp.FromTimeString(time_string, timezone=timezone)
[docs] def ParseRow(self, parser_mediator, row_offset, row): """Parses a line of the log file and produces events. Args: parser_mediator (ParserMediator): mediates interactions between parsers and other components, such as storage and dfvfs. row_offset (int): line number of the row. row (dict[str, str]): fields of a single row, as specified in COLUMNS. """ try: timestamp = self._ConvertToTimestamp( row['date'], row['time'], parser_mediator.timezone) except errors.TimestampError as exception: parser_mediator.ProduceExtractionWarning( 'Unable to parse time string: [{0:s} {1:s}] with error {2:s}'.format( repr(row['date']), repr(row['time']), exception)) return if timestamp is None: return event_data = McafeeAVEventData() event_data.action = row['action'] event_data.filename = row['filename'] event_data.offset = row_offset event_data.rule = row['rule'] event_data.status = row['status'] event_data.trigger_location = row['trigger_location'] event_data.username = row['username'] event = time_events.TimestampEvent( timestamp, definitions.TIME_DESCRIPTION_WRITTEN) parser_mediator.ProduceEventWithEventData(event, event_data)
[docs] def VerifyRow(self, parser_mediator, row): """Verifies if a line of the file is in the expected format. Args: parser_mediator (ParserMediator): mediates interactions between parsers and other components, such as storage and dfvfs. row (dict[str, str]): fields of a single row, as specified in COLUMNS. Returns: bool: True if this is the correct parser, False otherwise. """ if len(row) != 8: return False # This file can have a UTF-8 byte-order-marker at the beginning of # the first row. # TODO: Find out all the code pages this can have. Asked McAfee 10/31. row_bytes = codecs.encode(row['date'], parser_mediator.codepage) if row_bytes.startswith(b'\xef\xbb\xbf'): row['date'] = row['date'][3:] self._encoding = 'utf-8' # Check the date format! # If it doesn't parse, then this isn't a McAfee AV Access Protection Log try: timestamp = self._ConvertToTimestamp( row['date'], row['time'], parser_mediator.timezone) except errors.TimestampError: return False if timestamp is None: return False # Use the presence of these strings as a backup or in case of partial file. if (not 'Access Protection' in row['status'] and not 'Would be blocked' in row['status']): return False return True
manager.ParsersManager.RegisterParser(McafeeAccessProtectionParser)