Example #1
0
def main(args):
    # for i in dir(stix2):
    #     print(i)
    # sys.exit(0)
    pathname = os.path.dirname(sys.argv[0])
    if len(sys.argv) > 3:
        namespace[0] = sys.argv[3]
    if len(sys.argv) > 4:
        namespace[1] = sys.argv[4].replace(" ", "_")
        namespace[1] = re.sub('[\W]+', '', namespace[1])
    misp = pymisp.MISPEvent(None, False)
    misp.load_file(os.path.join(pathname, args[1]))
    SDOs = []
    object_refs = []
    external_refs = []
    identity = setIdentity(misp, SDOs)
    attributes = readAttributes(misp, identity, object_refs, external_refs)
    buildRelationships(attributes, object_refs)
    report = eventReport(misp, identity, object_refs, external_refs)
    SDOs.append(report)
    for attribute in attributes:
        SDOs.append(attribute)
    stix_package = generateEventPackage(misp, SDOs)
    saveFile(args, pathname, stix_package)
    print(1)
Example #2
0
def main(args):
    pathname = os.path.dirname(sys.argv[0])
    if len(sys.argv) > 3:
        namespace[0] = sys.argv[3]
    if len(sys.argv) > 4:
        namespace[1] = sys.argv[4].replace(" ", "_")
        namespace[1] = re.sub('[\W]+', '', namespace[1])
    misp = pymisp.MISPEvent(None, False)
    misp.load_file(os.path.join(pathname, args[1]))
    SDOs = []
    object_refs = []
    external_refs = []
    identity = setIdentity(misp)
    SDOs.append(identity)
    attributes = readAttributes(misp, identity, object_refs, external_refs)
    buildRelationships(attributes, object_refs)
    report = eventReport(misp, identity, object_refs, external_refs)
    SDOs.append(report)
    for attribute in attributes:
        SDOs.append(attribute)
    stix_package = generateEventPackage(misp, SDOs)
    saveFile(args, pathname, stix_package)
    print(1)
    descFilename = os.path.join(pymisp.__path__[0], 'data/describeTypes.json')
    descFile = open(descFilename, 'r')
    types = json.loads(descFile.read())
    print(types)
Example #3
0
    def feyemisp(self, alert, desc="FireEye alert", domain=None, url=None):
        if not self.misp or (not domain and not url):
            return
        ev = pymisp.MISPEvent()
        desc = unprintable(desc).strip()

        event_template = '{"orgc_id": "1", "info": "' + desc + \
            '", "event_creator_email": "*****@*****.**", "locked": false, "Object": [], "Tag": [{"name": "FireEye"}, {"name": "EmailScanner"}], "Galaxy": [], "published": false, "distribution": "1", "proposal_email_lock": false, "threat_level_id": "2", "RelatedEvent": []}'
        att = []

        if domain:
            att.append({
                "category": "Network activity",
                "to_ids": True,
                "type": "domain",
                "value": domain,
                "comment": desc
            })
        if url:
            att.append({
                "category": "Network activity",
                "to_ids": True,
                "type": "url",
                "value": url,
                "comment": desc
            })
        event_json = json.loads(event_template)
        event_json["Attribute"] = att
        ev.from_json(json.dumps(event_json))

        self.misp.add_event(ev)
Example #4
0
 def __init__(self, args):
     self.misp_event = pymisp.MISPEvent()
     self.args = args
     if len(args) > 3:
         namespace[0] = args[3]
     if len(args) > 4:
         ns = args[4].replace(" ", "_")
         namespace[1] = re.sub('[\W]+', '', ns)
     if not namespace[0]:
         namespace[0] = 'https://www.misp-project.org'
     try:
         idgen.set_id_namespace({namespace[0]: namespace[1]})
     except ValueError:
         try:
             idgen.set_id_namespace(Namespace(namespace[0], namespace[1]))
         except TypeError:
             idgen.set_id_namespace(Namespace(namespace[0], namespace[1], "MISP"))
     self.namespace_prefix = idgen.get_id_namespace_alias()
     self.simple_type_to_method = {"port": self.generate_port_observable, "domain|ip": self.generate_domain_ip_observable}
     self.simple_type_to_method.update(dict.fromkeys(hash_type_attributes["single"] + hash_type_attributes["composite"] + ["filename"] + ["attachment"], self.resolve_file_observable))
     self.simple_type_to_method.update(dict.fromkeys(["ip-src", "ip-dst", "ip-src|port", "ip-dst|port"], self.generate_ip_observable))
     self.simple_type_to_method.update(dict.fromkeys(["regkey", "regkey|value"], self.generate_regkey_observable))
     self.simple_type_to_method.update(dict.fromkeys(["hostname", "domain", "url", "AS", "mutex", "named pipe", "link"], self.generate_simple_observable))
     self.simple_type_to_method.update(dict.fromkeys(["email-src", "email-dst", "email-subject"], self.resolve_email_observable))
     self.simple_type_to_method.update(dict.fromkeys(["http-method", "user-agent"], self.resolve_http_observable))
     self.simple_type_to_method.update(dict.fromkeys(["pattern-in-file", "pattern-in-traffic", "pattern-in-memory"], self.resolve_pattern_observable))
Example #5
0
def main(args):
    pathname = os.path.dirname(sys.argv[0])
    stix2Event = loadEvent(args, pathname)
    stix2Event = stix2Event.get('objects')
    mispDict = buildMispDict(stix2Event)
    misp = pymisp.MISPEvent(None, False)
    misp.from_dict(**mispDict)
    saveFile(args, misp)
    print(1)
Example #6
0
def main(args):
    pathname = os.path.dirname(args[0])
    stixEvent = loadEvent(args, pathname)
    stixEvent = stixEvent["package"]
    mispDict = buildMispDict(stixEvent)
    #print(mispDict)
    misp = pymisp.MISPEvent(None, False)
    misp.from_dict(**mispDict)
    saveFile(args, pathname, misp)
    print(1)
Example #7
0
    def _insert_misp_event(self, intelmq_event):
        """Insert a new MISPEvent."""
        new_misp_event = pymisp.MISPEvent()

        if 'feed.provider' in intelmq_event:
            new_misp_event.info = 'from {} via IntelMQ'.format(
                intelmq_event['feed.provider'])
        else:
            new_misp_event.info = 'via IntelMQ'

        # set the tags
        new_misp_event.add_tag(self.parameters.misp_tag_for_bot)

        if (self.parameters.add_feed_provider_as_tag and
                'feed.provider' in intelmq_event):
            new_tag = 'IntelMQ:feed.provider="{}"'.format(
                intelmq_event['feed.provider'])
            new_misp_event.add_tag(new_tag)

        if (self.parameters.add_feed_name_as_tag and
                'feed.name' in intelmq_event):
            new_tag = 'IntelMQ:feed.name="{}"'.format(
                intelmq_event['feed.name'])
            new_misp_event.add_tag(new_tag)

        for new_tag in self.parameters.misp_additional_tags:
            new_misp_event.add_tag(new_tag)

        # build the MISPObject and its attributes
        obj = new_misp_event.add_object(name=MISPOBJECT_NAME)

        fields_to_correlate = (
            self.parameters.significant_fields +
            self.parameters.misp_additional_correlation_fields
        )

        for object_relation, value in intelmq_event.items():
            try:
                obj.add_attribute(
                    object_relation,
                    value=value,
                    disable_correlation=(
                        object_relation not in fields_to_correlate),
                    to_ids=(
                        object_relation in self.parameters.misp_to_ids_fields)
                )
            except pymisp.NewAttributeError:
                msg = 'Ignoring "{}":"{}" as not in object template.'
                self.logger.debug(msg.format(object_relation, value))

        misp_event = self.misp.add_event(new_misp_event)
        if self.parameters.misp_publish:
            self.misp.publish(misp_event)
        self.logger.info(
            'Inserted new MISP event with id: {}'.format(misp_event.id))
Example #8
0
def main(args):
    pathname = os.path.dirname(args[0])
    stix2Event = loadEvent(args, pathname)
    stix2Event = stix2Event.get('objects')
    if checkIfFromMISP(stix2Event):
        mispDict = buildMispDict(stix2Event)
    else:
        mispDict = parseExternalStix(stix2Event)
    misp = pymisp.MISPEvent(None, False)
    misp.from_dict(**mispDict)
    saveFile(args, misp)
    print(1)
Example #9
0
File: misp.py Project: kmdnet/tools
    def create_event(self):
        event = pymisp.MISPEvent()

        event.info = 'test_event'
        event.threat_level_id = 3
        event.distribution = 2
        event.analysis = 1
        event.add_attribute('ip-src', ip_list, comment='hogehoge')
        event.add_tag('test-dayo')

        event.publish()
        res = self.misp.add_event(event)
