def determine_directives(context): if context.section == "destination": return # Find out which Shadowserver configuaration shall be used. # Usually the feed.name is set by the parser of the shadowserver data. shadowserver_params = shadowserver_mapping.get(context.get("feed.name")) if shadowserver_params is not None: # This Script does only handle the feeds, that can be determined by the # configuration in the shadowserver_mapping dict below. # Have a look at the much more sophisticated 51avalanche.py # to find out more about different kinds of configuration possibilities, # such as annotations, or "matches". # TODO This way of generating directives is most likely underdesigned, # as a more sophisticated way, like in 51avalanche.py is usually required for contact in context.all_contacts(): directive = Directive.from_contact(contact) directive.update(shadowserver_params) directive.aggregate_by_field(context.section + ".asn") directive.aggregate_by_field("time.observation") # A simple example to add a group indicator for later stats if "water@example" in directive.recipient_address: directive.aggregate_key["recipient_group"] = "CNI_water" context.add_directive(directive) return True return
def determine_directives(context): if context.section == "destination": return directive_set = False for org in context.organisations: if any(annotation.tag == "xarf" for annotation in org.annotations): context.logger.debug("Create X-ARF Directive") context.logger.debug(org.contacts) for contact in org.contacts: directive = Directive.from_contact(contact) directive.update(xarf_settings) context.add_directive(directive) directive_set = True return directive_set
def evaluate_match(context, match): # For demonstration purposes, log some of the information available # for decisions here # 1) If a match for a FQDN exists, if match.field == "fqdn": context.logger.debug("Specific FQDN-Match: %r", match) # 2) If a match for an IP exist. # If an IP-Match exists, the Networks Address is written into # the match as "address" if match.field == "ip": context.logger.debug("Specific IP-Match: %r for Network %s", match, match.address) # 3) If a match for an ASN exist, if match.field == "asn": context.logger.debug("Specific ASN-Match: %r", match) # 4) If a match for a CountryCode exists (indicating a national cert), if match.field == "geolocation.cc": context.logger.debug("Specific Geolocation-Match: %r", match) # You could also check how the match was managed here: # for instance: if match.managed == "automatic" # Let's have a look at the Organisations associated to this match: for org in context.organisations_for_match(match): # Determine the Annotations for this Org. org_annotations = org.annotations context.logger.debug("Org Annotations: %r" % org_annotations) is_government = False is_critical = False for annotation in org_annotations: if annotation.tag == "government": is_government = True if annotation.tag == "critical": is_critical = True # Now create the Directives # # An organisation may have multiple contacts, so we need to # iterate over them. In many cases this will only loop once as # many organisations will have only one. for contact in org.contacts: directive = Directive.from_contact(contact) # Doing this defines "email" as medium and uses the # contact's email attribute as the recipient_address. # One could also do this by hand, see Directive in # intelmq.bots.experts.certbund_contact.rulesupport # If you like to know more details # Now fill in more details of the directive, depending on # the annotations of the directive and/or the type of the # match if is_critical: directive.update(constituency_contact_directive()) directive.aggregate_key["cidr"] = match.address context.add_directive(directive) elif is_government: directive.update(constituency_contact_directive()) directive.aggregate_key["cidr"] = match.address context.add_directive(directive) elif match.field == "geolocation.cc": # We know the National CERT that is responsible in this case directive.update(cert_contact_directive()) # Aggregate by Geolocation. directive.aggregate_by_field(context.section + ".geolocation.cc") context.add_directive(directive) else: directive.update(provider_contact_directive()) directive.aggregate_by_field(context.section + ".asn") context.add_directive(directive)
def add_matter_directives_to_context(context, match, matter): # This is Copy and Paste from 51avalanche.py, with some # minor edits # Let's have a look at the Organisations associated to this match: for org in context.organisations_for_match(match): # Determine the Annotations for this Org. org_annotations = org.annotations context.logger.debug("Org Annotations: %r" % org_annotations) is_government = False is_critical = False for annotation in org_annotations: if annotation.tag == GOVERNMENT_ANNOTATION: is_government = True if annotation.tag == CRITICAL_ANNOTATION: is_critical = True # Now create the Directives # # An organisation may have multiple contacts, so we need to # iterate over them. In many cases this will only loop once as # many organisations will have only one. for contact in org.contacts: directive = Directive.from_contact(contact) # Doing this defines "email" as medium and uses the # contact's email attribute as the recipient_address. # One could also do this by hand, see Directive in # intelmq.bots.experts.certbund_contact.rulesupport # If you like to know more details # Now fill in more details of the directive, depending on # the annotations of the directive and/or the type of the # match if is_critical: d = create_directive(notification_format=matter, target_group="constituency", interval=3600, data_format=matter + "_csv_attachment") directive.update(d) if matter in SPECIAL_MATTERS: # Add the observation time as an aggregation identifier, # in order to cluster all events from the same report-batch. # But only do so for those Events which have not been associated # to the generic malware-infection matter (see line 78) directive.aggregate_by_field("time.observation") # Always aggregate by the network directive.aggregate_key["cidr"] = match.address context.add_directive(directive) elif is_government: d = create_directive(notification_format=matter, target_group="constituency", interval=3600, data_format=matter + "_csv_attachment") directive.update(d) if matter in SPECIAL_MATTERS: # Add the observation time as an aggregation identifier, # in order to cluster all events from the same report-batch. # But only do so for those Events which have not been associated # to the generic malware-infection matter (see line 78) directive.aggregate_by_field("time.observation") # Always aggregate by the network directive.aggregate_key["cidr"] = match.address context.add_directive(directive) elif match.field == "geolocation.cc": if matter not in SPECIAL_MATTERS: # Do NOT send malware-infection events to CERTs pass else: # We know the National CERT that is responsible in this case d = create_directive(notification_format=matter, target_group="certs", interval=86400, data_format=matter + "_csv_attachment") directive.update(d) # Add the observation time as an aggregation identifier, # in order to cluster all events from the same report-batch. directive.aggregate_by_field("time.observation") # Aggregate by Geolocation. directive.aggregate_by_field(context.section + ".geolocation.cc") context.add_directive(directive) else: d = create_directive(notification_format=matter, target_group="provider", interval=86400, data_format=matter + "_csv_inline") directive.update(d) if matter in SPECIAL_MATTERS: # Add the observation time as an aggregation identifier, # in order to cluster all events from the same report-batch. # But only do so for those Events which have not been associated # to the generic malware-infection matter (see line 78) directive.aggregate_by_field("time.observation") # Always aggregate by ASN directive.aggregate_by_field(context.section + ".asn") context.add_directive(directive)