Ejemplo n.º 1
0
    def create_attr(self, raw_attr: dict) -> MISPAttribute:
        # Create attribute and assign simple values
        attr = MISPAttribute()
        attr.type = 'url'
        attr.value = raw_attr['url']
        attr.disable_correlation = False
        attr.__setattr__('first_seen', datetime.strptime(raw_attr['dateadded'], '%Y-%m-%d %H:%M:%S'))
        # Add URLhaus tag
        self.add_tag_to_attribute(attr, 'URLhaus')
        # Add other tags
        if raw_attr['tags']:
            for tag in raw_attr['tags'].split(','):
                self.add_tag_to_attribute(attr, tag.strip())

        # Add online/offline tag
        if not pandas.isna(raw_attr['url_status']):
            if raw_attr['url_status'] == 'online':
                attr.to_ids = True
            else:
                attr.to_ids = False
            self.add_tag_to_attribute(attr, raw_attr['url_status'])

        # Add reporter tag
        if not pandas.isna(raw_attr['reporter']):
            self.add_tag_to_attribute(attr, raw_attr['reporter'])

        attr.comment = raw_attr['urlhaus_link']
        return attr
Ejemplo n.º 2
0
def generate_MISP_Event(deduplicated_observations, conf, tags, attr_tags):
    dt = datetime.now()

    event = MISPEvent()
    event.info = dt.strftime("%Y%m%d ") + 'TIE'
    event.publish_timestamp = dt.strftime("%s")
    event.timestamp = dt.strftime("%s")
    event['timestamp'] = dt.strftime("%s")
    event.analysis = 2
    event.published = conf.event_published
    orgc = MISPOrganisation()
    orgc.from_json(json.dumps({'name': conf.org_name, 'uuid': conf.org_uuid}))
    event.orgc = orgc
    event.threat_level_id = conf.event_base_thread_level
    event.date = dt
    event['uuid'] = str(uuid.uuid1())
    if len(tags) > 0:
        event['Tag'] = tags

    attr_hashes = []

    for key, attr in deduplicated_observations.items():
        misp_attr = MISPAttribute()
        misp_attr.timestamp = dt.strftime("%s")
        misp_attr['timestamp'] = dt.strftime("%s")
        misp_attr.type = get_Attribute_Type(attr)
        misp_attr.value = get_MISP_Fitted_Value(attr["value"], misp_attr.type)
        if 'c2-server' in attr['categories'] and attr_tags.c2tags:
            misp_attr['Tag'] = attr_tags.c2tags
        if 'malware' in attr['categories'] and attr_tags.malwaretags:
            misp_attr['Tag'] = attr_tags.malwaretags
        if 'espionage' in attr['categories'] and attr_tags.espionagetags:
            misp_attr['Tag'] = attr_tags.espionagetags
        if 'bot' in attr['categories'] and attr_tags.bottags:
            misp_attr['Tag'] = attr_tags.bottags
        if 'whitelist' in attr['categories'] and attr_tags.whitelisttags:
            misp_attr['Tag'] = attr_tags.whitelisttags
        if 'cybercrime' in attr['categories'] and attr_tags.cybercrimetags:
            misp_attr['Tag'] = attr_tags.cybercrimetags
        if 'phishing' in attr['categories'] and attr_tags.phishingtags:
            misp_attr['Tag'] = attr_tags.phishingtags
        misp_attr.category = get_Attribute_Category(attr)
        if conf.attr_to_ids and attr[
                'min_confidence'] >= conf.attr_to_ids_threshold:
            misp_attr.to_ids = True
        else:
            misp_attr.to_ids = False
        misp_attr['comment'] = 'categories: ' + str(attr['categories']) + ' actors: ' + str(attr['actors']) + \
                               ' families: ' + str(attr['families']) + ' sources: ' + str(attr['sources']) + \
                               ' severity: ' + str(attr['max_severity']) + \
                               ' confidence: ' + str(attr['max_confidence'])
        misp_attr.edited = False
        event.add_attribute(**(misp_attr.to_dict()))
        attr_hashes.append([
            hashlib.md5(attr['value'].encode("utf-8")).hexdigest(),
            event['uuid']
        ])

    event.edited = False
    return event, attr_hashes