Example #10
0
def main(args):
    pathname = os.path.dirname(args[0])
    stixEvent, isJson = loadEvent(args, pathname)
    stixEvent = stixEvent["package"]
    if isJson:
        namefile = args[1]
    else:
        namefile = '{}.json'.format(args[1][:-4])
    mispDict = buildMispDict(stixEvent)
    misp = pymisp.MISPEvent(None, False)
    misp.from_dict(**mispDict)
    saveFile(namefile, pathname, misp)
    print(1)
Example #11
0
	def get_misp_event(eventid, info):
		eventid=1#The event id of the MISP event to upload objects to
		#info="The event's title"
		misp = MakeConn().get()
		if eventid:
			event = misp.get_event(eventid)
		elif info:
			event = misp.new_event(info=info)
		else:
			event = misp.new_event(info="VirusTotal Report")
		misp_event = pymisp.MISPEvent()
		misp_event.load(event)
		return misp_event
Example #12
0
    def _event_obj(self) -> pymisp.MISPEvent:
        obj = pymisp.MISPEvent()
        obj.info = f"Intelowl Job-{self.job_id}"
        obj.distribution = 0  # your_organisation_only
        obj.threat_level_id = 4  # undefined
        obj.analysis = 2  # completed
        obj.add_tag("source:intelowl")
        obj.add_tag(f"tlp:{self.tlp}")  # tlp tag for sharing

        # Add tags from Job
        for tag in self._job.tags.all():
            obj.add_tag(f"intelowl-tag:{tag.label}")

        return obj
Example #13
0
def insert_json(client, event_dict):
    #event_id = event_dict.get('Event', {}).get('id')
    uuid = event_dict.get('Event', {}).get('uuid')
    if uuid:
        event_obj = pymisp.MISPEvent()
        event_obj.from_dict(**event_dict)

        result = client.search(uuid=uuid)
        if len(result) > 0:
            client.update_event(event_obj)
        else:
            client.add_event(event_obj)
    else:
        raise Exception('There is no uuid in json')
Example #14
0
def get_misp_event(event_id=None, info=None):
    '''
    Smaller helper function for generating a new MISP event or using a preexisting one

    :event_id: The event id of the MISP event to upload objects to

    :info: The event's title/info
    '''
    if event_id:
        event = misp.get_event(event_id)
    elif info:
        event = misp.new_event(info=info)
    else:
        event = misp.new_event(info="VirusTotal Report")
    misp_event = pymisp.MISPEvent()
    misp_event.load(event)
    return misp_event
Example #15
0
    def _create_event(self, artifact):
        """Create an event in MISP, return an Event object."""
        event = pymisp.MISPEvent()
        event.info = self.event_info.format(source_name=artifact.source_name)

        # Add tags.
        for tag in self.tags:
            event.add_tag(tag)

        # Add references.
        if artifact.reference_link != "":
            event.add_attribute("link", artifact.reference_link)
        if artifact.reference_text != "":
            event.add_attribute("text", artifact.reference_text)
        if artifact.source_name != "":
            event.add_attribute("other", f'source:{artifact.source_name}')

        return event
Example #16
0
def main(args):
    pathname = os.path.dirname(args[0])
    stixEvent, isJson, fromMISP, stixJson = loadEvent(args, pathname)
    if isJson:
        namefile = args[1]
    else:
        namefile = '{}.json'.format(args[1])
    if fromMISP:
        stixEvent = stixEvent["package"]
        mispDict = buildMispDict(stixEvent)
    else:
        if stixJson:
            mispDict = buildExternalDict(stixEvent)
        else:
            mispDict = buildExternalDict_fromPackage(stixEvent)
    misp = pymisp.MISPEvent(None, False)
    misp.from_dict(**mispDict)
    saveFile(namefile, pathname, misp)
    print(1)
Example #17
0
def get_or_create_event(misp: pymisp.api.PyMISP, event_uuid: str):
    """
    Returns a MISP Event with the given UUID. Creates a new event with the given
    UUID if it does not exist yet.
    @param misp The PyMISP instance to use
    @param event_uuid The Event UUID to fetch or create
    """
    misp_event = pymisp.MISPEvent()
    misp_event.uuid = event_uuid
    event = misp.get_event(misp_event, deleted=False, pythonify=True)
    if not event or event.get("errors", None):
        logger.warn(f"Could not fetch MISP event with UUID {event_uuid}.")
        misp_event.info = "Retro-Matching roundtrip test event"
        event = misp.add_event(misp_event, pythonify=True)
        if not event or event.get("errors", None):
            errors = event.get("errors", {})
            logger.critical(
                f"Error creating new event. Make sure the configured UUID is not already deleted in MISP: {errors}"
            )
        logger.info(f"Created new MISP event with UUID '{event.uuid}'.")
    else:
        logger.info(f"Found MISP event with UUID '{event.uuid}'")
    return event
    def parse(self, analysis_link, result):
        """
        Parse the analysis result into a MISP event.

        :param str analysis_link: the analysis link
        :param dict[str, any] result: the JSON returned by the analysis client.
        :rtype: MISPEvent
        :return: some results that can be consumed by MIPS.
        """
        self.misp_event = pymisp.MISPEvent()

        # Add analysis subject info
        if "url" in result["analysis_subject"]:
            o = pymisp.MISPObject("url")
            o.add_attribute("url", result["analysis_subject"]["url"])
        else:
            o = pymisp.MISPObject("file")
            o.add_attribute("md5", type="md5", value=result["analysis_subject"]["md5"])
            o.add_attribute("sha1", type="sha1", value=result["analysis_subject"]["sha1"])
            o.add_attribute("sha256", type="sha256", value=result["analysis_subject"]["sha256"])
            o.add_attribute(
                "mimetype",
                type="mime-type",
                value=result["analysis_subject"]["mime_type"]
            )
        self.misp_event.add_object(o)

        # Add HTTP requests from url analyses
        network_dict = result.get("report", {}).get("analysis", {}).get("network", {})
        for request in network_dict.get("requests", []):
            parsed_uri = parse.urlparse(request["url"])
            o = pymisp.MISPObject(name='http-request')
            o.add_attribute('host', parsed_uri.netloc)
            o.add_attribute('method', "GET")
            o.add_attribute('uri', request["url"])
            o.add_attribute("ip", request["ip"])
            self.misp_event.add_object(o)

        # Add network behaviors from files
        for subject in result.get("report", {}).get("analysis_subjects", []):

            # Add DNS requests
            for dns_query in subject.get("dns_queries", []):
                hostname = dns_query.get("hostname")
                # Skip if it is an IP address
                try:
                    if hostname == "wpad":
                        continue
                    _ = ipaddress.ip_address(hostname)
                    continue
                except ValueError:
                    pass

                o = pymisp.MISPObject(name='dns-record')
                o.add_attribute('queried-domain', hostname)
                self.misp_event.add_object(o)

            # Add HTTP conversations (as network connection and as http request)
            for http_conversation in subject.get("http_conversations", []):
                o = pymisp.MISPObject(name="network-connection")
                o.add_attribute("ip-src", http_conversation["src_ip"])
                o.add_attribute("ip-dst", http_conversation["dst_ip"])
                o.add_attribute("src-port", http_conversation["src_port"])
                o.add_attribute("dst-port", http_conversation["dst_port"])
                o.add_attribute("hostname-dst", http_conversation["dst_host"])
                o.add_attribute("layer3-protocol", "IP")
                o.add_attribute("layer4-protocol", "TCP")
                o.add_attribute("layer7-protocol", "HTTP")
                self.misp_event.add_object(o)

                method, path, http_version = http_conversation["url"].split(" ")
                if http_conversation["dst_port"] == 80:
                    uri = "http://{}{}".format(http_conversation["dst_host"], path)
                else:
                    uri = "http://{}:{}{}".format(
                        http_conversation["dst_host"],
                        http_conversation["dst_port"],
                        path
                    )
                o = pymisp.MISPObject(name='http-request')
                o.add_attribute('host', http_conversation["dst_host"])
                o.add_attribute('method', method)
                o.add_attribute('uri', uri)
                o.add_attribute('ip', http_conversation["dst_ip"])
                self.misp_event.add_object(o)

        # Add sandbox info like score and sandbox type
        o = pymisp.MISPObject(name="sandbox-report")
        sandbox_type = "saas" if is_analysis_hosted(analysis_link) else "on-premise"
        o.add_attribute("score", result["score"])
        o.add_attribute("sandbox-type", sandbox_type)
        o.add_attribute("{}-sandbox".format(sandbox_type), "lastline")
        o.add_attribute("permalink", analysis_link)
        self.misp_event.add_object(o)

        # Add behaviors
        o = pymisp.MISPObject(name="sb-signature")
        o.add_attribute("software", "Lastline")
        for activity in result.get("malicious_activity", []):
            a = pymisp.MISPAttribute()
            a.from_dict(type="text", value=activity)
            o.add_attribute("signature", **a)
        self.misp_event.add_object(o)

        # Add mitre techniques
        for technique in self._get_mitre_techniques(result):
            self.misp_event.add_tag(technique)
