示例#1
0
def set_alchemy_node_sighting(aj, object_, an_package_id):
    LABEL_V2_WHERE_SIGHTED_REF = 'v2_where_sighted_ref'
    LABEL_V2_OBSERVED_DATA_REF = 'v2_observed_data_ref'

    node_id = convert_valid_node_id(object_['id'])
    title, description = get_common_title_description(
        object_, default_title=object_['id'], default_description='')
    keys = ['first_seen', 'last_seen', 'count', 'summary']
    for key in keys:
        if key in object_:
            description += get_description_string_from_attr(object_, key)
    an = AlchemyNode(node_id,
                     'v2_sighting',
                     title,
                     description,
                     cluster=an_package_id)
    an.set_stix2_object(object_)
    aj.add_json_node(an)
    set_created_by_ref_edge(aj, object_)
    if 'where_sighted_refs' in object_:
        for where_sighted_ref in object_['where_sighted_refs']:
            ae = AlchemyEdge(convert_valid_node_id(where_sighted_ref), node_id,
                             LABEL_V2_WHERE_SIGHTED_REF)
            aj.add_json_edge(ae)
    if 'observed_data_refs' in object_:
        for observed_data_ref in object_['observed_data_refs']:
            ae = AlchemyEdge(convert_valid_node_id(observed_data_ref), node_id,
                             LABEL_V2_OBSERVED_DATA_REF)
            aj.add_json_edge(ae)
    return
示例#2
0
def set_alchemy_node_threat_actor_v1(aj, threat_actor, an_tas_id, an_package_id):
    node_id = convert_valid_node_id(threat_actor.id_)
    an = AlchemyNode(node_id, 'Threat_Actor', threat_actor.title, threat_actor.description, cluster=an_package_id)
    aj.add_json_node(an)
    ae = AlchemyEdge(an_tas_id, node_id, LABEL_EDGE)
    aj.add_json_edge(ae)
    if threat_actor.observed_ttps:
        for observed_ttp in threat_actor.observed_ttps:
            relationship = observed_ttp.relationship if observed_ttp.relationship is not None else LABEL_UNSPECIFIED
            ae = AlchemyEdge(node_id, convert_valid_node_id(observed_ttp.item.idref), relationship)
            aj.add_json_edge(ae)
示例#3
0
def set_alchemy_node_indicator(aj, indicator, an_indicators_id=None, is_stix_v2=False, an_package_id=None):
    indicators_values = []

    if is_stix_v2:
        an_indicator_id = convert_valid_node_id(indicator['id'])
        value_list = []
        type_ = 'v2_indicator'
    else:
        an_indicator_id = convert_valid_node_id(indicator.id_)
        if indicator.observable is not None:
            value_list, type_ = get_observable_value(indicator.observable)
        else:
            value_list = []
            type_ = ''

    indicators_values.extend(value_list)

    title, description = get_alchemy_indicator_title_description(indicator, is_stix_v2)
    an = AlchemyNode(an_indicator_id, type_, title, description, cluster=an_package_id)
    if is_stix_v2:
        an.set_stix2_object(indicator)

    if is_stix_v2:
        type_, value = _get_indicator_type_value_stix2(indicator['pattern'])
        if type_:
            an._set_type(type_)
            an._set_caption(value)
            an.set_value(value)
        else:
            an.set_value(indicator['pattern'])
    else:
        if indicator.observable is not None:
            an.set_value(get_observable_value_string(indicator.observable))
    aj.add_json_node(an)

    if is_stix_v2:
        set_created_by_ref_edge(aj, indicator)
    else:
        ae = AlchemyEdge(an_indicators_id, an_indicator_id, LABEL_EDGE)
        aj.add_json_edge(ae)
        if indicator.observable is not None:
            if indicator.observable.idref is not None:
                ae = AlchemyEdge(an_indicator_id, convert_valid_node_id(indicator.observable.idref), LABEL_IDREF)
                aj.add_json_edge(ae)
        if indicator.indicated_ttps is not None:
            for ttp in indicator.indicated_ttps:
                ae = AlchemyEdge(an_indicator_id, convert_valid_node_id(ttp.item.idref), LABEL_IDREF)
                aj.add_json_edge(ae)
    return indicators_values
