ThreatFox から収集した イベントの一例です。

イベントには複数の IoC が登録されていますが、それぞれの IoC についてどのマルウェアの C2 なのかが記載されています。

WHY DON'T YOU DO YOUR BEST!!
ThreatFox から収集した イベントの一例です。

イベントには複数の IoC が登録されていますが、それぞれの IoC についてどのマルウェアの C2 なのかが記載されています。

先日構築したOpenCTIに登録された indicatorにAPIからアクセスできるか確認してみました。
できれば指定した indicator をピンポイントで検索できればと思っていますが、その前に取り合えず、APIから登録した indicator をリストで表示させることができたので、ここに記録しておきます。
なお、APIの使い方については以下のサイトに記載されています。
https://github.com/OpenCTI-Platform/client-python/blob/master/docs/client_usage/getting_started.rst
もしOpenCTIの環境に pycti を入れていないようであれば、以下の要領でインストールしておきましょう。
sudo apt install python3-pip pip3 install pycti
冒頭で紹介したサイトにサンプルが掲載されていますので、それをすこしいじって OpenCTI に indicator を登録します。
おもに以下の太字の部分を環境に合わせて修正すれば大丈夫です。
from dateutil.parser import parse
from pycti import OpenCTIApiClient
from stix2 import TLP_GREEN
# OpenCTI API client initialization
opencti_api_client = OpenCTIApiClient("http://localhost:8080", "<ローカルに立てたOpenCTIのAPI Keyを設定>")
# Define an OpenCTI compatible date
date = parse("2023-07-16").strftime("%Y-%m-%dT%H:%M:%SZ")
# Get the OpenCTI marking for stix2 TLP_GREEN
TLP_GREEN_CTI = opencti_api_client.marking_definition.read(id=TLP_GREEN["id"])
# Use the client to create an indicator in OpenCTI
indicator = opencti_api_client.indicator.create(
name="C2 server of the new campaign",
description="This is the C2 server of the campaign",
pattern_type="stix",
pattern="[IPv4-Addr:value = '100.172.180.181']",
x_opencti_main_observable_type="IPv4-Addr",
valid_from=date,
update=True,
markingDefinitions=[TLP_GREEN_CTI["id"]],
)
上記プログラムを「create_indicator.py」という名前で保存して、以下の通り OpenCTIのサーバ上で実行します。
$ python3 create_indicator.py
INFO:pycti.entities:Listing Threat-Actors with filters null.
INFO:pycti.entities:Reading Marking-Definition {marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da}.
INFO:pycti.entities:Creating Indicator {C2 server of the new campaign}.

それでは次に、OpenCTI に登録した Indicator をリストで表示してみます。
プログラムについては以下のサイトのものを参考にカスタマイズしています。
https://github.com/OpenCTI-Platform/client-python/blob/master/examples/get_all_indicators_using_pagination.py
以下、カスタマイズ後のプログラムです。
実行時に「pattern」や「description」などを表示するようにしています。
from pycti import OpenCTIApiClient
# Variables
api_url = "http://localhost:8080"
api_token = "ローカルに立てたOpenCTIのAPI Keyを設定>"
# OpenCTI initialization
opencti_api_client = OpenCTIApiClient(api_url, api_token)
# Get all reports using the pagination
custom_attributes = """
id
pattern_type
pattern
created
description
"""
final_indicators = []
data = {"pagination": {"hasNextPage": True, "endCursor": None}}
while data["pagination"]["hasNextPage"]:
after = data["pagination"]["endCursor"]
if after:
print("Listing indicators after " + after)
data = opencti_api_client.indicator.list(
first=50,
after=after,
customAttributes=custom_attributes,
withPagination=True,
orderBy="created_at",
orderMode="asc",
)
final_indicators += data["entities"]
for indicator in final_indicators:
print("[" + indicator["created"] + "] " + indicator["pattern"] + ", " + indicator["description"])
そしてこれが実行結果です。
$ python3 get_all_indicators.py INFO:pycti.entities:Listing Threat-Actors with filters null. INFO:pycti.entities:Listing Indicators with filters null. [2023-07-17T00:58:42.733Z] [domain-name:value = 'www.5z8.info'], This is the C2 server of the campaign [2023-07-17T01:18:55.912Z] [IPv4-Addr:value = '100.172.180.180'], This is the C2 server of the campaign [2023-07-17T01:34:48.208Z] [IPv4-Addr:value = '100.172.180.181'], This is the C2 server of the campaign
indicator やそのdescriptionがきちんと表示されています。
先日、ようやくルーフの塗り直しを行いましたが、ルーフの塗り直しだけでも20万円以上の費用がかかってしまいました。
https://k2-ornata.com/roadster_repaint_after
(それ以外にもサイドの塗装やドアハンドルまわりの修理をおこなったので、全体では30万円オーバーでしたが。。。)
そこで、再度ルーフの塗装を劣化をさせないように、前々から狙っていたAmazonで扱っているのルーフカバーを思い切って購入してみました。
(海外製、ロードスターNC専用ということでお値段は2万円オーバですが、これでルーフの劣化がさけられるならその価値はあるかなと。。。)
ブランド: North American Custom Covers
北米カスタムカバー ソフトトップルーフプロテクター ハーフカバー マツダ ミアータ MX5 Mk3 (NCモデルのみ)
そして、先週到着しました!
ルーフ部分だけのカバーなので、そこそこコンパクトです。(たぶん40cm×30cm、厚さ7cmくらい)
これなら遠出する時以外は、トランクに入れておいても邪魔にならないかと思います。