Example #19
0
    def write_row(self, count, row, match, enrichments, output_stream):
        me = pymisp.MISPEvent()

        extra_info = self._extra_information_by_tag
        tag = match['tag']

        containers = [row, match]
        if tag in extra_info:
            containers.append(extra_info[tag])

        # create the "subject" (info) line
        me.info = self.construct_info(containers)

        # create attributes
        self.add_attributes(me, containers)

        # set basic attributes
        me.published = False
        me.distribution = "1"
        try:
            ts = float(row['ts'])
            me.set_date(ts)
        except Exception:
            try:
                t = dateparser.parse(row['ts'])
                me.set_date(t.timestamp())
            except Exception:
                sys.stderr.write(f"couldn't convert date: {row['ts']}\n")

        # manually constructed attributes
        if 'uri' in row and row['uri'] != '-' and 'host' in row:
            me.add_attribute(
                type='url',
                category='Network activity',
                value=f'http://{row["host"]}:{row["id_resp_p"]}{row["uri"]}')

        # add in the row itself
        row_description = ""
        for item in row:
            row_description += f"{item}: {row[item]}\n"
        me.add_attribute(type='text',
                         category="External analysis",
                         value=row_description,
                         comment="zeek row")

        # and the match
        match_description = ""
        for item in match:
            match_description += f"{item}: {match[item]}\n"
        me.add_attribute(type='text',
                         category="External analysis",
                         value=match_description,
                         comment="threat source information")

        # If there is an external link to use, add it
        if self._web_report_urls:
            if not isinstance(self._web_report_urls, list):
                self._web_report_urls = [self._web_report_urls]

            for url in self._web_report_urls:
                location = url.format(count=count,
                                      row=row,
                                      match=match,
                                      enrichments=enrichments)
                me.add_attribute(type='link',
                                 category="External analysis",
                                 value=location,
                                 comment="GAWSEED report")

        # fake a priority
        if 'priority' in match:
            if match['priority'] >= 8:
                me.threat_level = 1
                me.threat_level_id = 1
            elif match['priority'] >= 5:
                me.threat_level = 2
                me.threat_level_id = 2
            else:
                me.threat_level = 3
                me.threat_level_id = 3

        self._misp.add_event(me)