示例#4
0
def set_alchemy_node_relationship(aj, object_, an_package_id):
    source_ref = object_['source_ref']
    target_ref = object_['target_ref']
    relationship_type = object_['relationship_type']
    ae = AlchemyEdge(source_ref, target_ref, relationship_type)
    aj.add_json_edge(ae)
    return
示例#5
0
def set_alchemy_node_vulnerability(aj, object_, an_package_id):
    node_id = convert_valid_node_id(object_['id'])
    title, description = get_common_title_description(object_, default_title=object_['id'], default_description=object_['id'])
    keys = ['external_references']
    for key in keys:
        if key in object_:
            description += get_description_string_from_attr(object_, key)
    an = AlchemyNode(node_id, 'v2_Vulerability', title, description, cluster=an_package_id)
    an.set_stix2_object(object_)
    aj.add_json_node(an)
    set_created_by_ref_edge(aj, object_)
    index = 1
    if 'external_references' in object_:
        for external_reference in object_['external_references']:
            if 'source_name' in external_reference:
                if external_reference['source_name'] == 'cve':
                    if 'external_id' in external_reference:
                        cve = external_reference['external_id']
                        cve_node_id = convert_valid_node_id('%s-%s' % (node_id, cve))
                        cve_an = AlchemyNode(cve_node_id, 'v2_CVE', cve, cve, cluster=an_package_id)
                        aj.add_json_node(cve_an)
                        index += 1
                        cve_ae = AlchemyEdge(cve_node_id, node_id, LABEL_V2_OBJECT_REF)
                        aj.add_json_edge(cve_ae)
    return
示例#6
0
def set_alchemy_node_observable_v2(aj, object_, an_package_id):
    value_list = []
    node_id = convert_valid_node_id(object_['id'])
    for key, observable in object_['objects'].items():
        values, title, description, type_ = get_v2_observable_value(observable)
        value_list.extend(values)
        an_observable_id = '%s_%s' % (node_id, key)
        an = AlchemyNode(an_observable_id, type_, title, description, cluster=an_package_id)
        an.set_stix2_object(object_)
        aj.add_json_node(an)
        ae = AlchemyEdge(node_id, an_observable_id, LABEL_EDGE)
        aj.add_json_edge(ae)
    caption = node_id
    description = '<br/>\n'
    keys = ['first_observed', 'last_observed', 'number_observed']
    for key in keys:
        if key in object_:
            description += get_description_string_from_attr(object_, key)
    description += 'Values:<br/>\n'
    for v in value_list:
        description += ('%s<br/>\n' % (v))
    an = AlchemyNode(node_id, 'v2_observables-data', caption, description, cluster=an_package_id)
    an.set_stix2_object(object_)
    aj.add_json_node(an)
    set_created_by_ref_edge(aj, object_)
    return value_list
示例#7
0
def set_alchemy_node_et(aj, et, an_ets_id, an_package_id):
    node_id = convert_valid_node_id(et.id_)
    an = AlchemyNode(node_id, 'Exploit_Target', et.title, et.description, cluster=an_package_id)
    aj.add_json_node(an)
    ae = AlchemyEdge(an_ets_id, node_id, LABEL_EDGE)
    aj.add_json_edge(ae)
    return
示例#8
0
def set_alchemy_node_incident(aj, incident, an_incidents_id, an_package_id):
    node_id = convert_valid_node_id(incident.id_)
    an = AlchemyNode(node_id, 'Incident', incident.title, incident.description, cluster=an_package_id)
    aj.add_json_node(an)
    ae = AlchemyEdge(an_incidents_id, node_id, LABEL_EDGE)
    aj.add_json_edge(ae)
    return
示例#9
0
def set_alchemy_node_coa_v1(aj, coa, an_coas_id, an_package_id):
    node_id = convert_valid_node_id(coa.id_)
    an = AlchemyNode(node_id, 'Course_Of_Action', coa.title, coa.description, cluster=an_package_id)
    aj.add_json_node(an)
    ae = AlchemyEdge(an_coas_id, node_id, LABEL_EDGE)
    aj.add_json_edge(ae)
    return
示例#10
0
def set_alchemy_node_ttp(aj, ttp, an_ttps_id, an_package_id):
    node_id = convert_valid_node_id(ttp.id_)
    an = AlchemyNode(node_id, 'TTP', ttp.title, ttp.description, cluster=an_package_id)
    aj.add_json_node(an)
    ae = AlchemyEdge(an_ttps_id, node_id, LABEL_EDGE)
    aj.add_json_edge(ae)
    return