そしてこちらが装着してみた状態です。

想像以上にNC RHT にもぴったりフィットしました。
なお、両サイドにはそれぞれ5つくらい磁石が埋め込まれていて、カバーの厚みもそこそこある為、ちょっとの風ではぴくりともしない感じです。
これなら台風の時以外は付けていても問題ないかなという感じです。
しいていえば、ドアハンドルのところも劣化するのでそこまでカバーできたらよかったかもしれません。
そしてこちらはリア部分ですが、カバーの端が飛び出ていて、トランクの蓋にちょうど挟み込まれるようになっています。
後ろからの風はこれでばっちりです。

フロントもちょうどワイパーでさえられるようになっています。
最近のNDだともしかしたらワイパーの位置関係で抑えられないかもしれませんね。

耐久性の確認はこれからですが、さきほど少し書いたように生地はかなり厚みがあり作りもしっかりしているので、5年くらいはもってくれるんじゃないかと思います。
現在も同カバーを利用していますが、まったく破れることもなく使えております。また、真夏は出かける直前までカバーをかけていることにより、暑さ対策になっていて重宝しております。
2025.11.3追記
うーん、そろそろカバーがヘタっけきたようで、サイドミラーのあたりが裂け始めました。最近の夏の猛暑もあり、2年くらいの耐久性のようですね。
先日、以下の通りロードスターのループパネルの塗装剥がれについて、見積もりをいただきました。
そこそこ金額だったので2ヶ月くらい保留にしていたのですが、ようやく塗り直してもらうことを決意し、修正をお願いしてきました。
その結果がこちらです!

めっちゃ綺麗になってとても満足です。
MISP には複数のイベントでIoCが一致していないかチェックする機能があります。
それをうまく利用すれば、インシデント調査で収集したIoCが外部から収集したIoCと一致していないか、また、外部から新たに収集したIoCが、過去のインシデント調査した際のIoCと一致していないかを確認することが可能です。
以下の通り、インシデント対応で抽出したIoCを「Add Event」から登録します。
なお、インシデント対応で抽出したIoCを登録する際はイベント名を「SOC-Insident 001」などとするとわかりやすいと思います。

上記画面で「Submit」後に、下図の赤枠で囲った部分にあるアイコン(populate using the Freetext Import tool)をクリックします。

すると以下のようなFreetext Import Tool のポップアップが表示されるので、インシデント対応の中で収集したIoCをペーストし、「Submit」します。

このツールはとても優秀で、IoC 以外の情報もまとめて放り込んでも、綺麗にIoCだけ抽出し、以下の通りピックアップしてくれます。

Freetext での取り込み結果を確認し、問題なければ「Submit attributes」ボタンを押します。
インシデント調査で収集したIoCの登録が完了すると、すでに登録されているイベントのIoCと重複していないか、赤枠の通り表示してくれます。

また重複している場合は、「+Correlation Graph」を選択することで、重複しているイベントとの相関図を以下のとおり表示してくれます。

なお、標的型攻撃などの場合には、インシデント調査で抽出したIoCが各Feed提供元のIoCリストにはまだ登録されていない、といったこともままあると思います。
したがって、新しくFeed提供元からIoCを取得した際に、そのIoCがすでにインシデント対応で抽出していたIoCと一致していないか確認する、といった使い方も可能です。