Example #20
0
def create_events(pulse_or_list, author=False, server=False, key=False, misp=False, blacklist_file = None, distribution=0, threat_level=4,
                  analysis=2, publish=True, tlp=True, discover_tags=False, to_ids=False, author_tag=False,
                  bulk_tag=None, dedup_titles=False, stop_on_error=False):
    """
    Parse a Pulse or a list of Pulses and add it/them to MISP if server and key are present

    :param pulse_or_list: a Pulse or list of Pulses as returned by `get_pulses`
    :param author: Prepend the author to the Pulse name
    :type author: Boolean
    :param server: MISP server URL
    :param key: MISP API key
    :param misp: MISP connection object
    :type misp: :class:`pymisp.PyMISP`
    :param blacklist_file: The name of a file containing a list of pulse title regexes for pulses taht should be ignored
    :type blacklist_file: String
    :param distribution: distribution of the MISP event (0-4)
    :param threat_level: threat level of the MISP object (1-4)
    :param analysis: analysis stae of the MISP object (0-2)
    :param publish: Is the MISP event should be published?
    :type publish: Boolean
    :param tlp: Add TLP level tag to event
    :type tlp: Boolean
    :param discover_tags: discover MISP tags from Pulse tags
    :type discover_tags: Boolean
    :param to_ids: Flag pulse attributes as being sent to an IDS
    :type to_ids: Boolean
    :param author_tag: Add the pulse author as an event tag
    :type author_tag: Boolean
    :param bulk_tag: A tag that will be added to all events for categorization (e.g. OTX)
    :type bulk_tag: String
    :param dedup_titles: Search MISP for an existing event title and update it, rather than create a new one
    :type dedup_titles: Boolean
    :return: a dict or a list of dict with the selected attributes
    """
    if not misp and (server and key):
        log.debug("Connection to MISP instance: {}".format(server))
        try:
            misp = pymisp.ExpandedPyMISP(server, key, ssl=False)
        except pymisp.PyMISPError as ex:
            raise ImportException("Cannot connect to MISP instance: {}".format(ex.message))
        except Exception as ex:
            raise ImportException("Cannot connect to MISP instance, unknown exception: {}".format(ex.message))
          
    # Let's load the list of blacklisted pulse titles, if exists
    global _otx_blacklisted_titles
    if blacklist_file and not _otx_blacklisted_titles:
        if not os.path.isfile(blacklist_file):
            log.warn("The blacklisted pulse titles file that has been provided does not exist: {}".format(blacklist_file))
        else:
            with open(blacklist_file) as f:
                lines = f.read().splitlines()
            for line in lines:
                if line != "":
                    _otx_blacklisted_titles.append(re.compile(line))
                
    # Let's load in cache all MISP tags available on the instance
    global _otx_tags_cache
    if _otx_tags_cache is None:
        _otx_tags_cache = misp.tags()

    if discover_tags:
        def get_tag_name(complete):
            parts = complete.split('=')
            if not len(parts):
                return complete
            last = parts[-1]
            if not len(last):
                return complete
            if last[0] == '"':
                last = last[1:]
            if last[-1] == '"':
                last = last[:-1]
            return last.lower()
        tags = dict()
        for tag in _otx_tags_cache:
            tags[get_tag_name(tag['name'])] = tag['name']
        misp.discovered_tags = tags

    if isinstance(pulse_or_list, (list, tuple)) or inspect.isgenerator(pulse_or_list):
        misp_events = []
        for pulse in pulse_or_list:
            try:
                misp_event = create_events(pulse, author=author, server=server, key=key, misp=misp,
                                           distribution=distribution, threat_level=threat_level, analysis=analysis,
                                           publish=publish, tlp=tlp, to_ids=to_ids, author_tag=author_tag,
                                           bulk_tag=bulk_tag, dedup_titles=dedup_titles, stop_on_error=stop_on_error)
                if misp_event:
                    misp_events.append(misp_event)
            except Exception as ex:
                if stop_on_error:
                    raise
                name = ''
                if pulse and 'name' in pulse:
                    name = pulse['name']
                log.error("Cannot import pulse {}: {}".format(name, ex))
        return misp_events

    pulse = pulse_or_list
    if author:
        event_name = pulse['author_name'] + ' | ' + pulse['name']
    else:
        event_name = pulse['name']
    event_name = event_name.strip()
    try:
        dt = date_parser.parse(pulse['created'])
    except (ValueError, OverflowError):
        log.error("Cannot parse Pulse 'created' date.")
        dt = datetime.utcnow()
    event_date = dt.strftime('%Y-%m-%d')
    
    # Let's ignore the pulse if its title is blacklisted
    for regex in _otx_blacklisted_titles:
        if regex.match(pulse['name']):
                log.info("## *** IGNORED *** {name} - {date}".format(name=event_name, date=event_date))
                return None
    log.info("## {name} - {date}".format(name=event_name, date=event_date))
    result_event = {
        'name': event_name,
        'date': event_date,
        'tags': list(),
        'attributes': {
            'hashes': {
                'md5': list(),
                'sha1': list(),
                'sha256': list(),
                'imphash': list(),
                'pehash': list()
            },
            'hostnames': list(),
            'domains': list(),
            'urls': list(),
            'ips': list(),
            'emails': list(),
            'mutexes': list(),
            'references': list(),
            'cves': list(),
            'filenames': list(),
            'yara': list()
        },
    }

    if misp:
        if not dedup_titles:
            event = pymisp.MISPEvent()
            event.distribution = distribution
            event.threat_level_id = threat_level
            event.analysis = analysis
            event.info = event_name
            event.date = dt
            event = misp.add_event(event)['Event']
        else:
            event = ''
            # Search MISP for the title
            result = misp.search(eventinfo=event_name, metadata=True)
            if len(result) == 0:
                event = pymisp.MISPEvent()
                event.distribution = distribution
                event.threat_level = threat_level
                event.analysis = analysis
                event.info = event_name
                event.set_date(dt)
                event = misp.add_event(event)['Event']
            else:
                for evt in result:
                    # If it exists, set 'event' to the event
                    if evt['Event']['info'] == event_name:
                        if 'SharingGroup' in evt['Event']:
                            del evt['Event']['SharingGroup']  # This deletes the SharingGroup from the list, thx SparkyNZL
                        event = evt['Event']
                        break
                if event == '':
                    # Event not found, even though search results were returned
                    # Build new event
                    event = pymisp.MISPEvent()
                    event.distribution = distribution
                    event.threat_level = threat_level
                    event.analysis = analysis
                    event.info = event_name
                    event.set_date(dt)
                    misp.add_event(event)
        time.sleep(0.2)
        if tlp:
            tag = None
            if 'TLP' in pulse:
                tag = "tlp:{}".format(pulse['TLP'])
            elif 'tlp' in pulse:
                tag = "tlp:{}".format(pulse['tlp'])
            if tag is not None:
                log.info("\t - Adding tag: {}".format(tag))
                tag_event(misp, event, tag)
                result_event['tags'].append(tag)

        if author_tag:
            tag_event(misp, event, pulse['author_name'])

        if bulk_tag is not None:
            tag_event(misp, event, bulk_tag)

    if misp and hasattr(misp, 'discovered_tags') and 'tags' in pulse:
        for pulse_tag in pulse['tags']:
            if pulse_tag.lower() in misp.discovered_tags:
                tag = misp.discovered_tags[pulse_tag.lower()]
                log.info("\t - Adding tag: {}".format(tag))
                tag_event(misp, event, tag)
                result_event['tags'].append(tag)
                
    if 'references' in pulse:
        for reference in pulse['references']:
            if reference:
                log.info("\t - Adding external analysis link: {}".format(reference))
                if misp:
                    a = pymisp.MISPAttribute()
                    a.category = "External analysis"
                    a.type = 'link'
                    a.value = reference
                    add_attribute(misp, event, a)
                result_event['attributes']['references'].append(reference)

    if misp and 'description' in pulse and isinstance(pulse['description'], six.text_type) and pulse['description']:
        log.info("\t - Adding external analysis comment")
        a = pymisp.MISPAttribute()
        a.category = 'External analysis'
        a.type = 'comment'
        a.value = pulse['description']
        add_attribute(misp, event, a)

    for ind in pulse['indicators']:
        ind_type = ind['type']
        ind_val = ind['indicator']
        a = pymisp.MISPAttribute()        
        a.value = ind_val
        a.to_ids = to_ids

        if 'description' in ind and isinstance(ind['description'], six.text_type) and ind['description']:
            a.comment = ind['description']
            
        if ind_type == 'FileHash-SHA256':
            log.info("\t - Adding SHA256 hash: {}".format(ind_val))
            a.category = 'Artifacts dropped'            
            a.type = 'sha256'
            add_attribute(misp, event, a)                        
            result_event['attributes']['hashes']['sha256'].append(ind_val)

        elif ind_type == 'FileHash-SHA1':
            log.info("\t - Adding SHA1 hash: {}".format(ind_val))
            a.category = 'Artifacts dropped'                        
            a.type = 'sha1'
            add_attribute(misp, event, a)                        
            result_event['attributes']['hashes']['sha1'].append(ind_val)

        elif ind_type == 'FileHash-MD5':
            log.info("\t - Adding MD5 hash: {}".format(ind_val))
            a.category = 'Artifacts dropped'                        
            a.type = 'md5'
            add_attribute(misp, event, a)                        
            result_event['attributes']['hashes']['md5'].append(ind_val)

        elif ind_type == 'FileHash-IMPHASH':
            log.info("\t - Adding IMPHASH hash: {}".format(ind_val))
            a.category = 'Artifacts dropped'                        
            a.type = 'imphash'
            add_attribute(misp, event, a)                        
            result_event['attributes']['hashes']['imphash'].append(ind_val)

        elif ind_type == 'FileHash-PEHASH':
            log.info("\t - Adding PEHASH hash: {}".format(ind_val))
            a.category = 'Artifacts dropped'                                    
            a.type = 'pehash'
            add_attribute(misp, event, a)                        
            result_event['attributes']['hashes']['pehash'].append(ind_val)
            
        elif ind_type == 'YARA':
            ind_title = ind.get('title', ind_val)
            ind_desc = ind.get('description', '')
            if ind_title == '':
                ind_title = ind_val
                if not ind_desc == '':
                    a.comment = ind_desc
            else:
                a.comment = "{} {}".format(ind_title, ind_desc)
            ind_val = ind.get('content', None)
            if ind_val is None or ind_val == "":
                log.warning("YARA indicator is empty: %s" % ind_title)
                continue
            log.info("\t - Adding YARA rule: {}".format(ind_title))
            a.category = 'Artifacts dropped'                                    
            a.type = 'yara'
            a.value = ind_val
            add_attribute(misp, event, a)                        
            result_event['attributes']['yara'].append({'title': ind_title, 'content': ind_val})

        elif ind_type == 'Mutex':
            log.info("\t - Adding mutex: {}".format(ind_val))
            a.category = 'Artifacts dropped'                                    
            a.type = 'mutex'
            add_attribute(misp, event, a)                        
            result_event['attributes']['mutexes'].append(ind_val)

        elif ind_type == 'FilePath':
            log.info("\t - Adding filename: {}".format(ind_val))
            a.category = 'Artifacts dropped'                                    
            a.type = 'filename'
            add_attribute(misp, event, a)                        
            result_event['attributes']['filenames'].append(ind_val)
            
        elif ind_type == 'URI' or ind_type == 'URL':
            log.info("\t - Adding URL: {}".format(ind_val))
            a.category = 'Network activity'            
            a.type = 'url'
            add_attribute(misp, event, a)                        
            result_event['attributes']['urls'].append(ind_val)

        elif ind_type == 'domain':
            log.info("\t - Adding domain: {}".format(ind_val))
            a.category = 'Network activity'                        
            a.type = 'domain'
            add_attribute(misp, event, a)                        
            result_event['attributes']['domains'].append(ind_val)

        elif ind_type == 'hostname':
            log.info("\t - Adding hostname: {}".format(ind_val))
            a.category = 'Network activity'                        
            a.type = 'hostname'
            add_attribute(misp, event, a)                        
            result_event['attributes']['hostnames'].append(ind_val)

        elif ind_type == 'IPv4' or ind_type == 'IPv6':
            log.info("\t - Adding ip: {}".format(ind_val))
            a.category = 'Network activity'                        
            a.type = 'ip-dst'
            add_attribute(misp, event, a)                        
            result_event['attributes']['ips'].append(ind_val)

        elif ind_type == 'email':
            log.info("\t - Adding email: {}".format(ind_val))
            a.category = 'Network activity'                        
            a.type = 'email-dst'
            result_event['attributes']['emails'].append(ind_val)
            add_attribute(misp, event, a)                        

        elif ind_type == 'CVE':
            log.info("\t - Adding CVE: {}".format(ind_val))
            a.type = 'External analysis'
            a.type = 'vulnerability'
            add_attribute(misp, event, a)            
            result_event['attributes']['cves'].append(ind_val)
            
        else:
            log.warning("Unsupported indicator type: %s" % ind_type)

    if misp and publish:
        misp.publish(event)
    return result_event
Example #21
0
 def __init__(self):
     self.misp_event = pymisp.MISPEvent()
     self.SDOs = []
     self.object_refs = []
     self.external_refs = []
Example #22
0
 def __init__(self):
     self.misp_event = pymisp.MISPEvent()
     self.event = []
     self.misp_event['Galaxy'] = []