Ejemplo n.º 3
0
 def create_new_event(self, entry):
     attribute = MISPAttribute()
     attribute.type = "malware-sample"
     attribute.value = entry["shasum"]
     attribute.data = Path(entry["outfile"])
     attribute.comment = "File uploaded to Cowrie ({})".format(entry["sensor"])
     attribute.expand = "binary"
     if "url" in entry:
         attributeURL = MISPAttribute()
         attributeURL.type = "url"
         attributeURL.value = entry["url"]
         attributeURL.to_ids = True
     else:
         attributeURL = MISPAttribute()
         attributeURL.type = "text"
         attributeURL.value = "External upload"
     attributeIP = MISPAttribute()
     attributeIP.type = "ip-src"
     attributeIP.value = entry["src_ip"]
     attributeDT = MISPAttribute()
     attributeDT.type = "datetime"
     attributeDT.value = entry["timestamp"]
     event = MISPEvent()
     event.info = "File uploaded to Cowrie ({})".format(entry["sensor"])
     event.add_tag("tlp:white")
     event.attributes = [attribute, attributeURL, attributeIP, attributeDT]
     event.run_expansions()
     if self.publish:
         event.publish()
     result = self.misp_api.add_event(event)
     if self.debug:
         log.msg(f"Event creation result: \n{result}")
Ejemplo n.º 4
0
def toggle_attribute(misp: pymisp.api.PyMISP, attr: pymisp.MISPAttribute):
    """
    First turns off the 'to_ids' flag for the given MISP Attribute, then turns
    it on. Once this function exits, the Attribute will always be left with
    'to_ids' enabled.
    @param misp The PyMISP instance to use
    @param attr The MISP Attribute to toggle
    """
    attr.to_ids = False
    resp = misp.update_attribute(attr)
    if not resp or resp.get("errors", {}):
        logger.error(f"Error disabling 'to_ids' flag for Attribute {attr}")
    attr.to_ids = True
    resp = misp.update_attribute(attr)
    if not resp or resp.get("errors", {}):
        logger.error(f"Error enabling 'to_ids' flag for Attribute {attr}")
        return
    logger.info(f"Toggled 'to_ids' flag for Attibute {attr}")
Ejemplo n.º 5
0
def propose(type, value, category):
    attr_type = type
    value = value
    category = category
    to_ids = False

    # Attribute data already defined
    attribute = MISPAttribute()
    attribute.type = attr_type
    attribute.value = value
    attribute.category = category
    attribute.to_ids = to_ids

    event_id = EVENTid
    proposal = misp.add_attribute_proposal(event_id, attribute)
    print('Proposed!')
Ejemplo n.º 6
0
 def create_attr_azorult(self, raw_attr: dict) -> MISPAttribute:
     attr_list = []
     for type in [{'json': 'domain', 'misp': 'domain'},
                  {'json': 'ip', 'misp': 'ip-dst'},
                  {'json': 'panel_index', 'misp': 'url'}]:
         if type['json'] in raw_attr:
             attr = MISPAttribute()
             self.add_tag_to_attribute(attr, 'AzorultTracker')
             self.add_tag_to_attribute(attr, raw_attr['panel_version'])
             self.add_tag_to_attribute(attr, raw_attr['feeder'])
             self.add_tag_to_attribute(attr, raw_attr['status'])
             attr.comment = f'Azorult panel {type["misp"]}'
             attr.__setattr__('first_seen', datetime.fromtimestamp(raw_attr['first_seen']))
             attr.to_ids = False
             attr.disable_correlation = False
             attr.type = type['misp']
             attr.value = f"{raw_attr[type['json']]}"
             attr_list.append(attr)
     return attr_list