ちなみに、他のイベントとIoCが重なった数はイベントリストの「Corr」カラムに記載されていますので、探しやすいと思います。

MISP をインストールした初期状態だと、以下の2つのIoC Feed取得元しか登録されていません。

そこで、このFeed元を増やす方法を確認しましたので、ここに記録しておきます。
以下のGitHubサイトにFeed元がたくさんかかれたJSONファイルがあるので、その内容をコピーします。
GitHub - MISP/app/files/feed-metadata/defaults.json https://github.com/MISP/MISP/blob/2.4/app/files/feed-metadata/defaults.json
1.でコピーしたFeed元の情報を取り込む為、上のFeeds画面の左ペインから「Import Feeds from JSON」を選択します。
そして先ほどコピーしたJSONを以下のとおりペーストし「ADD」ボタンを押します。

すると以下の通りFeed元が67件読み込まれました。

あとは、Feed元リストの左にあるチェックからFeedを取り込みたい提供元を選択後、上部にある「Fetch and store all feed data」をクリックすれば取り込まれます。
なお、取り込みの状況は「Administration」-「Jobs」から以下の通り確認可能です。

「Administration」-「Scheduled Tasks」で次の取り込み時間を指定することもできるようですが、毎回設定したいといけないように見えます。
そこで、cronjob と MISPのAPIを使った定期的なFeed元からの取り込み方法が以下のサイトに記載されていますので、興味のある方は参照してみると良いと思います。
Part 10. MISP Threat Intel(SOCFortress) https://socfortress.medium.com/part-10-misp-threat-intel-68131b18f719
k2-ornataのkuroです。
窓際で育てているアデニア・グラウカ、朝日を浴びてなにやらピカっと光るものが見えました。

よく見ると、葉の根元に今にも滴り落ちそうな大きな雫がついていました。
粘り気があり、舐めてみると甘くて苦みがありました。蜜です。

そういえば、たしかに昨年も蜜が出てました。ただ今回ほどではなく、ほんの少しだけでした。今年はなぜか大量生産。元気ならいいのですが。。
アデニア・グラウカは、南アフリカ原産のトケイソウ科の塊根植物(コーデックス)です。柔らかい葉と淡いグリーン色をしたすべすべの木肌が爽やかで清潔感があります。
冬は冬眠をするので11月~3月頃は完全に断水し、それ以外の季節も忘れた頃に水をあげるくらいで、ほぼ放置状態です。
手のかからない、とってもいいコです。
先日OpenCTIとMISPを連携させてみました。
その後、IoCデータが溜まってきているようなので、OpenCTIの使い勝手を少し確認してみましたので、その様子を記録しておきます。
内部でElasticを使っているせいなのか、全般的にとてもいかした画面で、SOCの大画面に投影しても映えそうです。
情報としては、集まってきているIoCの種類や数、そしてIoCに関連する攻撃グループの情報が表示されています。

こちらは上の画面の攻撃グループのグラフから、Turlaを選択した時の画面です。
この攻撃グループの概要やIoC提供者の情報が表示されています。

上の画像からトップメニューの「knowledge」を選択すると、この攻撃グループが保有するC2サイトなどの武器情報が表示されます。
表示がタイムラインになっていて、下にスクロールするほど新しい情報になるようです。

上の画像からトップメニューの「Indicators」を選択すると、その攻撃グループに関連するIoCもリストで確認できます。

また、攻撃グループの一覧をパネル形式で確認することも可能です。

先日SplunkにインストールしたVirusTotal Addon(vt4splunk)の使い勝手を再確認してみました。
すると思いがけず、VirusTotalのスコアが6/88の通信が発生していたので詳細を確認してみました。
とりあえず SplunkのStreamで収集しているhttp ログとVirusTotalの評価を突き合わせてみました。
sourcetype=stream:http | vt4splunk ip=dest_ip | table _time,dest_ip, vt_detections,vt_total_engines,vt_reputation,vt_info
すると、VirusTotalのスコアが1/88の通信先への通信が発生している様子。

まあ、googleも2/88だったりするし(たしか)、そんなこともありますよね。
そう思いながら vt4splunk のダッシュボードを見たところ、「Flaged IP Address」が11件発生しておりその中の一つは6/88のスコア。。。

そこで、リスト右端の「open」からVirusTotalの詳細な情報を確認。malicious や malware というワードが書かれているので、ちょっと不安に。。。