Example #23
0
def createActor(iUUID, iUpdate=False):
    try:
        # fUNCTION SETUP
        # -----------------------------------------------
        myUUID = iUUID
        myLinks = []
        myTags = []
        myMeta = []
        myCommonName = ""

        # ATTRIBUTES COMMON FIELDS
        # -----------------------------------------------
        attributeToIDS = 0  # 0 false : 1 true
        attributeComment = ""
        attribDisableCorrelation = 1  # 0 false : 1 true

        # MISP SETUP
        # -----------------------------------------------

        event = pm.MISPEvent()
        event.uuid = myUUID

        # GET META FOR ACTOR (USE COMMON NAME AS INCIDENT NAME)
        myMeta = db.get_actor_meta(myUUID)
        if gv._DEBUG:
            print("f(x) createActor: ACTOR META")
            print(json.dumps(myMeta, indent=4))

        # USED AS INCIDENT NAME
        myCommonName = myMeta["commonname"]
        event.info = "Threat Actor: " + myCommonName
        print("f(x) createActor: ACTOR NAME: {}".format(myCommonName))

        # USED AS A TEXT ATTRIBUTE
        myDescription = myMeta["description"]
        if myDescription != "":
            attributeType = "text"
            attributeCategory = "Internal reference"
            if gv._DEBUG:
                print(
                    "f(x) createFamily: CREATING FAMILY COMMENT: \nCATEGORY: {} \nTYPE: {} \nVALUE: {} \nCOMMENT: {} \nDISABLE CORRELATION: {} \
                    ".format(attributeCategory, attributeType, myDescription,
                             attributeToIDS, attributeComment,
                             attribDisableCorrelation))

            event.add_attribute(attributeType,
                                myDescription,
                                comment=attributeComment,
                                category=attributeCategory,
                                to_ids=attributeToIDS,
                                disable_correlation=attribDisableCorrelation)

        # -----------------------------------------------
        # GET TAGS
        if myCommonName != "UNATTRIBUTED" and myCommonName != "ERROR":
            # GET TAGS
            myTags = db.get_set_all_tags(myUUID)
            event.tags = myTags
            if gv._DEBUG:
                print("f(x) createActor: TAGS CREATED")
                print(*myTags, sep="\n")

            # REFERENCES/URLS
            myLinks = db.get_links(myUUID)
            for link in myLinks:
                attributeType = "link"
                attributeCategory = "Internal reference"
                if gv._DEBUG:
                    print(
                        "f(x) createActor: CREATING ACTOR LINK: \nCATEGORY: {} \nTYPE: {} \nVALUE: {} \nTO_IDS: {} \nCOMMENT: {}\nDISABLE CORRELATION: {} \
                            ".format(attributeCategory, attributeType,
                                     link["url"], attributeToIDS,
                                     attributeComment,
                                     attribDisableCorrelation))
                event.add_attribute(
                    attributeType,
                    link["url"],
                    comment=attributeComment,
                    category=attributeCategory,
                    to_ids=attributeToIDS,
                    disable_correlation=attribDisableCorrelation)

        # MARK SOURCE OF INFORMATION
        attributeType = "link"
        attributeCategory = "Internal reference"
        attributeComment = "DATA FROM MALPEDIA."
        if gv._DEBUG:
            print(
                "f(x) createActor: CREATING ACTOR ATTRIBUTION LINK: \nCATEGORY: {} \nTYPE: {} \nVALUE: {} \nTO_IDS: {} \nCOMMENT: {} \nDISABLE CORRELATION: {} \
                    ".format(attributeCategory, attributeType,
                             gv._MALPEDIA_URL, attributeToIDS,
                             attributeComment, attribDisableCorrelation))

        event.add_attribute(attributeType,
                            gv._MALPEDIA_URL,
                            comment=attributeComment,
                            category=attributeCategory,
                            to_ids=attributeToIDS,
                            disable_correlation=attribDisableCorrelation)

        gv._THREAD_LIST.append(
            executor.submit(pushToMISP, event, iUpdate, gv._MISP_URL,
                            gv._MISP_KEY, gv._MISP_VERIFYCERT, gv._DEBUG))
        # pushToMISP(event, iUpdate, gv._MISP_URL, gv._MISP_KEY, gv._MISP_VERIFYCERT, gv._DEBUG)

    except Exception as e:
        exc_type, _, exc_tb = sys.exc_info()
        fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
        print("f(x) createActor: {}: {}: {}".format(exc_type, fname,
                                                    exc_tb.tb_lineno))
        sys.exit(e)
Example #24
0
def createFamily(iUUID, iUpdate=False):
    try:
        # fUNCTION SETUP
        # -----------------------------------------------
        myUUID = iUUID
        myLinks = []
        myTags = []
        myMeta = []
        myCommonName = ""

        # ATTRIBUTES COMMON FIELDS
        # -----------------------------------------------
        attributeToIDS = 0  # 0 false : 1 true
        attributeComment = ""
        attribDisableCorrelation = 1  # 0 false : 1 true

        # MISP SETUP
        # -----------------------------------------------
        event = pm.MISPEvent()
        event.uuid = myUUID

        # GET UUID METADATA FROM PARENT CHILD TABLE
        # -----------------------------------------------
        iPC_META = db.get_parent_child_data(iUUID=myUUID)
        parentuuid = iPC_META["parentuuid"]
        event.extends_uuid = parentuuid

        # -----------------------------------------------
        # REFERENCES/URLS
        myLinks = db.get_links(myUUID)
        for link in myLinks:
            attributeType = "link"
            attributeCategory = "Internal reference"
            if gv._DEBUG:
                print(
                    "f(x) createFamily: LINK: \nCATEGORY: {} \nTYPE: {} \nVALUE: {} \nTO_IDS: {} \nCOMMENT: {}\nDISABLE CORRELATION: {} \
                        ".format(attributeCategory, attributeType, link["url"],
                                 attributeToIDS, attributeComment,
                                 attribDisableCorrelation))
            event.add_attribute(attributeType,
                                link["url"],
                                comment=attributeComment,
                                category=attributeCategory,
                                to_ids=attributeToIDS,
                                disable_correlation=attribDisableCorrelation)

        # GET TAGS
        myTags = db.get_set_all_tags(myUUID)
        event.tags = myTags
        if gv._DEBUG:
            print("f(x) createFamily: TAGS")
            print(*myTags, sep="\n")

        # GET META FOR ACTOR (USE COMMON NAME AS INCIDENT NAME)
        myMeta = db.get_family_meta(iUUID=myUUID)
        if gv._DEBUG:
            print("f(x) createFamily: META")
            print(json.dumps(myMeta, indent=4))

        # USED AS INCIDENT NAME
        myCommonName = myMeta["commonname"]
        event.info = myCommonName

        print("f(x) createFamily: MALWARE NAME: {}".format(myCommonName))

        # USED AS A TEXT ATTRIBUTE
        myDescription = myMeta["description"]
        if myDescription != "":
            attributeType = "text"
            attributeCategory = "Internal reference"
            if gv._DEBUG:
                print(
                    "f(x) createFamily: CREATING FAMILY COMMENT: \nCATEGORY: {} \nTYPE: {} \nVALUE: {} \nCOMMENT: {} \nDISABLE CORRELATION: {} \
                    ".format(attributeCategory, attributeType, myDescription,
                             attributeToIDS, attributeComment,
                             attribDisableCorrelation))

            event.add_attribute(attributeType,
                                myDescription,
                                comment=attributeComment,
                                category=attributeCategory,
                                to_ids=attributeToIDS,
                                disable_correlation=attribDisableCorrelation)

        # MARK SOURCE OF INFORMATION
        attributeType = "link"
        attributeCategory = "Internal reference"
        attributeComment = "DATA FROM MALPEDIA."
        if gv._DEBUG:
            print(
                "f(x) createFamily: ATTRIBUTION LINK: \nCATEGORY: {} \nTYPE: {} \nVALUE: {} \nTO_IDS: {} \nCOMMENT: {} \nDISABLE CORRELATION: {} \
                    ".format(attributeCategory, attributeType,
                             gv._MALPEDIA_URL, attributeToIDS,
                             attributeComment, attribDisableCorrelation))

        event.add_attribute(attributeType,
                            gv._MALPEDIA_URL,
                            comment=attributeComment,
                            category=attributeCategory,
                            to_ids=attributeToIDS,
                            disable_correlation=attribDisableCorrelation)

        # YARA
        # ADD OBJECTS
        # -----------------------------------------------
        # YARA
        iYara = db.get_yara_rules(myUUID)
        tlp = ""
        yaraAbsPath = ""

        for yara in iYara:
            tagList = []
            newTag = MISPTag()
            tlp = yara["tlp"]
            yaraAbsPath = yara["path_to_yara"]
            tlpTag = "tlp:" + tlp.split("_")[1]
            newTag.name = tlpTag
            tagList.append(newTag)
            yaraUUID = yara["attribute_uuid"]

            yaraContents = ""

            with open(yaraAbsPath, 'r') as yaraIn:
                yaraContents = yaraIn.read()
                yaraIn.close()

            misp_object = pm.tools.GenericObjectGenerator("yara")
            misp_object.comment = tlpTag
            misp_object.uuid = yaraUUID

            subAttribute = misp_object.add_attribute("yara", yaraContents)
            subAttribute.disable_correlation = True
            subAttribute.to_ids = False
            subAttribute.comment = tlpTag
            subAttribute.tags = tagList

            event.add_object(misp_object)

            if gv._DEBUG:
                print("f(x) createFamily: YARA")
                print(*iYara, sep="\n")

        gv._THREAD_LIST.append(
            executor.submit(pushToMISP, event, iUpdate, gv._MISP_URL,
                            gv._MISP_KEY, gv._MISP_VERIFYCERT, gv._DEBUG))
        # pushToMISP(event, iUpdate, gv._MISP_URL, gv._MISP_KEY, gv._MISP_VERIFYCERT, gv._DEBUG)

    except Exception as e:
        exc_type, _, exc_tb = sys.exc_info()
        fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
        print("f(x) createFamily: {}: {}: {}".format(exc_type, fname,
                                                     exc_tb.tb_lineno))
        sys.exit(e)
