def _make_stix_package_for_attached_file(self, file_, feed): # package ID作成 package_id = self.generator.create_id(prefix='Package') # 添付ファイルの中身を読み込み base64 で encode with open(file_.file_path, 'rb') as fp: content = base64.b64encode(fp.read()) # content作成 marking_specification_content = self._make_marking_specification_statement( MARKING_STRUCTURE_STIP_ATTACHEMENT_CONTENT_PREFIX, content.decode('utf-8')) # filename作成 marking_specification_file_name = self._make_marking_specification_statement( MARKING_STRUCTURE_STIP_ATTACHEMENT_FILENAME_PREFIX, file_.file_name) # header 作成 stix_header = STIXHeader() stix_header.handling = self._get_stix_header_marking(feed) stix_header.handling.add_marking(marking_specification_content) stix_header.handling.add_marking(marking_specification_file_name) stix_header.title = file_.file_name stix_header.description = 'File "%s" encoded in BASE64.' % ( file_.file_name) # Information Source 格納 stix_header.information_source = self._make_information_source() # package作成 stix_package = STIXPackage(id_=package_id) stix_package.timestamp = datetime.datetime.now( tz=pytz.timezone(feed.user.timezone)) stix_package.stix_header = stix_header return stix_package
def _make_stix_package(self, origin_feed, post, creator=None): # package ID作成 package_id = self.generator.create_id(prefix='Package') # package作成 stix_package = STIXPackage(id_=package_id) stix_package.timestamp = datetime.datetime.now(tz=pytz.timezone(origin_feed.user.timezone)) # header格納 stix_package.stix_header = self._get_stix_header(origin_feed, post, creator) # Comment元の Feed の Package ID を Related Package に追加する stix_package.add_related_package(origin_feed.package_id) return stix_package
def _make_stix_package(self, feed, indicators=[], ttps=[], tas=[]): user_timezone = pytz.timezone(feed.user.timezone) # package ID作成 package_id = self.generator.create_id(prefix='Package') # package作成 stix_package = STIXPackage(id_=package_id) stix_package.timestamp = datetime.datetime.now(tz=user_timezone) # header格納 stix_package.stix_header = self._get_stix_header(feed) # indicators 格納 # web 画面から取得した indicators (json) から stix indicators 作成する stix_indicators = Indicators() for indicator_json in indicators: indicator = CommonExtractor.get_indicator_from_json( indicator_json, user_timezone) if indicator is not None: stix_indicators.append(indicator) stix_package.indicators = stix_indicators # ExploitTargets格納 stix_exploit_targets = ExploitTargets() for ttp_json in ttps: et = CommonExtractor.get_exploit_target_from_json(ttp_json) if et is not None: stix_exploit_targets.append(et) stix_package.exploit_targets = stix_exploit_targets # ThreatActors 格納 for ta_json in tas: value = ta_json['value'] if SNSConfig.get_cs_custid( ) is not None and SNSConfig.get_cs_custkey() is not None: ta = self.get_ta_from_crowd_strike(value) if ta is None: # ATT&CK から ThreatActor 取得する ta = self.get_ta_from_attck(value) else: ta = self.get_ta_from_attck(value) stix_package.add_threat_actor(ta) # 添付ファイル用の STIX 作成する for file_ in feed.files.all(): attach_file_stix_package = self._make_stix_package_for_attached_file( file_, feed) self.attachment_files.append(attach_file_stix_package) # 添付ファイル用の STIX を Related Pacakge に追加する stix_package.add_related_package(attach_file_stix_package.id_) return stix_package
def capsulize_patch(self, pkg_id, enable_bfs=False): contents = [] pkg = STIXPackage( id_=pkg_id, stix_header=generate_stix_header(self) ) def pkg_dispatch(eo): if isinstance(eo.obj, stixbase.DBStixBase): PACKAGE_ADD_DISPATCH[eo.ty](pkg, eo.obj._object) else: PACKAGE_ADD_DISPATCH[eo.ty](pkg, eo.obj) if enable_bfs: queue = [self.id_] completed_ids = set() while queue: eo_id = queue.pop() if eo_id in completed_ids: continue completed_ids.add(eo_id) if self.id_ == eo_id: eo = self #must do this as self may be a version other than latest else: try: eo = EdgeObject.load(eo_id, self.filters) except EdgeError: continue pkg_dispatch(eo) contents.append(eo) queue.extend([edge.id_ for edge in eo.edges]) else: pkg_dispatch(self) contents.append(self) return pkg, contents
def transform(data, new_only=True): """ transform - The transforms are source specific. Source: http://www.malwaredomainlist.com/hostslist/mdl.xml data - must be source xml converted to a dictionary :param data: :param new_only: :return: """ # Input validation if not isinstance(data, dict): return False work = [] history = db('local_file', 'history', ADPTR_SRC_ID) value2key = db('local_file', 'value_to_key', 'values') items = data.get('rss', {}).get('channel', {}).get('item') if items: for item in items: guid = item.get('guid', {}).get('#text') if guid: # Check to see if this item has been process before # if not, add to work if guid in history: if not new_only: work.append(item) else: work.append(item) db('local_file', 'history', ADPTR_SRC_ID, {guid: { 'date': str(datetime.now()) }}) if work: ### Generate STIXPackage and STIXHeader set_ns_stix(ADPTR_NS_STIX) set_ns_cybox(ADPTR_NS_CYBOX) STIXPackage._version = ADPTR_VER_STIX pkg = STIXPackage() src_info, value2key = gen_info_src({}, 'www.malwaredomainlist.com', value2key) hdr = STIXHeader() hdr.title = data.get('rss', {}).get('channel', {}).get('title') hdr.description = data.get('rss', {}).get('channel', {}).get('description') hdr.information_source = src_info pkg.stix_header = hdr for item in work: key = item.get('guid', {}).get('#text') # Decompose data description tmp = [x.strip() for x in item.get('description').split(',')] decomp = {} for x in tmp: k, v = x.split(':') decomp.update({k.strip(): v.strip()}) # Generate STIX Indicator ind, history = gen_indicator(item, key, history) ind.producer = src_info ind.short_description = 'MDL RefID: %s | %s' % ( key, decomp.get('Description')) # Decompose host host = decomp.get('Host') uri = None file_ = None if '/' in host: host, uri = host.split('/', 1) # TODO: parse out file Name if host: # Generate Cybox HostName obj = Hostname() obj.is_domain_name = True obj.naming_system = 'DNS' obj.hostname_value = host ob, value2key = gen_CyboxOb(obj, host, value2key) ob.title = 'HostName: %s' % obj.hostname_value ind.add_observable(CyboxOb(idref=ob.id_)) pkg.add_observable(ob) if uri: # Generate Cybox URI obj = URI() obj.type_ = URI.TYPE_URL url = AnyURI('%s/%s' % (host, uri)) obj.value = url ob, value2key = gen_CyboxOb(obj, url, value2key) ob.title = 'URL: %s' % url ind.add_observable(CyboxOb(idref=ob.id_)) pkg.add_observable(ob) if file_: obj = File() ip = decomp.get('IP address') if ip: obj_ip = Address() if isIPv4(ip): obj_ip.category = Address.CAT_IPV4 elif isIPv6(ip): obj_ip.category = Address.CAT_IPV6 else: break obj_ip.is_source = True obj_ip.address_value = ip # if obj_host: # obj_ip.add_related(obj_host, # ObjectRelationship.TERM_RESOLVED_TO, # inline=False) ob = CyboxOb(obj_ip) ob.title = 'IP: %s' % ip ind.add_observable(CyboxOb(idref=ob.id_)) pkg.add_observable(ob) asn = decomp.get('ASN') if asn: obj_asn = Address() obj_asn.category = Address.CAT_ASN obj_asn.address_value = asn # if obj_host: # obj_asn.add_related(obj_host, # ObjectRelationship.TERM_CONNECTED_TO, # inline=False) # if obj_ip: # obj_asn.add_related(obj_ip, # ObjectRelationship.TERM_CONNECTED_TO, # inline=False) ob = CyboxOb(obj_asn) ob.title = 'ASN: %s' % ip ind.add_observable(CyboxOb(idref=ob.id_)) pkg.add_observable(ob) pkg.add_indicator(ind) db('local_file', 'value_to_key', 'values', value2key) db('local_file', 'history', ADPTR_SRC_ID, history) return pkg
def _get_stix_header_marking(self, feed, creator=None): if creator is None: user = feed.user else: user = creator s = STIXPackage() if user.region is not None: country_name_code = user.region.country_code admin_area_name_code = user.region.code else: country_name_code = user.country_code admin_area_name_code = None industry_type = ais.OTHER organisation_name = ais.OTHER ais_tlp = feed.tlp # REDの場合はAISではエラーとなるのでNoneとする if ais_tlp == 'RED': ais_tlp = None ais.add_ais_marking(s, False, 'EVERYONE', ais_tlp, country_name_code=country_name_code, country_name_code_type='ISO_3166-1_alpha-2', admin_area_name_code=admin_area_name_code, organisation_name=organisation_name, industry_type=industry_type, admin_area_name_code_type="ISO_3166-2", ) ais_marking_specification = s.stix_header.handling.marking[0] # Marking作成 marking = Marking() marking.add_marking(ais_marking_specification) # 汎用のTLPmarking_specification作成 marking_specification = self._get_tlp_marking_structure(feed) marking.add_marking(marking_specification) # Critical Infrastructure marking_critical_infrastructure = self._make_marking_specification_statement(const.STIP_SNS_CI_KEY, user.ci) marking.add_marking(marking_critical_infrastructure) # スクリーン名 marking_screen_name = self._make_marking_specification_statement(const.STIP_SNS_SCREEN_NAME_KEY, user.get_screen_name()) marking.add_marking(marking_screen_name) # username marking_user_name = self._make_marking_specification_statement(const.STIP_SNS_USER_NAME_KEY, user.username) marking.add_marking(marking_user_name) # 会社名 marking_affiliation = self._make_marking_specification_statement(const.STIP_SNS_AFFILIATION_KEY, user.affiliation) marking.add_marking(marking_affiliation) # region code if user.region is not None: marking_region_code = self._make_marking_specification_statement(const.STIP_SNS_REGION_CODE_KEY, user.region.code) marking.add_marking(marking_region_code) # Sharing Range if feed.sharing_range_type == const.SHARING_RANGE_TYPE_KEY_ALL: sharing_range = 'CIC Community' elif feed.sharing_range_type == const.SHARING_RANGE_TYPE_KEY_GROUP: sharing_range = 'Group: %s' % (feed.sharing_group.en_name) elif feed.sharing_range_type == const.SHARING_RANGE_TYPE_KEY_PEOPLE: sharing_range = 'People: ' feed.save() for sharing_stip_user in feed.tmp_sharing_people: sharing_range += sharing_stip_user.username sharing_range += ',' # 最後の改行を取り除く sharing_range = sharing_range[:-1] marking_sharing_range = self._make_marking_specification_statement('Sharing Range', sharing_range) marking.add_marking(marking_sharing_range) # referred_url if feed.referred_url is not None: marking_referred_url = self._make_marking_specification_statement(const.STIP_SNS_REFERRED_URL_KEY, feed.referred_url) marking.add_marking(marking_referred_url) # stix2_package_id if feed.stix2_package_id is not None and len(feed.stix2_package_id) != 0: marking_stix2_package_id = self._make_marking_specification_statement(const.STIP_SNS_STIX2_PACKAGE_ID_KEY, feed.stix2_package_id) marking.add_marking(marking_stix2_package_id) return marking