Ejemplo n.º 7
0
 def create_attr_feodo(self, raw_attr: dict) -> MISPAttribute:
     attr = MISPAttribute()
     attr.type = 'ip-dst|port'
     attr.value = f"{raw_attr['DstIP']}|{raw_attr['DstPort']}"
     self.add_tag_to_attribute(attr, 'FeodoTracker')
     self.add_tag_to_attribute(attr, raw_attr['Malware'])
     attr.comment = 'Feodo tracker DST IP/port'
     attr.__setattr__('first_seen', datetime.strptime(raw_attr['Firstseen'], '%Y-%m-%d %H:%M:%S'))
     if not pandas.isna(raw_attr['LastOnline']):
         last_seen_time = datetime.strptime(str(raw_attr['LastOnline']), '%Y-%m-%d').replace(tzinfo=pytz.utc)
         first_seen_time = datetime.strptime(str(raw_attr["Firstseen"]), '%Y-%m-%d %H:%M:%S').replace(tzinfo=pytz.utc)
         if first_seen_time > last_seen_time:
             last_seen_time = first_seen_time + timedelta(seconds=1)
         attr.__setattr__('last_seen', last_seen_time)
     else:
         last_seen_time = datetime.strptime(str(raw_attr['Firstseen']), '%Y-%m-%d %H:%M:%S').replace(tzinfo=pytz.utc)
         attr.__setattr__('last_seen', last_seen_time)
     attr.to_ids = False
     attr.disable_correlation = False
     return attr