Example #25
0
def createPath(iUUID, iUpdate=False):
    try:
        # fUNCTION SETUP
        # -----------------------------------------------
        myUUID = iUUID
        myTags = []
        myName = ""

        # ATTRIBUTES COMMON FIELDS
        # -----------------------------------------------
        attributeToIDS = 0  # 0 false : 1 true
        attributeComment = ""
        attribDisableCorrelation = 1  # 0 false : 1 true

        # MISP SETUP
        # -----------------------------------------------
        event = pm.MISPEvent()
        event.uuid = myUUID

        # GET UUID METADATA FROM PARENT CHILD TABLE
        # -----------------------------------------------
        iPC_META = db.get_parent_child_data(iUUID=myUUID)
        parentuuid = iPC_META["parentuuid"]
        myName = iPC_META["name"]
        event.extends_uuid = parentuuid
        event.info = myName
        print("f(x) createPath: MALWARE PATH NAME: {}".format(myName))

        # GET TAGS FROM PARENT AND ADD TO THIS PATH
        myTags = db.get_set_all_tags(myUUID)
        event.tags = myTags
        if gv._DEBUG:
            print("f(x) createPath: TAGS")
            print(*myTags, sep="\n")

        # MARK SOURCE OF INFORMATION
        attributeType = "link"
        attributeCategory = "Internal reference"
        attributeComment = "DATA FROM MALPEDIA."
        if gv._DEBUG:
            print(
                "f(x) createPath: ATTRIBUTION LINK: \nCATEGORY: {} \nTYPE: {} \nVALUE: {} \nTO_IDS: {} \nCOMMENT: {} \nDISABLE CORRELATION: {} \
                    ".format(attributeCategory, attributeType,
                             gv._MALPEDIA_URL, attributeToIDS,
                             attributeComment, attribDisableCorrelation))

        event.add_attribute(attributeType,
                            gv._MALPEDIA_URL,
                            comment=attributeComment,
                            category=attributeCategory,
                            to_ids=attributeToIDS,
                            disable_correlation=attribDisableCorrelation)

        gv._THREAD_LIST.append(
            executor.submit(pushToMISP, event, iUpdate, gv._MISP_URL,
                            gv._MISP_KEY, gv._MISP_VERIFYCERT, gv._DEBUG))
        # pushToMISP(event, iUpdate, gv._MISP_URL, gv._MISP_KEY, gv._MISP_VERIFYCERT, gv._DEBUG)

    except Exception as e:
        exc_type, _, exc_tb = sys.exc_info()
        fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
        print("f(x) createPath: {}: {}: {}".format(exc_type, fname,
                                                   exc_tb.tb_lineno))
        sys.exit(e)
Example #26
0
def createMalware(iUUID, iUpdate=False):
    try:
        # fUNCTION SETUP
        # -----------------------------------------------
        myUUID = iUUID
        myTags = []

        # ATTRIBUTES COMMON FIELDS
        # -----------------------------------------------
        attributeToIDS = 0  # 0 false : 1 true
        attributeComment = ""
        attribDisableCorrelation = 1  # 0 false : 1 true

        # MISP SETUP
        # -----------------------------------------------
        event = pm.MISPEvent()
        event.uuid = myUUID

        # GET UUID METADATA FROM PARENT CHILD TABLE
        # -----------------------------------------------
        iPC_META = db.get_parent_child_data(iUUID=myUUID)
        parentuuid = iPC_META["parentuuid"]
        event.extends_uuid = parentuuid

        name = iPC_META["name"]

        if name in gv._BLACKLISTED_FILES:
            return True

        event.info = name

        print("f(x) createMalware: MALWARE SAMPLE NAME: {}".format(name))

        # SET VERSION
        myVersion = iPC_META["version"]
        if myVersion != "":
            attributeType = "text"
            attributeCategory = "Internal reference"
            if gv._DEBUG:
                print(
                    "f(x) createMalware: CREATING FAMILY COMMENT: \nCATEGORY: {} \nTYPE: {} \nVALUE: {} \nCOMMENT: {} \nDISABLE CORRELATION: {} \
                    ".format(attributeCategory, attributeType, myVersion,
                             attributeToIDS, attributeComment,
                             attribDisableCorrelation))

            event.add_attribute(attributeType,
                                myVersion,
                                comment=attributeComment,
                                category=attributeCategory,
                                to_ids=attributeToIDS,
                                disable_correlation=attribDisableCorrelation)

        # SET DATE ADDED
        date_added = iPC_META["date_added"]
        if valid_date(date_added):
            event.date = date_added
        else:
            event.date = datetime.date.today()

        # GET TAGS
        myTags = db.get_set_all_tags(myUUID)
        event.tags = myTags
        if gv._DEBUG:
            print("f(x) createMalware: TAGS")
            print(*myTags, sep="\n")

        # MARK SOURCE OF INFORMATION
        attributeType = "link"
        attributeCategory = "Internal reference"
        attributeComment = "DATA FROM MALPEDIA."
        if gv._DEBUG:
            print(
                "f(x) createMalware: ATTRIBUTION LINK: \nCATEGORY: {} \nTYPE: {} \nVALUE: {} \nTO_IDS: {} \nCOMMENT: {} \nDISABLE CORRELATION: {} \
                    ".format(attributeCategory, attributeType,
                             gv._MALPEDIA_URL, attributeToIDS,
                             attributeComment, attribDisableCorrelation))

        event.add_attribute(attributeType,
                            gv._MALPEDIA_URL,
                            comment=attributeComment,
                            category=attributeCategory,
                            to_ids=attributeToIDS,
                            disable_correlation=attribDisableCorrelation)

        # ADD ATTACHMENT
        myPath = iPC_META["path"]
        fo = None
        peo = None
        seos = None

        # CREATE ATTACHMENT BUT DON'T UPLOAD IT AGAIN IF THIS IS JUST AN UPDATE
        if iUpdate == False:
            for f in glob.glob(iPC_META["path"]):
                try:
                    fo, peo, seos = make_binary_objects(f)
                except Exception as e:
                    continue

        gv._THREAD_LIST.append(
            uexecutor.submit(pushToMISPWithAttachment, event, myPath, iUpdate,
                             gv._MISP_URL, gv._MISP_KEY, gv._MISP_VERIFYCERT,
                             gv._DEBUG, fo, peo, seos))
        # pushToMISPWithAttachment(event, myPath, iUpdate, gv._MISP_URL, gv._MISP_KEY, gv._MISP_VERIFYCERT, gv._DEBUG, fo , peo, seos)

    except Exception as e:
        exc_type, _, exc_tb = sys.exc_info()
        fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
        print("f(x) createMalware: {}: {}: {}".format(exc_type, fname,
                                                      exc_tb.tb_lineno))
        sys.exit(e)