画面を下にスクロールして通信のログを確認。どうやらubuntsuのサイトにいっているらしい。VMでMISPを動かしていてそのOSがubuntsuなので、そいつがいっているのかも。

ちなみに11件という値をたたき出しているSPL文はこのようになっていました。うーん、むずい。。。
| inputlookup vt_ip_cache | search vt_detections > 0 | where "1" = "1" OR _first_seen_in_events >= relative_time(now(), "1")
| join type=left vt_id [| inputlookup vt_ignore_cache | search vt_type=ip] | where isnull(vt_type) | stats count
そこでChatGPTにこのSPL文を解説していただきました。
以下、ChatGPTの解説です。
このSPL(Splunk Processing Language)クエリは、Splunkデータベース内の`vt_ip_cache`と`vt_ignore_cache`という2つのテーブルからデータを取得し、さまざまな操作を行っています。以下に各行の意味を説明します。 1. `inputlookup vt_ip_cache`: `vt_ip_cache`テーブルからデータを取得します。 2. `search vt_detections > 0`: `vt_detections`フィールドが0より大きい行を検索します。 3. `where "1" = "1" OR _first_seen_in_events >= relative_time(now(), "1")`: 条件式が常に真となるため、すべての行をフィルタリングします。また、`_first_seen_in_events`フィールドの値が現在の時刻から1つの時間単位以上前である場合にも行をフィルタリングします。 4. `join type=left vt_id [| inputlookup vt_ignore_cache | search vt_type=ip]`: `vt_ignore_cache`テーブルから`vt_type`フィールドが"ip"の行を取得し、`vt_id`フィールドを使用して`vt_ip_cache`テーブルと結合します。結合は左外部結合(Left Join)です。 5. `where isnull(vt_type)`: 結合した後、`vt_type`フィールドが存在しない(NULL)行のみをフィルタリングします。 6. `stats count`: 結果の行数をカウントします。 このクエリの目的は、`vt_ip_cache`テーブルから検出数が0より大きい行を取得し、一定の条件に基づいてデータをフィルタリングします。さらに、`vt_ignore_cache`テーブルとの結合を行い、`vt_type`フィールドが存在しない(NULL)行の数をカウントします。
前回、MISPのAddon(MISP42)をSplunkにインストールし、イベントIDでMISPの検索を行ってみました。
しかしながら実際のインシデント調査では、調査の中で抽出したIoCがMISPに登録されていないか確認することが多いのではないかと思います。
そこで今回は、md5 や 通信先のIPアドレスをキーにMISPのデータを検索する方法を確認してみました。
MISP custom command のプルダウンメニューから「mispsearch」を選択すると、IoCのタイプを指定してMISP内のデータを検索することができます。

下の画面は、md5を指定してMISPを検索しているものになり、各パラメタについては
misp_instance:misp_instance01 field:md5 includeEventTags:True Paste your sample query here:| makeresults | eval md5="61e3571b8d9b2e9ccfadc3dde10fb6e1"
と設定しています。

またこの検索結果の下部から以下の画面の通り「サーチで開く」を選択すると、SPLでのサーチ文を確認することができます。

なお、この時のサーチ文は以下の通りとなっていました。
| makeresults | eval md5="61e3571b8d9b2e9ccfadc3dde10fb6e1" | search md5=61e3571b8d9b2e9ccfadc3dde10fb6e1 | mispsearch misp_instance=misp_instance01 field=md5 includeEventTags="true"
念のため、検索で表示された misp_event_id : 1057 をMISPのコンソールでも確認したところ、下の画面の通り、id:1057に同じ md5が含まれていました。

同じ要領で、送信先IPアドレスでも検索が行えます。
以下は送信先「37.120.170[.]231」に対するSPLでの検索例です。(このアドレスにアクセスしないように!)
| makeresults | eval ip-dst="37.120.170.231" | mispsearch misp_instance=misp_instance01 field=ip-dst includeEventTags="true" includeEventUuid="false" to_ids="false"
以下はMISPの「Comment」にEmotetと書かれているイベントを検索している例です。
| makeresults | eval misp_comment="Emotet" | mispsearch misp_instance=misp_instance01 field=misp_comment includeEventTags="true" includeEventUuid="false" to_ids="false"
Splunkにログを集約している企業などでは、同じSplunkコンソールからMISPのIoCを検索できるようになるので便利かもしれませんね。