Ejemplo n.º 8
0
def search_vmray_incomplete(
        m, url, wait_period, module_import_url, module_import_port, vmray_url,
        vmray_api, vmray_attribute_category, vmray_include_analysisid,
        vmray_include_imphash_ssdeep, vmray_include_extracted_files,
        vmray_include_analysisdetails, vmray_include_vtidetails,
        custom_tags_incomplete, custom_tags_complete):
    controller = 'attributes'
    vmray_value = 'VMRay Sample ID:'  # How sample IDs are stored in MISP
    req = None

    # Search for the events
    try:
        result = m.search(controller, tags=custom_tags_incomplete)

        attribute = result['Attribute']

        if len(attribute) == 0:
            sys.exit("No VMRay attributes found that match %s" %
                     custom_tags_incomplete)

        timestamp = int(attribute[0]["timestamp"])
        # Not enough time has gone by to lookup the analysis jobs
        if int((time.time() - timestamp) / 60) < int(wait_period):
            if module_DEBUG:
                r_timestamp = datetime.datetime.fromtimestamp(
                    timestamp).strftime('%Y-%m-%d %H:%M:%S')
                print(
                    "Attribute to recent for wait_period (%s minutes) - timestamp attribute: %s (%s minutes old)"
                    % (wait_period, r_timestamp,
                       round((int(time.time() - timestamp) / 60), 2)))
            return False

        if module_DEBUG:
            print("All attributes older than %s" % int(wait_period))

        for att in attribute:
            value = att['value']

            if vmray_value in value:  # We found a sample ID
                att_id = att['id']
                att_uuid = att['uuid']

                # VMRay Sample IDs are stored as VMRay Sample ID: 2796577
                vmray_sample_id = value.split(vmray_value)[1].strip()
                if vmray_sample_id.isdigit():
                    event_id = att['event_id']

                    if module_DEBUG:
                        print(
                            "Found event %s with matching tags %s for sample id %s "
                            % (event_id, custom_tags_incomplete,
                               vmray_sample_id))

                    # Prepare request to send to vmray_import via misp modules
                    misp_modules_url = module_import_url + ':' + module_import_port + '/query'
                    misp_modules_headers = {'Content-Type': 'application/json'}
                    misp_modules_body = '{ "sample_id":"' + vmray_sample_id + '","module":"vmray_import","event_id":"' + event_id + '","config":{"apikey":"' + vmray_api + '","url":"' + vmray_url + '","include_analysisid":"' + vmray_include_analysisid + '","include_analysisdetails":"' + vmray_include_analysisdetails + '","include_extracted_files":"' + vmray_include_extracted_files + '","include_imphash_ssdeep":"' + vmray_include_imphash_ssdeep + '","include_vtidetails":"' + vmray_include_vtidetails + '","sample_id":"' + vmray_sample_id + '"},"data":""}'
                    req = requests.post(misp_modules_url,
                                        data=misp_modules_body,
                                        headers=misp_modules_headers)
                    if module_DEBUG and req is not None:
                        print(
                            "Response code from submitting to MISP modules %s"
                            % (req.status_code))

                    # Succesful response from the misp modules?
                    if req.status_code == 200:
                        req_json = req.json()
                        if "error" in req_json:
                            print("Error code in reply %s " %
                                  req_json["error"])
                            continue
                        else:
                            results = req_json["results"]

                            # Walk through all results in the misp-module reply
                            for el in results:
                                to_ids = True
                                values = el['values']
                                types = el['types']
                                if "to_ids" in el:
                                    to_ids = el['to_ids']
                                if "text" in types:
                                    to_ids = False
                                comment = el['comment']
                                if len(comment) < 1:
                                    comment = "Enriched via the vmray_import module"

                                # Attribute can belong in different types
                                for attr_type in types:
                                    try:
                                        new_attribute = MISPAttribute()
                                        new_attribute.type = attr_type
                                        new_attribute.category = vmray_attribute_category
                                        new_attribute.value = values
                                        new_attribute.to_ids = to_ids
                                        new_attribute.comment = comment
                                        r = m.add_attribute(
                                            event_id, new_attribute)
                                        if module_DEBUG:
                                            print(
                                                "Add event %s: %s as %s (%s) (toids: %s)"
                                                % (event_id, values, attr_type,
                                                   comment, to_ids))
                                    except Exception as e:
                                        if module_DEBUG:
                                            print(
                                                "Unable to add attribute %s as type %s for event %s"
                                                %
                                                (values, attr_type, event_id))
                                        continue

                            # Remove 'incomplete' state tags
                            m.untag(att_uuid, custom_tags_incomplete)
                            # Update tags to 'complete' state
                            m.tag(att_uuid, custom_tags_complete)
                            if module_DEBUG:
                                print("Updated event %s" % event_id)

                    else:
                        sys.exit(
                            'MISP modules did not return HTTP 200 code (event %s ; sampleid %s)'
                            % (event_id, vmray_sample_id))

    except Exception as e:
        sys.exit("Invalid response received from MISP : %s", e)