Example #27
0
def main(args):
    logging.info('Passing through misp_exporter')
    with open(args.fingerprint) as file:
        try:
            data = json.load(file)
        except Exception:
            logging.error('Fingerprint not compatible.')
            return
    misp = pymisp.ExpandedPyMISP(args.misp_url,
                                 args.misp_key,
                                 ssl=False,
                                 debug=True)
    event = pymisp.MISPEvent(strict_validation=True)
    event.info = args.event_info
    event.distribution = args.distribution
    event.threat_level_id = args.threat_level
    event.analysis = args.analysis_level
    event.add_tag(tag='validated')
    ddos = pymisp.MISPObject('ddos', strict=True)
    logging.info('Fingerprint processed: {}'.format(args.fingerprint))
    if 'attack_vector' in data:
        av = data['attack_vector'][0]
        snort = {
            'protocol': [],
            'src_ip': [],
            'src_port': [],
            'dst_port': [],
            'options': [],
        }
        df = find_ips(av)
        logging.info('IPs found: {}'.format(len(df['ip'])))
        subnets = utils.smart_aggregate(df)
        logging.info('The IPs were summarized in: {} subnets'.format(
            len(subnets)))
        if args.subnets:
            add_attributes(event, subnets, 'ip-src', 'attacker subnet')
            ddos.add_attributes('ip-src', *subnets)
            snort['src_ip'] += subnets
        else:
            add_attributes(event, df['ip'], 'ip-src', 'attacker ip')
            ddos.add_attributes('ip-src', *df['ip'])
            snort['src_ip'] += df['ip'].tolist()
        if 'srcport' in av:
            sport = find_attr(av['srcport'], 'srcport')
            add_attributes(event, sport['srcport'], 'port',
                           'source port of attack')
            ddos.add_attributes('src-port', *sport['srcport'])
            snort['src_port'] += sport['srcport'].tolist()
        if 'dstport' in av:
            dport = find_attr(av['dstport'], 'dstport')
            add_attributes(event, dport['dstport'], 'port',
                           'destination port of attack')
            ddos.add_attributes('dst-port', *sport['dstport'])
            snort['dst_port'] += sport['dstport']
        if 'ip_proto' in av:
            proto4 = find_attr(av['ip_proto'], 'ip_proto')
            add_attributes(event, proto4['ip_proto'], 'other',
                           '4 level protocol of attack')
            ddos.add_attributes('protocol', *proto4['ip_proto'])
            snort['protocol'] += proto4['ip_proto'].tolist()
        if 'dns_qry_name' in av:
            snort['options'] += snort_content(av['dns_qry_name'])
        if 'http_request' in av:
            snort['options'] += snort_content(av['http_request'])
        if 'http_response' in av:
            snort['options'] += snort_content(av['http_response'])
        if 'http_user_agent' in av:
            snort['options'] += snort_content(av['http_user_agent'])
        if 'icmp_type' in av:
            snort['options'] += snort_itype(av['icmp_type'])
        if 'icmp_code' in av:
            snort['options'] += snort_icode(av['icmp_code'])
        if 'ip_ttl' in av:
            snort['options'] += snort_ttl(av['ip_ttl'])
        if 'ntp_priv_reqcode' in av:
            snort['options'] += snort_content(av['ntp_priv_reqcode'])
        if 'tcp_flags' in av:
            snort['options'] += snort_flags(av['tcp_flags'])
        if 'tags' in av:
            for tag in av['tags']:
                event.add_tag(tag=tag)
        if 'duration_sec' in av:
            add_attribute_comment(event, 'duration_sec', av['duration_sec'])
        if 'total_dst_ports' in av:
            add_attribute_comment(event, 'total_dst_ports',
                                  av['total_dst_ports'])
        if 'total_ips' in av:
            add_attribute_comment(event, 'total_ips', av['total_ips'])
        if 'total_packets' in av:
            add_attribute_comment(event, 'total_packets', av['total_packets'])
        add_attribute_snort(event, snort)
        event.add_tag(tag='ddos attack')
    if 'amplifiers' in data:
        amp = data['amplifiers'][0]
        dfa = find_ips(amp)
        logging.info('Amplifier IPs found: {}'.format(len(dfa['ip'])))
        subnetsa = utils.smart_aggregate(dfa)
        logging.info('The IPs were summarized in: {} subnets'.format(
            len(subnetsa)))
        if args.subnets:
            add_attributes(event, subnetsa, 'ip-src', 'amplifier subnet')
            for elem in subnetsa:
                ddos.add_attribute('ip-src', elem, to_ids=0)
        else:
            add_attributes(event, dfa['ip'], 'ip-src', 'amplifier ip')
            for elem in dfa['ip']:
                ddos.add_attribute('ip-src', elem, to_ids=0)
        event.add_tag(tag='ddos amplification attack')
    p = pathlib.Path(args.fingerprint)
    comment = 'DDoS fingerprint json file generated by dissector'
    event.add_attribute(type='attachment',
                        value=p.name,
                        data=p,
                        comment=comment)
    event.add_object(ddos, pythonify=True)
    event = misp.add_event(event, pythonify=True)
Example #28
0
    def misp_send(self, strMISPEventID, strInput, strInfo, strUsername):
        # Establish communication with MISP.

        # The main processing block.
        try:
            objects = []
            # Get comments and tags from string input.
            str_comment, tags = self.get_comm_and_tags(strInput)
            if tags == None:
                self.misp_logger.info('Irate not in Tags: %s equals None' %
                                      tags)
                response = None
                return response
            # Setup misp objects.
            mispobj_email = pymisp.MISPObject(name="email")
            mispobj_file = pymisp.MISPObject(name="file")
            mispobj_files = {}
            mispobj_domainip = pymisp.MISPObject(name="domain-ip")
            url_no = 0
            file_no = 0
            mispobj_urls = {}

            for line in strInput.splitlines():
                # Catch domain and add to domain/IP object.
                if ("domain:" in line.lower()):
                    mispobj_domainip = pymisp.MISPObject(name="domain-ip")
                    vals = line.split(":", 1)
                    mispobj_domainip.add_attribute("domain",
                                                   value=vals[1].strip(),
                                                   comment=str_comment)
                    objects.append(mispobj_domainip)
                # Catch IP and add to domain/IP object.
                elif ("ip:" in line.lower()) or (
                        "ip-dst:" in line.lower()) or ("ip-src:"
                                                       in line.lower()):
                    if "domain:" in strInput.splitlines():
                        mispobj_domainip = pymisp.MISPObject(name="domain-ip")
                        vals = line.split(":", 1)
                        mispobj_domainip.add_attribute("ip",
                                                       value=vals[1].strip(),
                                                       comment=str_comment)
                        objects.append(mispobj_domainip)
                    else:
                        mispobj_network_connection = pymisp.MISPObject(
                            name="network-connection")
                        vals = line.split(":", 1)
                        if ("ip:" in line.lower()) or ("ip-dst:"
                                                       in line.lower()):
                            mispobj_network_connection.add_attribute(
                                "ip-dst",
                                type="ip-dst",
                                value=vals[1].strip(),
                                comment=str_comment)
                        else:
                            mispobj_network_connection.add_attribute(
                                "ip-src",
                                type="ip-src",
                                value=vals[1].strip(),
                                comment=str_comment)
                        objects.append(mispobj_network_connection)

                # Catch email and add to email object.
                elif ("source-email:" in line.lower()) or (
                        "email-source" in line.lower()) or ("from:"
                                                            in line.lower()):
                    vals = line.split(":", 1)
                    mispobj_email.add_attribute("from",
                                                value=vals[1].strip(),
                                                comment=str_comment)
                # Catch URL and add to URL object.
                elif ("url:" in line.lower()) or (
                    ('kit:' in line.lower() or ('creds:' in line.lower())) and
                    (('hxxp' in line.lower()) or ('http' in line.lower()))):
                    vals = line.split(":", 1)
                    url = vals[1].strip()
                    url = refang(url)
                    parsed = urlparse(url)
                    mispobj_url = pymisp.MISPObject(name="url")
                    mispobj_url.add_attribute("url",
                                              value=parsed.geturl(),
                                              category="Payload delivery",
                                              comment=str_comment)
                    if parsed.hostname:
                        mispobj_url.add_attribute("host",
                                                  value=parsed.hostname,
                                                  comment=str_comment)
                    if parsed.scheme:
                        mispobj_url.add_attribute("scheme",
                                                  value=parsed.scheme,
                                                  comment=str_comment)
                    if parsed.port:
                        mispobj_url.add_attribute("port",
                                                  value=parsed.port,
                                                  comment=str_comment)
                    mispobj_urls[url_no] = mispobj_url
                    url_no += 1

                # Catch different hash types, and add to file object.
                elif ("sha1:" in line.lower()) or ("SHA1:" in line):
                    vals = line.split(":", 1)
                    mispobj_file.add_attribute("sha1",
                                               value=vals[1].strip(),
                                               comment=str_comment)
                elif ("sha256:" in line.lower()) or ("SHA256:" in line):
                    vals = line.split(":", 1)
                    mispobj_file.add_attribute("sha256",
                                               value=vals[1].strip(),
                                               comment=str_comment)
                elif ("md5:" in line.lower()) or ("MD5:" in line):
                    vals = line.split(":", 1)
                    mispobj_file.add_attribute("md5",
                                               value=vals[1].strip(),
                                               comment=str_comment)
                # Catch subject and add to email object.
                elif ("subject:" in line.lower()):
                    self.misp_logger.info('adding subject')
                    vals = line.split(":", 1)
                    mispobj_email.add_attribute("subject",
                                                value=vals[1].strip(),
                                                comment=str_comment)
                # catch hash|filename pair and add to file object.
                elif ("hash|filename:" in line.lower()):
                    vals = line.split(":", 1)
                    val = vals[1].split("|")
                    l_hash = val[0]
                    l_filename = val[1]
                    l_mispobj_file = pymisp.MISPObject(name="file")
                    if len(re.findall(r"\b[a-fA-F\d]{32}\b", l_hash)) > 0:
                        l_mispobj_file.add_attribute("md5",
                                                     value=l_hash.strip(),
                                                     comment=str_comment)
                        l_mispobj_file.add_attribute("filename",
                                                     value=l_filename.strip(),
                                                     comment=str_comment)
                        mispobj_files[file_no] = l_mispobj_file
                    elif len(re.findall(r'\b[0-9a-f]{40}\b', l_hash)) > 0:
                        l_mispobj_file.add_attribute("sha1",
                                                     value=l_hash.strip(),
                                                     comment=str_comment)
                        l_mispobj_file.add_attribute("filename",
                                                     value=l_filename.strip(),
                                                     comment=str_comment)
                        mispobj_files[file_no] = l_mispobj_file
                    elif len(re.findall(r'\b[A-Fa-f0-9]{64}\b', l_hash)) > 0:
                        l_mispobj_file.add_attribute("sha256",
                                                     value=l_hash.strip(),
                                                     comment=str_comment)
                        l_mispobj_file.add_attribute("filename",
                                                     value=l_filename.strip(),
                                                     comment=str_comment)
                        mispobj_files[file_no] = l_mispobj_file
                    file_no += 1

            # Add all misp objects to List to be processed and submitted to MISP server as one.
            if len(mispobj_file.attributes) > 0:
                objects.append(mispobj_file)
            if len(mispobj_email.attributes) > 0:
                objects.append(mispobj_email)

            for _, u_value in mispobj_urls.items():
                if len(u_value.attributes) > 0:
                    objects.append(u_value)
            for _, f_value in mispobj_files.items():
                if len(f_value.attributes) > 0:
                    objects.append(f_value)
            # Update timestamp and event.

        except Exception:
            error = traceback.format_exc()
            response = "Error occured when converting string to misp objects:\n %s" % error
            self.misp_logger.error(response)
            return response

        if self.check_object_length(objects) != True:
            self.misp_logger.error(
                'Input from %s did not contain accepted tags.\n Input: \n%s' %
                (strUsername, strInput))
            return "Error in the tags you entered. Please see the guide for accepted tags."

        try:
            event = self.misp.new_event(info=strInfo,
                                        distribution='0',
                                        analysis='2',
                                        threat_level_id='3',
                                        published=True)
            misp_event = pymisp.MISPEvent()
            misp_event.load(event)
            self.submit_to_misp(self.misp, misp_event, objects)
            for tag in tags:
                self.misp.tag(misp_event.uuid, tag)
            self.misp.add_internal_comment(misp_event.id,
                                           reference="Author: " + strUsername,
                                           comment=str_comment)
            self.misp.fast_publish(misp_event.id, alert=False)
            misp_event = self.misp.get_event(misp_event.id)
            response = misp_event
            # for response in misp_event:
            if ('errors' in response and response['errors'] != None):
                return ("Submission error: " + repr(response['errors']))
            else:
                if response['Event']['RelatedEvent']:
                    e_related = ""
                    for each in response['Event']['RelatedEvent']:
                        e_related = e_related + each['Event']['id'] + ", "
                    return "Created ID: " + str(
                        response['Event']
                        ['id']) + "\nRelated Events: " + ''.join(e_related)
                else:
                    return "Created ID: " + str(response['Event']['id'])

        except Exception:
            error = traceback.format_exc()
            response = "Error occured when submitting to misp:\n %s" % error
            self.misp_logger.error(response)
            return response