示例#11
0
def set_created_by_ref_edge(aj, dict_):
    if 'created_by_ref' in dict_:
        ae = AlchemyEdge(convert_valid_node_id(dict_['created_by_ref']),
                         convert_valid_node_id(dict_['id']),
                         LABEL_V2_CREATED_BY_REF)
        aj.add_json_edge(ae)
    return
示例#12
0
def related_package_nodes(request):
    request.session.set_expiry(SESSION_EXPIRY)
    if request.method != 'POST':
        r = {'status': 'NG',
             'message': 'Invalid HTTP method'}
        return JsonResponse(r, safe=False)
    r = check_allow_l2_view(request)
    if r is not None:
        return r
    base_package = get_l2_ajax_base_package(request)
    compared_package_ids = request.POST.getlist('check_packages[]')
    is_ip_similar_check = get_l2_ajax_related_campagins_similar_ip(request)
    is_domain_similar_check = get_l2_ajax_related_campagins_similar_domain(request)
    exact = True

    try:
        ctirs = Ctirs(request)
        ret = ctirs.get_contents_and_edges(base_package, exact, compared_package_ids, is_ip_similar_check, is_domain_similar_check)
        if ret is None:
            r = {'status': 'NG',
                 'message': ' /api/v1/gv/contents_and_edges has no data.'}
            return JsonResponse(r, safe=False)
    except BaseException:
        r = {'status': 'NG',
             'message': '/api/v1/gv/contents_and_edges error.'}
        return JsonResponse(r, safe=False)

    is_redact_confirm = get_l2_ajax_too_many_nodes(request)

    aj = AlchemyJsonData()
    for content in ret['contents']:
        set_alchemy_nodes(aj, content)

    aj.set_json_node_user_language(request.user.language)

    for object_ref, o_ in aj._json_nodes.items():
        if o_._stix2_object is not None:
            modified = o_._stix2_object['modified']
            language_contents = ctirs.get_language_contents(object_ref, modified)
            if len(language_contents) > 0:
                modify_alchemy_node_language_content(aj, language_contents[0])

    for edge in ret['edges']:
        start_node_id = convert_valid_node_id(edge['start_node']['node_id'])
        end_node_id = convert_valid_node_id(edge['end_node']['node_id'])
        aj.set_json_node_exact(start_node_id)
        aj.set_json_node_exact(end_node_id)
        ae = AlchemyEdge(start_node_id, end_node_id, edge['edge_type'])
        aj.add_json_edge(ae)

    ret_json = aj.get_alchemy_json(is_redact_confirm)
    if ret_json is None:
        ret_json = {'status': 'WARNING',
                    'message': 'Too many nodes'}
        return JsonResponse(ret_json, safe=False)

    return JsonResponse(ret_json, safe=False)
示例#13
0
def set_alchemy_node_custom_object(aj, object_, an_package_id):
    node_id = convert_valid_node_id(object_['id'])
    title, description = get_common_title_description(object_, default_title=object_['id'], default_description=object_['id'])
    an = AlchemyNode(node_id, 'v2_CustomObject', title, description, cluster=an_package_id)
    an.set_stix2_object(object_)
    aj.add_json_node(an)
    set_created_by_ref_edge(aj, object_)
    if 'object_refs' in object_:
        for observed_data_ref in object_['object_refs']:
            ae = AlchemyEdge(node_id, convert_valid_node_id(observed_data_ref), LABEL_V2_OBJECT_REF)
            aj.add_json_edge(ae)
    return
