Source code for plaso.parsers.symantec

"""Symantec AV Corporate Edition and Endpoint Protection log file parser."""

from dfdatetime import time_elements as dfdatetime_time_elements

from plaso.containers import events
from plaso.lib import errors
from plaso.parsers import dsv_parser
from plaso.parsers import manager


[docs] class SymantecEventData(events.EventData): """Symantec event data. Attributes: access (str): access. action0 (str): action0. action1 (str): action1. action1_status (str): action1 status. action2 (str): action2. action2_status (str): action2 status. address (str): address. backup_id (str): backup identifier. cat (str): category. cleaninfo (str): clean information. clientgroup (str): client group. compressed (str): compressed. computer (str): computer. definfo (str): definfo. defseqnumber (str): def sequence number. deleteinfo (str): delete information. depth (str): depth. description (str): description. domain_guid (str): domain identifier (GUID). domainname (str): domain name. err_code (str): error code. event_data (str): event data. event (str): event. extra (str): extra. file (str): file. flags (str): flags. groupid (str): group identifier. guid (str): guid. last_written_time (dfdatetime.DateTimeValues): entry last written date and time. license_expiration_dt (str): license expiration date. license_feature_name (str): license feature name. license_feature_ver (str): license feature ver. license_fulfillment_id (str): license fulfillment identifier. license_lifecycle (str): license lifecycle. license_seats_delta (str): license seats delta. license_seats (str): license seats. license_seats_total (str): license seats total. license_serial_num (str): license serial number. license_start_dt (str): license start date. logger (str): logger. login_domain (str): login domain. log_session_guid (str): log session identifier (GUID). macaddr (str): MAC address. new_ext (str): new ext. ntdomain (str): ntdomain. offset (str): offset. parent (str): parent. quarfwd_status (str): quarfwd status. remote_machine_ip (str): remote machine IP address. remote_machine (str): remote machine. scanid (str): scan identifier. snd_status (str): snd status. status (str): status. still_infected (str): still infected. time (str): time. user (str): user. vbin_id (str): vbin identifier. vbin_session_id (str): vbin session identifier. version (str): version. virus_id (str): virus identifier. virus (str): virus. virustype (str): virustype. """ DATA_TYPE = "av:symantec:scanlog"
[docs] def __init__(self): """Initializes event data.""" super().__init__(data_type=self.DATA_TYPE) self.access = None self.action0 = None self.action1 = None self.action1_status = None self.action2 = None self.action2_status = None self.address = None self.backup_id = None self.cat = None self.cleaninfo = None self.clientgroup = None self.compressed = None self.computer = None self.definfo = None self.defseqnumber = None self.deleteinfo = None self.depth = None self.description = None self.domain_guid = None self.domainname = None self.err_code = None self.event_data = None self.event = None self.extra = None self.file = None self.flags = None self.groupid = None self.guid = None self.last_written_time = None self.license_expiration_dt = None self.license_feature_name = None self.license_feature_ver = None self.license_fulfillment_id = None self.license_lifecycle = None self.license_seats_delta = None self.license_seats = None self.license_seats_total = None self.license_serial_num = None self.license_start_dt = None self.logger = None self.login_domain = None self.log_session_guid = None self.macaddr = None self.new_ext = None self.ntdomain = None self.offset = None self.parent = None self.quarfwd_status = None self.remote_machine_ip = None self.remote_machine = None self.scanid = None self.snd_status = None self.status = None self.still_infected = None self.time = None self.user = None self.vbin_id = None self.vbin_session_id = None self.version = None self.virus_id = None self.virus = None self.virustype = None
[docs] class SymantecParser(dsv_parser.DSVParser): """Parses Symantec AV Corporate Edition and Endpoint Protection log files.""" NAME = "symantec_scanlog" DATA_FORMAT = "Symantec AV Corporate Edition and Endpoint Protection log file" # Define the columns that make up the structure of a Symantec log file. # http://www.symantec.com/docs/TECH100099 COLUMNS = [ "time", "event", "cat", "logger", "computer", "user", "virus", "file", "action1", "action2", "action0", "virustype", "flags", "description", "scanid", "new_ext", "groupid", "event_data", "vbin_id", "virus_id", "quarfwd_status", "access", "snd_status", "compressed", "depth", "still_infected", "definfo", "defseqnumber", "cleaninfo", "deleteinfo", "backup_id", "parent", "guid", "clientgroup", "address", "domainname", "ntdomain", "macaddr", "version:", "remote_machine", "remote_machine_ip", "action1_status", "action2_status", "license_feature_name", "license_feature_ver", "license_serial_num", "license_fulfillment_id", "license_start_dt", "license_expiration_dt", "license_lifecycle", "license_seats_total", "license_seats", "err_code", "license_seats_delta", "status", "domain_guid", "log_session_guid", "vbin_session_id", "login_domain", "extra", ] def _ParseTimestamp(self, timestamp): """Parses a Symantec log timestamp. A Symantec log timestamp consist of six hexadecimal octets, that represent: First octet: Number of years since 1970 Second octet: Month, where 0 represents January. Third octet: Day of the month Fourth octet: Number of hours Fifth octet: Number of minutes Sixth octet: Number of seconds For example, 200A13080122 represents November 19, 2002, 8:01:34 AM. Args: timestamp (str): hexadecimal encoded date and time values. Returns: dfdatetime.TimeElements: date and time value. Raises: ParseError: if a valid date and time value cannot be derived from the time elements. """ try: year, month, day_of_month, hours, minutes, seconds = ( int(hexdigit[0] + hexdigit[1], 16) for hexdigit in zip(timestamp[::2], timestamp[1::2]) ) time_elements_tuple = ( 1970 + year, month + 1, day_of_month, hours, minutes, seconds, ) date_time = dfdatetime_time_elements.TimeElements( time_elements_tuple=time_elements_tuple ) date_time.is_local_time = True return date_time except (TypeError, ValueError) as exception: raise errors.ParseError( f"Unable to parse time elements with error: {exception!s}" )
[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. """ timestamp = row["time"] # TODO: remove unused attributes. event_data = SymantecEventData() event_data.access = row.get("access") event_data.action0 = row.get("action0") event_data.action1 = row.get("action1") event_data.action1_status = row.get("action1_status") event_data.action2 = row.get("action2") event_data.action2_status = row.get("action2_status") event_data.address = row.get("address") event_data.backup_id = row.get("backup_id") event_data.cat = row.get("cat") event_data.cleaninfo = row.get("cleaninfo") event_data.clientgroup = row.get("clientgroup") event_data.compressed = row.get("compressed") event_data.computer = row.get("computer") event_data.definfo = row.get("definfo") event_data.defseqnumber = row.get("defseqnumber") event_data.deleteinfo = row.get("deleteinfo") event_data.depth = row.get("depth") event_data.description = row.get("description") event_data.domain_guid = row.get("domain_guid") event_data.domainname = row.get("domainname") event_data.err_code = row.get("err_code") event_data.event_data = row.get("event_data") event_data.event = row.get("event") event_data.extra = row.get("extra") event_data.file = row.get("file") event_data.flags = row.get("flags") event_data.groupid = row.get("groupid") event_data.guid = row.get("guid") event_data.last_written_time = self._ParseTimestamp(timestamp) event_data.license_expiration_dt = row.get("license_expiration_dt") event_data.license_feature_name = row.get("license_feature_name") event_data.license_feature_ver = row.get("license_feature_ver") event_data.license_fulfillment_id = row.get("license_fulfillment_id") event_data.license_lifecycle = row.get("license_lifecycle") event_data.license_seats_delta = row.get("license_seats_delta") event_data.license_seats = row.get("license_seats") event_data.license_seats_total = row.get("license_seats_total") event_data.license_serial_num = row.get("license_serial_num") event_data.license_start_dt = row.get("license_start_dt") event_data.logger = row.get("logger") event_data.login_domain = row.get("login_domain") event_data.log_session_guid = row.get("log_session_guid") event_data.macaddr = row.get("macaddr") event_data.new_ext = row.get("new_ext") event_data.ntdomain = row.get("ntdomain") event_data.offset = row_offset event_data.parent = row.get("parent") event_data.quarfwd_status = row.get("quarfwd_status") event_data.remote_machine_ip = row.get("remote_machine_ip") event_data.remote_machine = row.get("remote_machine") event_data.scanid = row.get("scanid") event_data.snd_status = row.get("snd_status") event_data.status = row.get("status") event_data.still_infected = row.get("still_infected") event_data.time = row.get("time") event_data.user = row.get("user") event_data.vbin_id = row.get("vbin_id") event_data.vbin_session_id = row.get("vbin_session_id") event_data.version = row.get("version:") event_data.virus_id = row.get("virus_id") event_data.virus = row.get("virus") event_data.virustype = row.get("virustype") parser_mediator.ProduceEventData(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. """ timestamp = row["time"] try: self._ParseTimestamp(timestamp) except errors.ParseError: return False try: my_event = int(row["event"], 10) except (TypeError, ValueError): return False if my_event < 1 or my_event > 77: return False try: category = int(row["cat"], 10) except (TypeError, ValueError): return False if category < 1 or category > 4: return False return True
manager.ParsersManager.RegisterParser(SymantecParser)