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

755 lines
36 KiB
Python
Executable File

#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright 2014 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.
import os
import logging
from plaso.lib import errors, event, timelib
from plaso.events.time_events import TimestampEvent
from plaso.lib.eventdata import EventTimestamp
from plaso.parsers import interface
from plaso.parsers import manager
try:
import xml.etree.cElementTree as ElementTree
except ImportError:
import xml.etree.ElementTree as ElementTree
__author__ = 'Stefan Swerk (stefan_rubanetra@swerk.priv.at)'
class RubanetraXmlParser(interface.BaseParser):
""" This class represents the python parser-component of the Rubanetra
project. Currently, it is only capable of parsing files adhering to the
XML standard and depends on the 'xml.etree' library.
"""
NAME = 'rubanetra_xml_parser'
DESCRIPTION = u'Rubanetra XML file parser'
VERSION = u'0.0.6'
RUBANETRA_METADATA_FIELDS = frozenset(['implementationVersion', 'implementationTitle', 'implementationVendor'])
def Parse(self, parser_context, file_entry, parser_chain=None):
""" Parses a XML file containing Rubanetra produced content.
:param parser_context: A parser context object (instance of ParserContext).
:param file_entry: A file entry object (instance of dfvfs.FileEntry).
:param parser_chain: Optional string containing the parsing chain up to this
point. The default is None.
"""
rubanetra_metadata_fields = set(self.RUBANETRA_METADATA_FIELDS)
rubanetra_metadata_dict = dict()
file_handle = None
try:
if file_entry is not None and file_entry.IsFile():
# Open the file read-only.
file_handle = file_entry.GetFileObject()
else:
raise errors.UnableToParseFile(u'Not a valid Rubanetra file.')
file_size = file_handle.get_size()
if file_size <= 0:
raise errors.UnableToParseFile(u'File size: {0:d} bytes is less or equal than 0.'.format(file_size))
# read from the beginning and check whether this is a XML file
file_handle.seek(0, os.SEEK_SET)
# get an iterable xml parser context
xml_parser_context = ElementTree.iterparse(file_handle, events=('start', 'end'))
# turn it into an iterator
xml_parser_context = iter(xml_parser_context)
# check whether this is a valid XML file
try:
xml_parser_context.next()
except ElementTree.ParseError:
raise errors.UnableToParseFile(u'Not a valid Rubanetra file (not XML).')
# Add ourselves to the parser chain, which will be used in all subsequent
# event creation in this parser.
parser_chain = self._BuildParserChain(parser_chain)
# read from the beginning to process metadata
file_handle.seek(0, os.SEEK_SET)
# get an iterable xml parser context
xml_parser_context = ElementTree.iterparse(file_handle, events=('start', 'end'))
# turn it into an iterator
xml_parser_context = iter(xml_parser_context)
# get the root element
xml_event, xml_root = xml_parser_context.next()
for xml_event, xml_elem in xml_parser_context:
if xml_event == 'end':
# ... process metadata ...
if xml_elem.tag in rubanetra_metadata_fields:
rubanetra_metadata_dict[xml_elem.tag] = xml_elem.text
rubanetra_metadata_fields.discard(xml_elem.tag)
elif len(rubanetra_metadata_fields) == 0:
xml_elem.clear()
xml_root.clear()
break
xml_elem.clear()
xml_root.clear()
if len(rubanetra_metadata_fields) != 0:
raise errors.UnableToParseFile(
u'Unable to verify metadata, required fields {0:s} could not be parsed'.format(rubanetra_metadata_fields))
self.validate_metadata(rubanetra_metadata_dict)
# reopen the file handle
file_handle.seek(0, os.SEEK_SET)
# get an iterable xml parser context
xml_parser_context = ElementTree.iterparse(file_handle, events=('start', 'end'))
# turn it into an iterator
xml_parser_context = iter(xml_parser_context)
# get the root element
xml_event, xml_root = xml_parser_context.next()
for xml_event, xml_elem in xml_parser_context:
if xml_event == 'end':
# ... process activities ...
if xml_elem.tag == 'activity':
activity_dict_list = self.element_to_dict(xml_elem).pop('activity')
event_objects = self.parse_activity(merge_list_of_dicts_to_dict(activity_dict_list))
parser_context.ProduceEvents(event_objects, parser_chain=parser_chain, file_entry=file_entry)
xml_root.clear()
finally:
if file_handle is not None:
file_handle.close()
def parse_activity(self, activity_dict_merged):
""" Takes a dictionary resembling an arbitrary activity and parses all fields in a recursive manner in order
to process nested activities as well as ordinary leaf values.
The following cases are currently handled:
- Nested and split activities may occur as a list of dictionaries, as long as each activity dict contains
an 'activityType'
- Nested activities are allowed to occur under arbitrary key values
- EventObjects are constructed using reflective access to the event class, i.e. each occurring 'activityType' must
be mapped via 'activity_type_to_class_dict' and the mapped class must have a constructor that can handle the
parsing process of a single flat activity using a dict.
- If there is no mapping of an occurring 'activityType' within 'activity_type_to_class_dict', a BaseActivityEvent
will be constructed instead.
- Leaf values that do not represent an entire Activity will not be modified but instead passed as constructor
argument to the corresponding EventObject implementation.
:param activity_dict_merged: an arbitrary activity as dictionary, conforming to a certain 'activityType'.
:return: a list of EventObjects that could be parsed from the given dictionary, corresponding to the
value of 'activityType', if possible. Otherwise, either an empty list, in case the given dict does not
contain a valid activity, or None, in case the given argument is not a dict, will be returned.
"""
if activity_dict_merged is None:
return None
event_objects = list()
if isinstance(activity_dict_merged, list):
for v in activity_dict_merged:
if isinstance(v, dict) and 'activityType' in v:
if len(v) == 1:
# It is safe to assume that this is a nested and split activity. Therefore break the loop
# and parse it. This assumption does no longer hold true in case of a scenario where
# an activity_dict_list contains both, a split activity and another nested activity_dict.
# Currently the xml parser handles this case by wrapping the nested activity_dict in another
# list.
return self.parse_activity(merge_list_of_dicts_to_dict(activity_dict_merged))
else:
# this is a nested activity, parse and save objects
child_evt_objs = self.parse_activity(v)
if child_evt_objs is not None:
for e in child_evt_objs:
if isinstance(e, event.EventObject):
event_objects += [e]
else:
event_objects += self.parse_activity(v)
return event_objects
# is it a leaf value or an actual activity?
if not isinstance(activity_dict_merged, dict):
return None
# it is at least a dict, however, is it an activity or a value?
activity_type = activity_dict_merged.get('activityType', None)
if activity_type is not None: # it is an activity
event_object_class = activity_type_to_class_dict.get(activity_type, BaseActivityEvent)
event_objects = [event_object_class(activity_dict_merged)] # TODO check whether it is an actual class
# everything that remains may be another activity or an unconsumed leaf value
for k, v in activity_dict_merged.items():
child_evt_objs = self.parse_activity(v)
# currently, the key attribute is not used -> TODO: find a way to link the child-events to its parent?
if child_evt_objs is not None:
for e in child_evt_objs:
if isinstance(e, event.EventObject):
event_objects += [e]
return event_objects
def parse_timestamp_events(self, activity_dict):
""" Takes a dictionary of dictionaries that must contain at least two keys:
- 'startInstant', a dictionary that corresponds to a serialized Java Instant object
- 'endInstant', as above
This method will produce a dictionary consisting of either one or two JavaInstantEvent objects.
:param activity_dict: containing the 'startInstant' and 'endInstant' dictionaries
:return: either one, iff 'startInstant' == 'endInstant', or two JavaInstantEvent-objects inside a dictionary.
"""
start_instant_dict = merge_list_of_dicts_to_dict(activity_dict.get('startInstant', None))
end_instant_dict = merge_list_of_dicts_to_dict(activity_dict.get('endInstant', None))
if start_instant_dict != end_instant_dict:
instant_dict = dict(startInstant=None, endInstant=None)
# interval
start_instant_evt = JavaInstantEvent.from_java_instant_dict(start_instant_dict,
EventTimestamp.FIRST_CONNECTED)
end_instant_evt = JavaInstantEvent.from_java_instant_dict(end_instant_dict,
EventTimestamp.LAST_CONNECTED)
instant_dict['startInstant'] = start_instant_evt
instant_dict['endInstant'] = end_instant_evt
return instant_dict
else:
return dict(startInstant=JavaInstantEvent.from_java_instant_dict(start_instant_dict, u'Pcap time stamp'))
def element_to_dict(self, elem):
""" Internal method to transform a XML node to a dictionary.
:param elem: the XML node
:return: a dictionary containing the values below 'elem', using 'elem.tag' as respective keys
"""
return {elem.tag: map(self.element_to_dict, list(elem)) or elem.text}
def validate_metadata(self, rubanetra_metadata_dict):
""" Tries to verify that the parsed XML document corresponds to a known version to prevent potential
issues due to version incompatibility. An exception will be raised if such a case is encountered.
:param rubanetra_metadata_dict: a dictionary containing the basic Rubanetra metadata values
"""
if rubanetra_metadata_dict.get('implementationTitle') != u'Rubanetra':
raise errors.UnableToParseFile(u'Unknown Rubanetra implementation title encountered.')
version = rubanetra_metadata_dict.get('implementationVersion')
if version != self.VERSION:
logging.warning(u'Rubanetra version number mismatch, expected:{0:s}, actual:{1:s}'.format(self.VERSION, version))
def link_activity(self, event_object_from, event_object_to):
""" This method is currently unused, however, in case it is necessary to group multiple events,
a link between those events must be established. Whether a backtracking chain or a forward-chain should be
established depends entirely on the caller.
Currently, the UUID of 'event_object_to' will be appended to the list 'related_activity_uuids' of
'event_object_from'.
"""
if isinstance(event_object_to, BaseActivityEvent):
event_object_from.related_activity_uuids.append(event_object_to.uuid)
# TODO: else error
class BaseActivityEvent(event.EventObject):
def __init__(self, activity_dict,
data_type='java:rubanetra:base_activity'):
"""Initializes the base event object.
Args:
activity_dict: A dictionary containing all related BaseActivity key/value pairs.
"""
super(BaseActivityEvent, self).__init__()
if activity_dict is None:
raise errors.UnableToParseFile
self.data_type = data_type
self.activity_type = activity_dict.pop('activityType', 'BaseActivity')
self.description = activity_dict.pop('description', None)
compound_frame_number_dict_list = activity_dict.pop('compoundFrameNumbers', None)
self.compound_frame_number_list = list()
if compound_frame_number_dict_list is not None:
for d in compound_frame_number_dict_list:
for k, v in d.items():
self.compound_frame_number_list.append(long(v)) # TODO checks
self.optional_field_dict = merge_list_of_dicts_to_dict(activity_dict.pop('optionalFields', None))
self.replaced = string_to_boolean(activity_dict.pop('replaced', None))
self.source_address = activity_dict.pop('sourceAddressAsString', None)
self.destination_address = activity_dict.pop('destinationAddressAsString', None)
start_instant_dict = merge_list_of_dicts_to_dict(activity_dict.get('startInstant', None))
end_instant_dict = merge_list_of_dicts_to_dict(activity_dict.get('endInstant', None))
start_instant_evt = None
if start_instant_dict != end_instant_dict:
start_instant_evt = JavaInstantEvent.from_java_instant_dict(start_instant_dict,
EventTimestamp.FIRST_CONNECTED)
# interval
end_instant_evt = JavaInstantEvent.from_java_instant_dict(end_instant_dict,
EventTimestamp.LAST_CONNECTED)
self.last_timestamp = end_instant_evt.timestamp if end_instant_evt is not None else None
else:
start_instant_evt = JavaInstantEvent.from_java_instant_dict(start_instant_dict, u'Pcap time stamp')
self.timestamp = self.first_timestamp = start_instant_evt.timestamp if start_instant_evt is not None else None
self.timestamp_desc = start_instant_evt.timestamp_desc
self.related_activity_uuids = list()
class PcapActivityEvent(BaseActivityEvent):
def __init__(self, pcap_activity_dict):
super(PcapActivityEvent, self).__init__(pcap_activity_dict,
data_type='java:rubanetra:pcap_activity')
pcap_packet = merge_list_of_dicts_to_dict(pcap_activity_dict.pop('pcapPacket', None))
if pcap_packet is not None:
self.pcap_total_size = pcap_packet.pop('totalSize', None)
self.pcap_frame_number = pcap_packet.pop('frameNumber', None)
self.pcap_packet_wirelen = pcap_packet.pop('packetWirelen', None)
self.pcap_header_count = pcap_packet.pop('headerCount', None)
class HttpRequestActivityEvent(BaseActivityEvent):
def __init__(self, http_request_activity_dict):
super(HttpRequestActivityEvent, self).__init__(http_request_activity_dict,
data_type='java:rubanetra:http_request_activity')
self.http_version = http_request_activity_dict.pop('httpVersion', None)
self.server_address = http_request_activity_dict.pop('serverAddress', None)
self.client_address = http_request_activity_dict.pop('clientAddress', None)
self.http_method = http_request_activity_dict.pop('httpMethod', None)
self.http_query_string = http_request_activity_dict.pop('httpQueryString', None)
self.http_query_parameters = http_request_activity_dict.pop('httpQueryParameters', None)
self.http_request_header_dict = http_request_activity_dict.pop('requestHeaderMap', None)
self.url = http_request_activity_dict.pop('url', None)
http_request = merge_list_of_dicts_to_dict(http_request_activity_dict.pop('httpRequest', None))
if http_request is not None:
self.orig_http_header = http_request.pop('header', None)
self.content_type = http_request.pop('contentType', None)
self.is_response = http_request.pop('response', None)
self.jnetpcap_http_string = http_request.pop('JNetPcap-HTTP-String', None)
self.source_address = self.client_address
self.destination_address = self.server_address
class HttpResponseActivityEvent(BaseActivityEvent):
def __init__(self, http_response_activity_dict):
super(HttpResponseActivityEvent, self).__init__(http_response_activity_dict,
data_type='java:rubanetra:http_response_activity')
self.http_version = http_response_activity_dict.pop('httpVersion', None)
self.response_status_code = http_response_activity_dict.pop('responseStatusCode', None)
self.response_status_line = http_response_activity_dict.pop('responseStatusLine', None)
self.response_header_dict = http_response_activity_dict.pop('responseHeaderMap', None)
http_response = merge_list_of_dicts_to_dict(http_response_activity_dict.pop('httpResponse', None))
if http_response is not None:
self.orig_http_header = http_response.pop('header', None)
self.content_type = http_response.pop('contentType', None)
self.is_response = http_response.pop('response', None)
self.jnetpcap_http_string = http_response.pop('JNetPcap-HTTP-String', None)
class HttpImageActivityEvent(BaseActivityEvent):
def __init__(self, http_image_activity_dict):
super(HttpImageActivityEvent, self).__init__(http_image_activity_dict,
data_type='java:rubanetra:http_image_activity')
self.image_type = http_image_activity_dict.pop('imageType', None)
self.image_path = http_image_activity_dict.pop('imagePath', None)
class DnsActivityEvent(BaseActivityEvent):
def __init__(self, dns_activity_dict):
super(DnsActivityEvent, self).__init__(dns_activity_dict,
data_type='java:rubanetra:dns_activity')
self.question_record_list = dns_activity_dict.pop('questionRecords', None)
self.answer_record_list = dns_activity_dict.pop('answerRecords', None)
self.authority_record_list = dns_activity_dict.pop('authorityRecords', None)
self.additional_record_list = dns_activity_dict.pop('additionalRecords', None)
self.dns_message_header = merge_list_of_dicts_to_dict(dns_activity_dict.pop('dnsMessageHeader', None))
self.is_response_bool = string_to_boolean(dns_activity_dict.pop('response', None))
class ArpActivityEvent(BaseActivityEvent):
def __init__(self, arp_activity_dict):
super(ArpActivityEvent, self).__init__(arp_activity_dict,
data_type='java:rubanetra:arp_activity')
self.hardware_type = arp_activity_dict.pop('hardwareType', None)
self.protocol_type = arp_activity_dict.pop('protocolType', None)
self.hardware_address_length = arp_activity_dict.pop('hardwareAddressLength', None)
self.protocol_address_length = arp_activity_dict.pop('protocolAddressLength', None)
self.sender_mac_address = arp_activity_dict.pop('senderHardwareAddress', None)
self.target_mac_address = arp_activity_dict.pop('targetHardwareAddress', None)
self.sender_protocol_address = arp_activity_dict.pop('senderProtocolAddress', None)
self.target_protocol_address = arp_activity_dict.pop('targetProtocolAddress', None)
self.jnetpcap_arp = arp_activity_dict.pop('arp', None)
class DhcpActivityEvent(BaseActivityEvent):
def __init__(self, dhcp_activity_dict):
super(DhcpActivityEvent, self).__init__(dhcp_activity_dict,
data_type='java:rubanetra:dhcp_activity')
self.dhcp_message = dhcp_activity_dict.pop('dhcpMessage', None)
class EthernetActivityEvent(BaseActivityEvent):
def __init__(self, ethernet_activity_dict):
super(EthernetActivityEvent, self).__init__(ethernet_activity_dict,
data_type='java:rubanetra:ethernet_activity')
self.source_mac_address = ethernet_activity_dict.pop('sourceMacAddress', None)
self.destination_mac_address = ethernet_activity_dict.pop('destinationMacAddress', None)
self.ethernet_type = ethernet_activity_dict.pop('ethernetType', None)
self.ethernet_type_enum = ethernet_activity_dict.pop('ethernetTypeEnum', None)
self.jnetpcap_ethernet = ethernet_activity_dict.pop('ethernet', None)
class FtpActivityEvent(BaseActivityEvent):
def __init__(self, ftp_activity_dict):
super(FtpActivityEvent, self).__init__(ftp_activity_dict,
data_type='java:rubanetra:ftp_activity')
self.ftp_type = ftp_activity_dict.pop('ftpActivityType', None)
self.command = ftp_activity_dict.pop('command', None)
self.reply = ftp_activity_dict.pop('reply', None)
self.list = ftp_activity_dict.pop('list', None)
class Icmpv4ActivityEvent(BaseActivityEvent):
def __init__(self, icmpv4_activity_dict):
super(Icmpv4ActivityEvent, self).__init__(icmpv4_activity_dict,
data_type='java:rubanetra:icmpv4_activity')
self.icmp_subtype = icmpv4_activity_dict.pop('icmpSubType', None)
self.icmp_packet = icmpv4_activity_dict.pop('icmpPacket', None)
self.icmp_message = icmpv4_activity_dict.pop('icmpMessage', None)
self.icmp_type = icmpv4_activity_dict.pop('icmpType', None)
self.icmp_code = icmpv4_activity_dict.pop('icmpCode', None)
self.source_address = icmpv4_activity_dict.pop('sourceAddress', None)
self.destination_address = icmpv4_activity_dict.pop('destinationAddress', None)
self.identifier = icmpv4_activity_dict.pop('identifier', None)
self.sequence = icmpv4_activity_dict.pop('sequence', None)
self.jnetpcap_icmp = icmpv4_activity_dict.pop('icmp', None)
class Icmpv6ActivityEvent(BaseActivityEvent):
def __init__(self, icmpv6_activity_dict):
super(Icmpv6ActivityEvent, self).__init__(icmpv6_activity_dict,
data_type='java:rubanetra:icmpv6_activity')
self.icmp_subtype = icmpv6_activity_dict.pop('icmpSubType', None)
self.icmp_packet = icmpv6_activity_dict.pop('icmpPacket', None)
self.icmp_message = icmpv6_activity_dict.pop('icmpMessage', None)
self.icmp_type = icmpv6_activity_dict.pop('icmpType', None)
self.jnetpcap_icmp = icmpv6_activity_dict.pop('icmp', None)
class IpActivityEvent(BaseActivityEvent):
def __init__(self, ip_activity_dict):
super(IpActivityEvent, self).__init__(ip_activity_dict,
data_type='java:rubanetra:ip_activity')
self.version = ip_activity_dict.pop('version', None)
self.protocol = ip_activity_dict.pop('protocol', None)
self.source_address = ip_activity_dict.pop('sourceAddress', None)
self.destination_address = ip_activity_dict.pop('destinationAddress', None)
class Ipv4ActivityEvent(BaseActivityEvent):
def __init__(self, ip_activity_dict):
super(Ipv4ActivityEvent, self).__init__(ip_activity_dict,
data_type='java:rubanetra:ipv4_activity')
self.internet_header_length = ip_activity_dict.pop('internetHeaderLength', None)
self.differentiated_services_code_point = ip_activity_dict.pop('differentiatedServicesCodePoint', None)
self.total_length = ip_activity_dict.pop('totalLength', None)
self.identification = ip_activity_dict.pop('identification', None)
self.flags = ip_activity_dict.pop('flags', None)
self.fragment_offset = ip_activity_dict.pop('fragmentOffset', None)
self.time_to_live = ip_activity_dict.pop('timeToLive', None)
self.header_checksum = ip_activity_dict.pop('headerChecksum', None)
self.options = ip_activity_dict.pop('options', None)
self.jnetpcap_ip4 = ip_activity_dict.pop('ipv4', None)
class Ipv6ActivityEvent(BaseActivityEvent):
def __init__(self, ip_activity_dict):
super(Ipv6ActivityEvent, self).__init__(ip_activity_dict,
data_type='java:rubanetra:ipv6_activity')
self.traffic_class = ip_activity_dict.pop('trafficClass', None)
self.flow_label = ip_activity_dict.pop('flowLabel', None)
self.payload_length = ip_activity_dict.pop('payloadLength', None)
self.next_header = ip_activity_dict.pop('nextHeader', None)
self.hop_limit = ip_activity_dict.pop('hopLimit', None)
self.jnetpcap_ip6 = ip_activity_dict.pop('ipv6', None)
self.kraken_ip6 = ip_activity_dict.pop('ipv6Packet', None)
class MsnActivityEvent(BaseActivityEvent):
def __init__(self, activity_dict):
super(MsnActivityEvent, self).__init__(activity_dict,
data_type='java:rubanetra:msn_activity')
self.account = activity_dict.pop('account', None)
self.chat = activity_dict.pop('chat', None)
class NetbiosActivityEvent(BaseActivityEvent):
def __init__(self, activity_dict):
super(NetbiosActivityEvent, self).__init__(activity_dict,
data_type='java:rubanetra:netbios_activity')
self.datagram_packet = activity_dict.pop('datagramPacket', None)
self.name_packet = activity_dict.pop('namePacket', None)
class Pop3ActivityEvent(BaseActivityEvent):
def __init__(self, activity_dict):
super(Pop3ActivityEvent, self).__init__(activity_dict,
data_type='java:rubanetra:pop3_activity')
self.sub_type = activity_dict.pop('subType', None)
self.header = activity_dict.pop('header', None)
self.data = activity_dict.pop('data', None)
self.command = activity_dict.pop('command', None)
self.response = activity_dict.pop('response', None)
class SmtpCommandActivityEvent(BaseActivityEvent):
def __init__(self, activity_dict):
super(SmtpCommandActivityEvent, self).__init__(activity_dict,
data_type='java:rubanetra:smtp_command_activity')
self.command = activity_dict.pop('command', None)
self.parameter = activity_dict.pop('parameter', None)
class SmtpReplyActivityEvent(BaseActivityEvent):
def __init__(self, activity_dict):
super(SmtpReplyActivityEvent, self).__init__(activity_dict,
data_type='java:rubanetra:smtp_reply_activity')
self.code = activity_dict.pop('code', None)
self.message = activity_dict.pop('message', None)
class SmtpSendActivityEvent(BaseActivityEvent):
def __init__(self, activity_dict):
super(SmtpSendActivityEvent, self).__init__(activity_dict,
data_type='java:rubanetra:smtp_send_activity')
self.header = activity_dict.pop('header', None)
self.data = activity_dict.pop('data', None)
class Snmpv1ActivityEvent(BaseActivityEvent):
def __init__(self, activity_dict):
super(Snmpv1ActivityEvent, self).__init__(activity_dict,
data_type='java:rubanetra:snmpv1_activity')
self.pdu = activity_dict.pop('pdu', None)
self.source_socket_address = activity_dict.pop('sourceSocketAddress', None)
self.destination_socket_address = activity_dict.pop('destinationSocketAddress', None)
class Snmpv2ActivityEvent(BaseActivityEvent):
def __init__(self, activity_dict):
super(Snmpv2ActivityEvent, self).__init__(activity_dict,
data_type='java:rubanetra:snmpv2_activity')
self.pdu = activity_dict.pop('pdu', None)
self.source_socket_address = activity_dict.pop('sourceSocketAddress', None)
self.destination_socket_address = activity_dict.pop('destinationSocketAddress', None)
class TcpActivityEvent(BaseActivityEvent):
def __init__(self, activity_dict):
super(TcpActivityEvent, self).__init__(activity_dict,
data_type='java:rubanetra:tcp_activity')
self.source_port = activity_dict.pop('sourcePort', None)
self.destination_port = activity_dict.pop('destinationPort', None)
self.sequence_number = activity_dict.pop('sequenceNumber', None)
self.acknowledge_number = activity_dict.pop('acknowledgeNumber', None)
self.relative_sequence_number = activity_dict.pop('relativeSequenceNumber', None)
self.relative_acknowledge_number = activity_dict.pop('relativeAcknowledgeNumber', None)
self.data_offset = activity_dict.pop('dataOffset', None)
self.control_bits = activity_dict.pop('controlBits', None)
self.window_size = activity_dict.pop('windowSize', None)
self.checksum = activity_dict.pop('checksum', None)
self.urgent_pointer = activity_dict.pop('urgentPointer', None)
self.tcp_length = activity_dict.pop('tcpLength', None)
self.options = activity_dict.pop('options', None)
self.padding = activity_dict.pop('padding', None)
self.syn = activity_dict.pop('syn', None)
self.ack = activity_dict.pop('ack', None)
self.psh = activity_dict.pop('psh', None)
self.fin = activity_dict.pop('fin', None)
self.rst = activity_dict.pop('rst', None)
self.urg = activity_dict.pop('urg', None)
self.direction = activity_dict.pop('direction', None)
self.client_state = activity_dict.pop('clientState', None)
self.server_state = activity_dict.pop('serverState', None)
self.jnetpcap_tcp = activity_dict.pop('tcp', None)
self.source_address = activity_dict.pop('sourceAddress', None)
self.destination_address = activity_dict.pop('destinationAddress', None)
self.source_socket_address = activity_dict.pop('sourceSocketAddress', None)
self.destination_socket_address = activity_dict.pop('destinationSocketAddress', None)
class TelnetActivityEvent(BaseActivityEvent):
def __init__(self, activity_dict):
super(TelnetActivityEvent, self).__init__(activity_dict,
data_type='java:rubanetra:telnet_activity')
self.sub_type = activity_dict.pop('subType', None)
self.command = activity_dict.pop('command', None)
self.option = activity_dict.pop('option', None)
self.ansi_mode = activity_dict.pop('ansiMode', None)
self.arguments = activity_dict.pop('arguments', None)
self.text = activity_dict.pop('text', None)
self.title = activity_dict.pop('title', None)
class TlsActivityEvent(BaseActivityEvent):
def __init__(self, activity_dict):
super(TlsActivityEvent, self).__init__(activity_dict,
data_type='java:rubanetra:tls_activity')
self.client_to_server_traffic = activity_dict.pop('clientToServerTraffic', None)
self.server_to_client_traffic = activity_dict.pop('serverToClientTraffic', None)
class UdpActivityEvent(BaseActivityEvent):
def __init__(self, activity_dict):
super(UdpActivityEvent, self).__init__(activity_dict,
data_type='java:rubanetra:udp_activity')
self.source_port = activity_dict.pop('sourcePort', None)
self.destination_port = activity_dict.pop('destinationPort', None)
self.length = activity_dict.pop('length', None)
self.checksum = activity_dict.pop('checksum', None)
self.jnetpcap_udp = activity_dict.pop('udp', None)
self.source_socket_address = activity_dict.pop('sourceSocketAddress', None)
self.destination_socket_address = activity_dict.pop('destinationSocketAddress', None)
class OpenSSHActivityEvent(BaseActivityEvent):
def __init__(self, activity_dict):
super(OpenSSHActivityEvent, self).__init__(activity_dict,
data_type='java:rubanetra:open_ssh_activity')
self.client_to_server_traffic = activity_dict.pop('clientToServerTraffic', None)
self.server_to_client_traffic = activity_dict.pop('serverToClientTraffic', None)
class DropboxTlsActivityEvent(BaseActivityEvent):
def __init__(self, activity_dict):
super(DropboxTlsActivityEvent, self).__init__(activity_dict,
data_type='java:rubanetra:dropbox_tls_activity')
self.client_address = activity_dict.pop('clientAddress', None)
self.server_address = activity_dict.pop('serverAddress', None)
class SpiderOakActivityEvent(BaseActivityEvent):
def __init__(self, activity_dict):
super(SpiderOakActivityEvent, self).__init__(activity_dict,
data_type='java:rubanetra:spideroak_activity')
self.client_address = activity_dict.pop('clientAddress', None)
self.server_address = activity_dict.pop('serverAddress', None)
class SkypePayloadActivityEvent(BaseActivityEvent):
def __init__(self, activity_dict):
super(SkypePayloadActivityEvent, self).__init__(activity_dict,
data_type='java:rubanetra:skype_payload_activity')
self.source_object_id = activity_dict.pop('sourceObjectId', None)
self.destination_object_id = activity_dict.pop('destinationObjectId', None)
self.source_host = activity_dict.pop('sourceHost', None)
self.destination_host = activity_dict.pop('destinationHost', None)
class JavaInstantEvent(TimestampEvent):
"""Convenience class for a Java Instant-based event."""
def __init__(self, instant_epoch_seconds, instant_nano, usage, data_type='java:time:Instant'):
"""Initializes a Java instant-based event object.
Args:
java_java_instant_epoch_seconds: The Java epoch seconds value (long).
java_java_instant_nano: The Java nano seconds value (long), will be reduced to microsecond precision.
usage: The description of the usage of the instant value.
data_type: The event data type. If not set data_type is derived
from DATA_TYPE.
"""
super(JavaInstantEvent, self).__init__(
timelib.Timestamp.FromPosixTimeWithMicrosecond(instant_epoch_seconds, instant_nano / 1000),
usage, data_type)
self.instant_epoch_seconds = instant_epoch_seconds
self.instant_nano = instant_nano
self.related_activity_uuids = list()
@classmethod
def from_java_instant_dict(cls, java_instant_as_dict, usage, data_type='java:time:Instant'):
# TODO: validate fields
instant_epoch_seconds = long(java_instant_as_dict.pop('epochSecond', -1))
instant_nano = long(java_instant_as_dict.pop('nano', -1))
return cls(instant_epoch_seconds, instant_nano, usage, data_type)
""" FIXME: This method is ineffective for now, because
it is apparently not possible to specify a filter expression that
is based on a boolean value.
"""
def string_to_boolean(s):
""" Returns true, iff s.lower() in ('true', '1')
:param s: a String representation of a boolean value
:return:true, iff s.lower() in ('true', '1'), false otherwise
"""
#return s.lower() in ('true', '1')
return s
def merge_list_of_dicts_to_dict(list_of_dicts):
""" Takes a list of dictionaries and transforms it to a flat dictionary, overwriting duplicate keys in the process.
:param list_of_dicts: a list of dictionaries
:return: a flat dictionary containing the keys and values of all dictionaries that were previously located inside the
list. If two dictionaries contained the same key, the mapping of the last dictionary that contained that key
will be included, while the older value is discarded.
"""
if list_of_dicts is None or not isinstance(list_of_dicts, list) or isinstance(list_of_dicts, dict):
return list_of_dicts
return {k: v for d in list_of_dicts for k, v in d.items()}
# A dictionary of 'activityType' to class mappings.
activity_type_to_class_dict = {
'ArpActivity': ArpActivityEvent,
'DhcpActivity': DhcpActivityEvent,
'DnsActivity': DnsActivityEvent,
'EthernetActivity': EthernetActivityEvent,
'FtpActivity': FtpActivityEvent,
'HttpImageActivity': HttpImageActivityEvent,
'HttpRequestActivity': HttpRequestActivityEvent,
'HttpResponseActivity': HttpResponseActivityEvent,
'Icmpv4Activity': Icmpv4ActivityEvent,
'Icmpv6Activity': Icmpv6ActivityEvent,
'IpActivity': IpActivityEvent,
'Ipv4Activity': Ipv4ActivityEvent,
'Ipv6Activity': Ipv6ActivityEvent,
'MsnActivity': MsnActivityEvent,
'NetbiosActivity': NetbiosActivityEvent,
'PcapActivity': PcapActivityEvent,
'Pop3Activity': Pop3ActivityEvent,
'SmtpCommandActivity': SmtpCommandActivityEvent,
'SmtpReplyActivity': SmtpReplyActivityEvent,
'SmtpSendActivity': SmtpSendActivityEvent,
'TcpActivity': TcpActivityEvent,
'TelnetActivity': TelnetActivityEvent,
'TlsActivity': TlsActivityEvent,
'UdpActivity': UdpActivityEvent,
'OpenSSHActivity': OpenSSHActivityEvent,
'DropboxTlsActivity': DropboxTlsActivityEvent,
'SpiderOakActivity': SpiderOakActivityEvent,
'SkypePayloadActivity': SkypePayloadActivityEvent}
manager.ParsersManager.RegisterParser(RubanetraXmlParser)