示例#14
0
def set_alchemy_node_campaign_v1(aj, campaign, an_campaigns_id, an_package_id):
    an_campaign_id = convert_valid_node_id(campaign.id_)
    an = AlchemyNode(an_campaign_id, 'Campaign', campaign.title, campaign.description, cluster=an_package_id)
    aj.add_json_node(an)
    ae = AlchemyEdge(an_campaigns_id, an_campaign_id, LABEL_EDGE)
    aj.add_json_edge(ae)
    if campaign.related_incidents is not None:
        for related_incident in campaign.related_incidents:
            relationship = related_incident.relationship if related_incident.relationship is not None else LABEL_UNSPECIFIED
            ae = AlchemyEdge(an_campaign_id, convert_valid_node_id(related_incident.item.idref), relationship)
            aj.add_json_edge(ae)
    if campaign.related_indicators is not None:
        for realated_indicator in campaign.related_indicators:
            relationship = realated_indicator.relationship if realated_indicator.relationship is not None else LABEL_UNSPECIFIED
            ae = AlchemyEdge(an_campaign_id, convert_valid_node_id(realated_indicator.item.idref), relationship)
            aj.add_json_edge(ae)
    if campaign.related_packages is not None:
        for related_package in campaign.related_packages:
            relationship = related_package.relationship if related_package.relationship is not None else LABEL_UNSPECIFIED
            ae = AlchemyEdge(an_campaign_id, convert_valid_node_id(related_package.item.idref), relationship)
            aj.add_json_edge(ae)
    if campaign.related_ttps is not None:
        for related_ttp in campaign.related_ttps:
            relationship = related_ttp.relationship if related_ttp.relationship is not None else LABEL_UNSPECIFIED
            ae = AlchemyEdge(an_campaign_id, convert_valid_node_id(related_ttp.item.idref), relationship)
            aj.add_json_edge(ae)
    if campaign.attribution is not None:
        for attribution in campaign.attribution:
            if attribution.threat_actor is not None:
                for threat_actor in attribution.threat_actor:
                    relationship = threat_actor.relationship if threat_actor.relationship is not None else LABEL_UNSPECIFIED
                    ae = AlchemyEdge(an_campaign_id, convert_valid_node_id(threat_actor.item.idref), relationship)
                    aj.add_json_edge(ae)
    return
示例#15
0
def set_alchemy_node_observable_v1(aj, observable, an_observables_id, an_package_id):
    node_id = convert_valid_node_id(observable.id_)
    value_list, type_ = get_observable_value(observable)
    title = ''
    if observable.title is not None:
        title = observable.title
    else:
        title = get_observable_value_string_from_list(value_list)
    an = AlchemyNode(node_id, type_, title, observable.description, cluster=an_package_id)
    an.set_value(get_observable_value_string(observable))
    aj.add_json_node(an)
    ae = AlchemyEdge(an_observables_id, node_id, LABEL_EDGE)
    aj.add_json_edge(ae)
    return value_list
示例#16
0
def set_alchemy_node_report(aj, object_, an_package_id):
    node_id = convert_valid_node_id(object_['id'])
    title, description = get_common_title_description(object_, default_title=object_['id'], default_description=object_['id'])
    keys = ['labels', 'published']
    for key in keys:
        if key in object_:
            description += get_description_string_from_attr(object_, key)
    an = AlchemyNode(node_id, 'v2_Report', title, description, cluster=an_package_id)
    an.set_stix2_object(object_)
    aj.add_json_node(an)
    set_created_by_ref_edge(aj, object_)
    if 'object_refs' in object_:
        for observed_data_ref in object_['object_refs']:
            ae = AlchemyEdge(node_id, convert_valid_node_id(observed_data_ref), LABEL_V2_OBJECT_REF)
            aj.add_json_edge(ae)
    return
