def like(request): # Like元のパッケージID package_id = request.POST['package_id'] feed = Feed.get_feeds_from_package_id(request.user, package_id) # user は STIPUser stip_user = request.user # liker情報取得 likers = rs.get_likers_from_rs(stip_user, package_id) # すでにLikeされているか判定 # 自分自身の liker 文字列は instance_name + space + user_name myliker = '%s %s' % (SNSConfig.get_sns_identity_name(), stip_user.username) like = myliker in likers # Like/Unlike 用の STIX イメージ作成 feed_stix_like = FeedStixLike(feed, like, creator=stip_user) if like: # notify の unlike処理 stip_user.unotify_liked(package_id, feed.user) else: # notify の like処理 stip_user.notify_liked(package_id, feed.user) # 一時ファイルにstixの中身を書き出す tmp_file_path = write_like_comment_attach_stix( feed_stix_like.get_xml_content()) # RS に登録する rs.regist_ctim_rs(stip_user, feed_stix_like.file_name, tmp_file_path) os.remove(tmp_file_path) # 現在の Like 情報を取得する likers = rs.get_likers_from_rs(stip_user, package_id) return HttpResponse(len(likers))
def async_post(envelop, collection, taxii2_status, stip_user, community): pendings = [] bundle_objects = [] for object_ in envelop['objects']: object_id = object_['id'] modified = get_modified_from_object(object_) try: objects = StixObject.objects.filter(object_id=object_id, modified=modified) is_exist = False for object_ in objects: if not object_.deleted: is_exist = True break if is_exist: msg = 'Duplication Object(id: %s, modifed: %s)' % (object_id, modified) taxii2_status.failure(object_id, modified, msg) continue except StixObject.DoesNotExist: pass bundle_objects.append(object_) pendings.append((object_id, modified)) if len(bundle_objects) == 0: return bundle = Bundle(bundle_objects, allow_custom=True) try: _, stix2_file_path = tempfile.mkstemp() with open(stix2_file_path, 'w', encoding='utf-8') as fp: fp.write( bundle.serialize(True, ensure_ascii=False, include_optional_defaults=True)) rs.regist_ctim_rs(stip_user, bundle.id, stix2_file_path, community.name) except Exception as e: raise (e) finally: try: os.remove(stix2_file_path) except Exception: pass for object_id, modified in pendings: taxii2_status.success(object_id, modified) return
def post_comment(api_user, original_package_id, post, comment_user): # Feed 情報作成 origin_feed = Feed.get_feeds_from_package_id(api_user, original_package_id) # comment 作成 post = post.strip() if len(post) > 0: post = post[:10240] # Comment 用の STIX イメージ作成 feed_stix_comment = FeedStixComment(origin_feed, post, api_user) # 一時ファイルにstixの中身を書き出す tmp_file_path = write_like_comment_attach_stix( feed_stix_comment.get_xml_content()) # RS に登録する rs.regist_ctim_rs(api_user, feed_stix_comment.file_name, tmp_file_path) # 一時ファイルは削除 os.remove(tmp_file_path) # 通知 comment_user.notify_commented(original_package_id, origin_feed.user) notify_also_commented(original_package_id, origin_feed.user, comment_user)
def create_sighting_object(request): try: package_id = request.GET['package_id'] feed_id = request.GET['feed_id'] value_ = request.GET['value'] type_ = request.GET['type'] count = int(request.GET['count']) first_seen = request.GET['first_seen'] last_seen = request.GET['last_seen'] observable_id = request.GET['observable_id'] stip_user = request.user feed = Feed.get_feeds_from_package_id(stip_user, package_id) stix_file_path = Feed.get_cached_file_path(feed_id) stix2 = stip_sighting.convert_to_stix2_from_stix_file_path( stix_file_path) stix2 = stip_sighting.insert_sighting_object(stix2, type_, value_, observable_id, count, first_seen, last_seen, stip_user) stix2_str = stix2.serialize(True, ensure_ascii=False) _, stix2_file_path = tempfile.mkstemp() with open(stix2_file_path, 'w', encoding='utf-8') as fp: fp.write(stix2_str) # RS に登録する rs.regist_ctim_rs(feed.user, stix2.id, stix2_file_path) os.remove(stix2_file_path) file_name = '%s.json' % (stix2.id) output = io.StringIO() output.write(str(stix2_str)) response = HttpResponse(output.getvalue(), content_type='application/json') response['Content-Disposition'] = 'attachment; filename=%s' % ( file_name) return response except Exception as e: traceback.print_exc() return HttpResponseServerError(str(e))
def save_post(request, feed, post, json_indicators=[], ttps=[], tas=[], is_stix2=False, stix2_titles=[], stix2_contents=[]): if len(post) == 0: return None feed.post = post[:10240] # STIX 2.x 出力の場合は RS 登録する if is_stix2: bundle = get_stix2_bundle(json_indicators, ttps, tas, feed.title, post, stix2_titles, stix2_contents, request.user) feed.stix2_package_id = bundle.id _, stix2_file_path = tempfile.mkstemp() with open(stix2_file_path, 'w', encoding='utf-8') as fp: fp.write(bundle.serialize(True, ensure_ascii=False)) # RS に登録する rs.regist_ctim_rs(feed.user, bundle.id, stix2_file_path) os.remove(stix2_file_path) # stixファイルを作成する feed_stix = FeedStix(feed=feed, indicators=json_indicators, ttps=ttps, tas=tas) # Slack 投稿用の添付ファイル作成 if feed.files.count() > 1: # ファイルが複数 # ファイルが添付されている場合は file upload をコメント付きで temp = tempfile.NamedTemporaryFile() with zipfile.ZipFile(temp.name, 'w', compression=zipfile.ZIP_DEFLATED) as new_zip: for file_ in feed.files.all(): new_zip.write(file_.file_path, arcname=file_.file_name) upploaded_filename = 'uploaded_files.zip' elif feed.files.count() == 1: # ファイルが単数 temp = tempfile.NamedTemporaryFile() file_ = feed.files.get() with open(file_.file_path, 'rb') as fp: temp.write(fp.read()) temp.seek(0) upploaded_filename = file_.file_name else: temp = None feed.stix_file_path = write_stix_file(feed, feed_stix) # package_id取得 feed.package_id = feed_stix.get_stix_package().id_ # slack 投稿 if feed.user.username != const.SNS_SLACK_BOT_ACCOUNT: slack_post = '' slack_post += '[%s]\n' % (feed.title) slack_post += '\n' slack_post += '%s\n' % (ioc_fanger.defang(feed.post)) slack_post += '\n' slack_post += '---------- S-TIP Post Info (TLP: %s) ----------\n' % ( feed.tlp) slack_post += '%s: %s\n' % ('Account', feed.user.username) slack_post += '%s: %s\n' % ('Package_ID', feed.package_id) slack_post += '%s: %s\n' % ('Referred URL', feed.referred_url if feed.referred_url is not None else '') slack_post = slack_post.replace('&', '%amp;amp;') slack_post = slack_post.replace('<', '%amp;lt;') slack_post = slack_post.replace('>', '%amp;gt;') # Slack 投稿用の添付ファイル作成 from daemon.slack.receive import wc if wc is not None: post_slack_channel = SNSConfig.get_slack_bot_chnnel() if temp is not None: try: # ファイルが添付されている場合は file uplaod をコメント付きで wc.files_upload(initial_comment=slack_post, channels=post_slack_channel, file=open(temp.name, 'rb'), filename=upploaded_filename) finally: # 閉じると同時に削除される temp.close() else: try: wc.chat_postMessage(text=slack_post, channel=post_slack_channel, as_user='******') except Exception as _: pass # 添付 ファイルstixを送る for attachment_file in feed_stix.attachment_files: file_name = attachment_file.stix_header.title # 一時ファイルにstixの中身を書き出す tmp_file_path = write_like_comment_attach_stix( attachment_file.to_xml()) # RS に登録する rs.regist_ctim_rs(feed.user, file_name, tmp_file_path) # 登録後にファイルは削除 os.remove(tmp_file_path) # 添付ファイル STIX を RS に登録後、投稿 STIX を送る rs.regist_ctim_rs(feed.user, feed.title, feed.stix_file_path) # 添付ファイル削除 for file_ in feed.files.all(): os.remove(file_.file_path) # indicatorが存在していれば chatbot 起動する indicators = feed_stix.get_stix_package().indicators if indicators is not None and len(indicators) != 0: # chatbot指定があれば起動する if const.SNS_GV_CONCIERGE_ACCOUNT is not None: try: concierge_user = STIPUser.objects.get( username=const.SNS_GV_CONCIERGE_ACCOUNT) # 非同期で RS から matching 情報を取得しコメントをつける matching_comment_th = threading.Thread( target=post_rs_indicator_matching_comment, args=(request, feed, feed_stix.get_stix_package().id_, concierge_user)) matching_comment_th.daemon = True matching_comment_th.start() except Exception: pass if const.SNS_FALCON_CONCIERGE_ACCOUNT is not None: try: concierge_user = STIPUser.objects.get( username=const.SNS_FALCON_CONCIERGE_ACCOUNT) # 非同期で CrowdStrike から indicator に該当する report を取得しコメントをつける crowd_strike_report_th = threading.Thread( target=post_crowd_strike_indicator_matching_comment, args=(feed, feed_stix.get_stix_package().id_, concierge_user, json_indicators)) crowd_strike_report_th.daemon = True crowd_strike_report_th.start() except Exception: pass return