plaso-rubanetra/plaso/parsers/symantec.py
2020-04-06 18:48:34 +02:00

154 lines
5.1 KiB
Python

#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright 2013 The Plaso Project Authors.
# Please see the AUTHORS file for details on individual authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""This file contains a Symantec parser in plaso."""
from plaso.events import text_events
from plaso.lib import timelib
from plaso.parsers import manager
from plaso.parsers import text_parser
import pytz
__author__ = 'David Nides (david.nides@gmail.com)'
class SymantecEvent(text_events.TextEvent):
"""Convenience class for a Symantec line event."""
DATA_TYPE = 'av:symantec:scanlog'
class SymantecParser(text_parser.TextCSVParser):
"""Parse Symantec AV Corporate Edition and Endpoint Protection log files."""
NAME = 'symantec_scanlog'
DESCRIPTION = u'Parser for Symantec Anti-Virus log files.'
# 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 _GetTimestamp(self, timestamp_raw, timezone=pytz.utc):
"""Return a 64-bit signed timestamp value in micro seconds since Epoch.
The timestamp consists of six hexadecimal octets.
They represent the following:
First octet: Number of years since 1970
Second octet: Month, where January = 0
Third octet: Day
Fourth octet: Hour
Fifth octet: Minute
Sixth octet: Second
For example, 200A13080122 represents November 19, 2002, 8:01:34 AM.
Args:
timestamp_raw: The hexadecimal encoded timestamp value.
timezone: Optional timezone (instance of pytz.timezone).
The default is UTC.
Returns:
A plaso timestamp value, micro seconds since Epoch in UTC.
"""
if timestamp_raw == '':
return 0
year, month, day, hours, minutes, seconds = (
int(x[0] + x[1], 16) for x in zip(
timestamp_raw[::2], timestamp_raw[1::2]))
return timelib.Timestamp.FromTimeParts(
year + 1970, month + 1, day, hours, minutes, seconds, timezone=timezone)
def VerifyRow(self, parser_context, row):
"""Verify a single line of a Symantec log file.
Args:
parser_context: A parser context object (instance of ParserContext).
row: A single row from the CSV file.
Returns:
True if this is the correct parser, False otherwise.
"""
try:
timestamp = self._GetTimestamp(row['time'], parser_context.timezone)
except (TypeError, ValueError):
return False
if not timestamp:
return False
# Check few entries.
try:
my_event = int(row['event'])
except TypeError:
return False
if my_event < 1 or my_event > 77:
return False
try:
category = int(row['cat'])
except TypeError:
return False
if category < 1 or category > 4:
return False
return True
def ParseRow(
self, parser_context, row_offset, row, file_entry=None,
parser_chain=None):
"""Parses a row and extract event objects.
Args:
parser_context: A parser context object (instance of ParserContext).
row_offset: The offset of the row.
row: A dictionary containing all the fields as denoted in the
COLUMNS class list.
file_entry: optional file entry object (instance of dfvfs.FileEntry).
The default is None.
parser_chain: Optional string containing the parsing chain up to this
point. The default is None.
"""
timestamp = self._GetTimestamp(row['time'], parser_context.timezone)
# TODO: Create new dict object that only contains valuable attributes.
event_object = SymantecEvent(timestamp, row_offset, row)
parser_context.ProduceEvent(
event_object, parser_chain=parser_chain, file_entry=file_entry)
manager.ParsersManager.RegisterParser(SymantecParser)