예제 #1
0
def _packet_from_pdml_packet(pdml_packet):
    layers = [Layer(proto) for proto in pdml_packet.proto]
    geninfo, frame, layers = layers[0], layers[1], layers[2:]
    return Packet(layers=layers, frame_info=frame, number=geninfo.get_field_value('num'),
                  length=geninfo.get_field_value('len'), sniff_time=geninfo.get_field_value('timestamp', raw=True),
                  captured_length=geninfo.get_field_value('caplen'),
                  interface_captured=frame.get_field_value('interface_id', raw=True))
예제 #2
0
def packet_from_xml_packet(xml_pkt):
    """
    Gets a TShark XML packet object or string, and returns a pyshark Packet objec.t

    :param xml_pkt: str or xml object.
    :return: Packet object.
    """
    if not isinstance(xml_pkt, lxml.objectify.ObjectifiedElement):
        xml_pkt = lxml.objectify.fromstring(xml_pkt)
    layers = [Layer(proto) for proto in xml_pkt.proto]
    geninfo, frame, layers = layers[0], layers[1], layers[2:]
    frame.raw_mode = True
    return Packet(layers=layers,
                  length=geninfo.get_field_value('len'),
                  sniff_time=geninfo.get_field_value('timestamp', raw=True),
                  captured_length=geninfo.get_field_value('caplen'),
                  interface_captured=frame.get_field_value('interface_id'))
예제 #3
0
    def _get_layer_dict(layer: Layer) -> (dict, dict):
        """
        TODO: Manage Tags
        :param layer: The layer to process
        :return: The dictionary of layer, The dictionary of src and dest ip/mac (looked up)
        """

        field_tree = dict()  # tree dict { name => pkt }

        def update_field_tree_keys(local_field_tree_keys: list) -> (list, dict):
            """
            Insert into the field_tree the input keys recursively
            Eg. local_field_tree_keys = ['a', 'b', 'c']
                field_tree['a']['b']['c'] = dict()
            :param local_field_tree_keys: the dictionary keys used to create the parent dicts of field
            :return: The family (as list) and the node (as dict) of field to insert
            """
            local_field_node = field_tree
            local_field_tree_family = []
            for local_field_tree_key in local_field_tree_keys:
                local_field_tree_child = local_field_node.get(local_field_tree_key)
                if local_field_tree_child is None:
                    local_field_tree_child = dict()
                    local_field_node[local_field_tree_key] = local_field_tree_child
                local_field_tree_family.insert(0, local_field_tree_child)
                local_field_node = local_field_tree_child
            return local_field_tree_family, local_field_node

        pcap_layer_field_root = PcapLayerField(sanitized_name='root')

        # noinspection PyProtectedMember
        def local_get_field_tree(local_field: LayerField) -> PcapLayerField:
            """
            :param local_field: The LayerField to insert in dict
            """
            try:
                parent_poss = (int(local_field.pos), int(local_field.pos) - int(local_field.size))
            except TypeError:
                parent_poss = ()
                local_field.pos = 0
                local_field.size = 0

            if local_field.name is None:
                local_field.name = ''

            field_tree_keys = local_field.name.split('.')
            family, node = update_field_tree_keys(field_tree_keys)

            def find_pcap_layer_field_parent(local_member: dict, only_hex: bool = False) -> PcapLayerField or None:
                """
                If exists, found the big brother of local_field, otherwise, the parent
                :param local_member: The family tree of local_field (as dict)
                :param only_hex: True if the member_parent of local_field should has an hexadecimal value
                :return: If exits, the big brother of local_field, otherwise, the parent or None
                """
                parent = None
                for key, member_parent in local_member.items():
                    member_parent: PcapLayerField or dict
                    if not only_hex and isinstance(member_parent, dict):
                        # Check brothers
                        member_brother = find_pcap_layer_field_parent(member_parent, True)
                        if member_brother is not None:
                            return member_brother  # brother
                    if key in parent_poss and member_parent.name != local_field.name:
                        member_parent: PcapLayerField
                        if not only_hex:
                            parent = member_parent  # parent (but the preferred is brother)
                        elif is_hex(member_parent.value) and \
                                member_parent.pos == int(local_field.pos) and \
                                not PcapSniffer._field_is_binary(member_parent):
                            return member_parent  # brother
                return parent

            pcap_layer_field_parent = None
            for member in family:
                pcap_layer_field_parent = find_pcap_layer_field_parent(member)
                if pcap_layer_field_parent is not None:
                    break

            if pcap_layer_field_parent is None:
                pcap_layer_field_parent = pcap_layer_field_root

            local_field_sanitized_name = layer._sanitize_field_name(local_field.name)
            local_pcap_layer_field = PcapLayerField(
                local_field,
                local_field_sanitized_name,
                pcap_layer_field_parent
            )
            node[int(local_field.pos)] = local_pcap_layer_field  # Update dictionary tree
            return local_pcap_layer_field

        source = {
            'mac': None,
            'mac_manufacturer': None,
            'mac_lookup': None,
            'ip': None,
            'ip_host': None,
            'port': None
        }
        destination = {
            'mac': None,
            'mac_manufacturer': None,
            'mac_lookup': None,
            'ip': None,
            'ip_host': None,
            'port': None
        }
        protocol = None

        field_insert = set()
        for field in layer._get_all_fields_with_alternates():
            field: LayerField
            if field.name in PcapLayerField.AMBIGUOUS_FIELD_NAMES:
                continue
            field_unique_key = str(field.pos) + '_' + str(field.name)
            if field_unique_key in field_insert:
                continue
            pcap_layer_field: PcapLayerField = local_get_field_tree(field)
            if pcap_layer_field is None:
                continue

            if pcap_layer_field.sanitized_name in PcapLayerField.PROTO_FIELDS:
                protocol = pcap_layer_field.value
            else:
                host = None
                if pcap_layer_field.sanitized_name in PcapLayerField.SRC_FIELDS:
                    host = source
                elif pcap_layer_field.sanitized_name in PcapLayerField.DST_FIELDS:
                    host = destination
                if host is not None:
                    if is_mac(pcap_layer_field.value):
                        mac_manufacturer_result = MacManufacturer.lookup(pcap_layer_field.value)
                        host['mac'] = pcap_layer_field.value
                        host['mac_manufacturer'] = mac_manufacturer_result.get('manufacturer')
                        # noinspection PyTypeChecker
                        host['mac_lookup'] = mac_manufacturer_result
                    elif is_ip(pcap_layer_field.value):
                        try:
                            host['ip'] = pcap_layer_field.value
                            host['ip_host'] = socket.gethostbyaddr(pcap_layer_field.value)[0]
                        except (socket.herror, socket.gaierror):
                            pass
                    elif is_int(pcap_layer_field.value):
                        # It's the port
                        host['port'] = pcap_layer_field.value

            field_insert.add(field_unique_key)

        return {
                   'name': layer.layer_name.upper(),
                   'fields': pcap_layer_field_root.get_dict().get('children')
               }, {
                   'source': source,
                   'destination': destination,
                   'protocol': protocol
               }