示例#17
0
def set_alchemy_nodes(aj, content):
    if content['version'].startswith('2.'):
        is_stix_v2 = True
    else:
        is_stix_v2 = False

    package_name = content['package_name']
    if is_stix_v2:
        if isinstance(content, dict):
            package = content['dict']
        else:
            package = json.loads(content['dict'])
    else:
        package = STIXPackage.from_dict(content['dict'])

    if is_stix_v2:
        stix_header = None
    else:
        stix_header = package.stix_header

    if is_stix_v2:
        an_package_id = package['id']
    else:
        an_package_id = convert_valid_node_id(package.id_)

    an_header_id = an_package_id

    if is_stix_v2:
        indicators = []
        observables = []
        campaigns = []
        threat_actors = []
        coas = []
        identies = []
        malwares = []
        sightings = []
        intrusion_sets = []
        attack_patterns = []
        relationships = []
        reports = []
        tools = []
        vulnerabilities = []
        custom_objects = []

        locations = []
        opinions = []
        notes = []
        language_contents = []
        '''
        x_stip_snses = []
        '''

        ttps = None
        ets = None
        incidents = None

        for o_ in package['objects']:
            object_type = o_['type']
            if object_type == 'indicator':
                indicators.append(o_)
            elif object_type == 'identity':
                identies.append(o_)
            elif object_type == 'observed-data':
                observables.append(o_)
            elif object_type == 'malware':
                malwares.append(o_)
            elif object_type == 'sighting':
                sightings.append(o_)
            elif object_type == 'intrusion-set':
                intrusion_sets.append(o_)
            elif object_type == 'threat-actor':
                threat_actors.append(o_)
            elif object_type == 'attack-pattern':
                attack_patterns.append(o_)
            elif object_type == 'campaign':
                campaigns.append(o_)
            elif object_type == 'relationship':
                relationships.append(o_)
            elif object_type == 'course-of-action':
                coas.append(o_)
            elif object_type == 'report':
                reports.append(o_)
            elif object_type == 'tool':
                tools.append(o_)
            elif object_type == 'vulnerability':
                vulnerabilities.append(o_)
            elif object_type == 'location':
                locations.append(o_)
            elif object_type == 'opinion':
                opinions.append(o_)
            elif object_type == 'note':
                notes.append(o_)
            elif object_type == 'language-content':
                language_contents.append(o_)

            '''
            elif object_type == 'x-stip-sns':
                x_stip_snses.append(o_)
            '''
            if object_type == 'x-stip-sns':
                continue

            elif object_type.startswith('x-'):
                custom_objects.append(o_)
    else:
        indicators = package.indicators
        observables = package.observables
        campaigns = package.campaigns
        ttps = package.ttps
        threat_actors = package.threat_actors
        ets = package.exploit_targets
        coas = package.courses_of_action
        incidents = package.incidents

        identies = None
        malwares = None
        sightings = None
        intrusion_sets = None
        attack_patterns = None
        relationships = None
        reports = None
        tools = None
        vulnerabilities = None
        locations = None
        opinions = None
        notes = None
        language_contents = None
        custom_objects = None

    if not is_stix_v2:
        an = AlchemyNode(an_header_id, 'Header', package_name, stix_header.description, cluster=an_package_id)
        aj.add_json_node(an)

    if indicators is not None:
        if not is_stix_v2:
            an_indicators_id = an_package_id + '--indicators'
        else:
            an_indicators_id = None

        indicators_values = []
        for indicator in indicators:
            l = set_alchemy_node_indicator(aj, indicator, an_indicators_id, is_stix_v2, an_package_id)
            indicators_values.extend(l)

        if not is_stix_v2:
            an = AlchemyNode(an_indicators_id, 'Indicators', 'Indicators', '', cluster=an_package_id)
            an.set_value(get_observable_value_string_from_list(indicators_values))
            aj.add_json_node(an)
            ae = AlchemyEdge(an_header_id, an_indicators_id, LABEL_EDGE)
            aj.add_json_edge(ae)

    if observables is not None:
        if not is_stix_v2:
            an_observables_id = an_package_id + '--observables'
        else:
            an_observables_id = None
        obsevables_values = []
        for observed_data in observables:
            l = set_alchemy_node_observable(aj, observed_data, an_observables_id, is_stix_v2, an_package_id)
            obsevables_values.extend(l)

        if not is_stix_v2:
            an = AlchemyNode(an_observables_id, 'Observables', 'Observables', '', cluster=an_package_id)
            an.set_value(get_observable_value_string_from_list(obsevables_values))
            aj.add_json_node(an)
            ae = AlchemyEdge(an_header_id, an_observables_id, LABEL_EDGE)
            aj.add_json_edge(ae)

    if campaigns is not None:
        if not is_stix_v2:
            an_campaigns_id = an_package_id + '--campaigns'
            an = AlchemyNode(an_campaigns_id, 'Campaigns', 'Campaigns', '', cluster=an_package_id)
            aj.add_json_node(an)
            ae = AlchemyEdge(an_header_id, an_campaigns_id, LABEL_EDGE)
            aj.add_json_edge(ae)
        else:
            an_campaigns_id = None
        for campaign in campaigns:
            set_alchemy_node_campaign(aj, campaign, an_campaigns_id, is_stix_v2, an_package_id)

    if threat_actors is not None:
        if not is_stix_v2:
            an_tas_id = an_package_id + '--tas'
            an = AlchemyNode(an_tas_id, 'Threat_Actors', 'Threat_Actors', '', cluster=an_package_id)
            aj.add_json_node(an)
            ae = AlchemyEdge(an_header_id, an_tas_id, LABEL_EDGE)
            aj.add_json_edge(ae)
        else:
            an_tas_id = None
        for threat_actor in threat_actors:
            set_alchemy_node_threat_actor(aj, threat_actor, an_tas_id, is_stix_v2, an_package_id)

    if coas is not None:
        if not is_stix_v2:
            an_coas_id = an_package_id + '--coas'
            an = AlchemyNode(an_coas_id, 'Courses_Of_Action', 'Courses_Of_Action', '', cluster=an_package_id)
            aj.add_json_node(an)
            ae = AlchemyEdge(an_header_id, an_coas_id, LABEL_EDGE)
            aj.add_json_edge(ae)
        else:
            an_coas_id = None
        for coa in coas:
            set_alchemy_node_coa(aj, coa, an_coas_id, is_stix_v2, an_package_id)

    if ttps is not None:
        an_ttps_id = an_package_id + '--ttps'
        an = AlchemyNode(an_ttps_id, 'TTPs', 'TTPs', '', cluster=an_package_id)
        aj.add_json_node(an)
        ae = AlchemyEdge(an_header_id, an_ttps_id, LABEL_EDGE)
        aj.add_json_edge(ae)
        for ttp in ttps:
            set_alchemy_node_ttp(aj, ttp, an_ttps_id, an_package_id)

    if ets is not None:
        an_ets_id = an_package_id + '--ets'
        an = AlchemyNode(an_ets_id, 'Exploit_Targets', 'Exploit_Targets', '', cluster=an_package_id)
        aj.add_json_node(an)
        ae = AlchemyEdge(an_header_id, an_ets_id, LABEL_EDGE)
        aj.add_json_edge(ae)
        for et in ets:
            set_alchemy_node_et(aj, et, an_ets_id, an_package_id)

    if incidents is not None:
        an_incidents_id = an_package_id + '--incidents'
        an = AlchemyNode(an_incidents_id, 'Incidents', 'Incidents', '', cluster=an_package_id)
        aj.add_json_node(an)
        ae = AlchemyEdge(an_header_id, an_incidents_id, LABEL_EDGE)
        aj.add_json_edge(ae)
        for incident in incidents:
            set_alchemy_node_incident(aj, incident, an_incidents_id, an_package_id)

    if identies is not None:
        for identity in identies:
            set_alchemy_node_identity(aj, identity, an_package_id)

    if malwares is not None:
        for malware in malwares:
            set_alchemy_node_malware(aj, malware, an_package_id)

    if sightings is not None:
        for sighting in sightings:
            set_alchemy_node_sighting(aj, sighting, an_package_id)

    if intrusion_sets is not None:
        for intrusion_set in intrusion_sets:
            set_alchemy_node_intrusion_set(aj, intrusion_set, an_package_id)

    if attack_patterns is not None:
        for attack_pattern in attack_patterns:
            set_alchemy_node_attack_pattern(aj, attack_pattern, an_package_id)

    if reports is not None:
        for report in reports:
            set_alchemy_node_report(aj, report, an_package_id)

    if tools is not None:
        for tool in tools:
            set_alchemy_node_tool(aj, tool, an_package_id)

    if vulnerabilities is not None:
        for vulnerability in vulnerabilities:
            set_alchemy_node_vulnerability(aj, vulnerability, an_package_id)

    if locations is not None:
        for location in locations:
            set_alchemy_node_location(aj, location, an_package_id)

    if opinions is not None:
        for opinion in opinions:
            set_alchemy_node_opinion(aj, opinion, an_package_id)

    if notes is not None:
        for note in notes:
            set_alchemy_node_note(aj, note, an_package_id)

    if custom_objects is not None:
        for custom_object in custom_objects:
            set_alchemy_node_custom_object(aj, custom_object, an_package_id)

    '''
    if x_stip_snses is not None:
        for x_stip_sns in x_stip_snses:
            set_alchemy_node_x_stip_sns(aj, x_stip_sns, an_package_id)
    '''

    if relationships is not None:
        for relationship in relationships:
            set_alchemy_node_relationship(aj, relationship, an_package_id)
    return