Ejemplo n.º 9
0
def poll_taxii():
    global f_hashes, f_manifest, f_events
    results_dict = {}
    client = create_client(
        CYBERSAIYAN_FEED_URL,
        use_https=TAXII_USE_TLS,
        discovery_path=TAXII_DISCOVERY_PATH
    )

    blocks = client.poll(collection_name=CYBERSAIYAN_COLLECTION_NAME)

    for block in blocks:
        content = block.content
        if content:
            if type(content) == str:
                continue
            elif type(content) == bytes:
                content = content.decode('utf-8')
        pkg = STIXPackage.from_xml(StringIO(content))

        title = pkg.stix_header.title
        information_source = pkg.stix_header.information_source.identity.name

        cs_event = (title, information_source)
        cs_event_hash = hash(cs_event)


        db_cursor.execute("SELECT uuid FROM hashes WHERE hash = '%s'" % cs_event_hash)
        element = db_cursor.fetchone()
        if element:
            e_uuid = element[0]
        else:
            e_uuid = str(uuid.uuid4())
            db_cursor.execute("INSERT INTO hashes VALUES (?,?)", (cs_event_hash,e_uuid,))

        if cs_event_hash not in results_dict:
            results_dict[cs_event_hash] = MISPEvent()

        m_ev = results_dict[cs_event_hash]
        m_ev.info = str(pkg.stix_header.description)
        m_ev.analysis = 0
        m_ev.uuid = e_uuid

        #m_ev.org = "CyberSaiyan"

        csorg = MISPOrganisation()
        csorg.name = "CyberSaiyan"
        csorg.uuid = "8aaa81ed-72ef-4fb1-8e96-fa1bc200faeb"
        m_ev.orgc = csorg

        marking = pkg.stix_header.handling.marking
        tlp = 0
        found_tlp = False
        for m in marking:
            for struct in m.marking_structures:
                if struct._XSI_TYPE == "tlpMarking:TLPMarkingStructureType":
                    found_tlp = True
                    tlp = max(TLP[struct.color.lower()], tlp)
        if tlp == 0 and not found_tlp:
            tlp = TLP["amber"]
        m_ev.add_tag("tlp:"+TLP[tlp])
        m_ev.add_tag("CyberSaiyan")

        indicators = pkg.indicators
        last_ts = utc.localize(datetime.datetime(1970,1,1))
        for indicator in indicators:
            cur_ts = indicator.timestamp
            if cur_ts > last_ts:
                last_ts = cur_ts
            obj = indicator.observable.object_
            obj_d = obj.properties.to_dict()

            attr_type = obj_d["xsi:type"]
            if attr_type == "AddressObjectType":

                attr = MISPAttribute()
                attr.category = "Network activity"
                attr.type = "ip-dst"
                attr.value = obj_d["address_value"]
                attr.disable_correlation = False
                attr.to_ids = True

            elif attr_type == "DomainNameObjectType":

                attr = MISPAttribute()
                attr.category = "Network activity"
                attr.type = "domain"
                attr.value = obj_d["value"]
                attr.disable_correlation = False
                attr.to_ids = True

            elif attr_type == "URIObjectType":

                attr = MISPAttribute()
                attr.category = "Network activity"
                attr.type = "url"
                attr.value = obj_d["value"]
                attr.disable_correlation = False
                attr.to_ids = True


            elif attr_type == "FileObjectType":
                hash_type = obj_d["hashes"][0]["type"]["value"].lower()
                hash_value = obj_d["hashes"][0]["simple_hash_value"]

                attr = MISPAttribute()
                attr.category = "Payload delivery"
                assert hash_type in ('md5', "sha1", "sha224",
                                     "sha256", "sha384", "sha512", "ssdeep")
                attr.type = hash_type
                attr.value = hash_value
                attr.disable_correlation = False
                attr.to_ids = True

            m_ev.date = last_ts.strftime("%Y-%m-%d")
            m_ev.attributes.append(attr)

    db_conn.commit()
    c_hashes, c_manifest, c_events = list(), dict(), dict()

    for event in results_dict.values():
        e_feed = event.to_feed(with_meta=True).get("Event")
        c_hashes += [[h, event.uuid] for h in e_feed.pop("_hashes")]
        c_manifest.update(e_feed.pop('_manifest'))
        c_events[event.uuid] = e_feed

    f_hashes, f_manifest, f_events = c_hashes, c_manifest, c_events
Ejemplo n.º 10
0
#     one level of sample crawling. i.e. all samples refered
#     to by sampled tagged COVID-19 will be included in the Event
for hash, sample in samples.copy().items():

    # get a detailed report of the sample
    details = getSampleDetail(hash)
    if (details is not None):
        # if it exists, add the comment
        if ('comment' in details):
            comment = details['comment']
            if (comment is not None):
                newattr = MISPAttribute()
                newattr.category = commattr['category']
                newattr.type = commattr['type']
                newattr.value = commattr['value']
                newattr.to_ids = commattr['to_ids']
                sample.add_reference(referenced_uuid=newattr.uuid,
                                     relationship_type='related-to')
                attributes.update({newattr.value: newattr})

        # find and add x-references
        if ('file_information' in details):
            info = details['file_information']

            if (info is not None):
                for context_set in info:
                    context = context_set['context']
                    value = context_set['value']

                    print("context: {}, value: {}".format(context, value))