Example #29
0
 def add_event(self, event: DtlMispEvent):
     """Add a new event into the misp. If the event already exist, it is ignored"""
     misp_event = pymisp.MISPEvent()
     misp_event.load(event)
     if not self.misp_backend.event_exists(misp_event):
         return self.misp_backend.add_event(misp_event, pythonify=True)
Example #30
0
    def parse(self, analysis_link: str, result: Dict[str,
                                                     Any]) -> pymisp.MISPEvent:
        """
        Parse the analysis result into a MISP event.

        :param str analysis_link: the analysis link
        :param dict[str, any] result: the JSON returned by the analysis client.
        :rtype: pymisp.MISPEvent
        :return: a MISP event
        """
        misp_event = pymisp.MISPEvent()

        # Add analysis subject info
        if "url" in result["analysis_subject"]:
            o = pymisp.MISPObject("url")
            o.add_attribute("url", result["analysis_subject"]["url"])
        else:
            o = pymisp.MISPObject("file")
            o.add_attribute("md5",
                            type="md5",
                            value=result["analysis_subject"]["md5"])
            o.add_attribute("sha1",
                            type="sha1",
                            value=result["analysis_subject"]["sha1"])
            o.add_attribute("sha256",
                            type="sha256",
                            value=result["analysis_subject"]["sha256"])
            o.add_attribute("mimetype",
                            category="Payload delivery",
                            type="mime-type",
                            value=result["analysis_subject"]["mime_type"])
        misp_event.add_object(o)

        # Add HTTP requests from url analyses
        network_dict = result.get("report", {}).get("analysis",
                                                    {}).get("network", {})
        for request in network_dict.get("requests", []):
            if not request["url"] and not request["ip"]:
                continue
            o = pymisp.MISPObject(name="http-request")
            o.add_attribute("method", "GET")
            if request["url"]:
                parsed_uri = parse.urlparse(request["url"])
                o.add_attribute("host", parsed_uri.netloc)
                o.add_attribute("uri", request["url"])
            if request["ip"]:
                o.add_attribute("ip-dst", request["ip"])
            misp_event.add_object(o)

        # Add network behaviors from files
        for subject in result.get("report", {}).get("analysis_subjects", []):

            # Add DNS requests
            for dns_query in subject.get("dns_queries", []):
                hostname = dns_query.get("hostname")
                # Skip if it is an IP address
                try:
                    if hostname == "wpad" or hostname == "localhost":
                        continue
                    # Invalid hostname, e.g., hostname: ZLKKJRPY or 2.2.0.10.in-addr.arpa.
                    if "." not in hostname or hostname[-1] == ".":
                        continue
                    _ = ipaddress.ip_address(hostname)
                    continue
                except ValueError:
                    pass

                o = pymisp.MISPObject(name="domain-ip")
                o.add_attribute("hostname", type="hostname", value=hostname)
                for ip in dns_query.get("results", []):
                    o.add_attribute("ip", type="ip-dst", value=ip)

                misp_event.add_object(o)

            # Add HTTP conversations (as network connection and as http request)
            for http_conversation in subject.get("http_conversations", []):
                o = pymisp.MISPObject(name="network-connection")
                o.add_attribute("ip-src", http_conversation["src_ip"])
                o.add_attribute("ip-dst", http_conversation["dst_ip"])
                o.add_attribute("src-port", http_conversation["src_port"])
                o.add_attribute("dst-port", http_conversation["dst_port"])
                o.add_attribute("hostname-dst", http_conversation["dst_host"])
                o.add_attribute("layer3-protocol", "IP")
                o.add_attribute("layer4-protocol", "TCP")
                o.add_attribute("layer7-protocol", "HTTP")
                misp_event.add_object(o)

                method, path, http_version = http_conversation["url"].split(
                    " ")
                if http_conversation["dst_port"] == 80:
                    uri = "http://{}{}".format(http_conversation["dst_host"],
                                               path)
                else:
                    uri = "http://{}:{}{}".format(
                        http_conversation["dst_host"],
                        http_conversation["dst_port"], path)
                o = pymisp.MISPObject(name="http-request")
                o.add_attribute("host", http_conversation["dst_host"])
                o.add_attribute("method", method)
                o.add_attribute("uri", uri)
                o.add_attribute("ip-dst", http_conversation["dst_ip"])
                misp_event.add_object(o)

        # Add sandbox info like score and sandbox type
        o = pymisp.MISPObject(name="sandbox-report")
        sandbox_type = "saas" if tau_clients.is_task_hosted(
            analysis_link) else "on-premise"
        o.add_attribute("score", result["score"])
        o.add_attribute("sandbox-type", sandbox_type)
        o.add_attribute("{}-sandbox".format(sandbox_type),
                        "vmware-nsx-defender")
        o.add_attribute("permalink", analysis_link)
        misp_event.add_object(o)

        # Add behaviors
        # Check if its not empty first, as at least one attribute has to be set for sb-signature object
        if result.get("malicious_activity", []):
            o = pymisp.MISPObject(name="sb-signature")
            o.add_attribute("software", "VMware NSX Defender")
            for activity in result.get("malicious_activity", []):
                a = pymisp.MISPAttribute()
                a.from_dict(type="text", value=activity)
                o.add_attribute("signature", **a)
            misp_event.add_object(o)

        # Add mitre techniques
        for techniques in result.get("activity_to_mitre_techniques",
                                     {}).values():
            for technique in techniques:
                for misp_technique_id, misp_technique_name in self.techniques_galaxy.items(
                ):
                    if technique["id"].casefold(
                    ) in misp_technique_id.casefold():
                        # If report details a sub-technique, trust the match
                        # Otherwise trust it only if the MISP technique is not a sub-technique
                        if "." in technique[
                                "id"] or "." not in misp_technique_id:
                            misp_event.add_tag(misp_technique_name)
                            break
        return misp_event