オープンソースの脅威インテリジェンス・プラットフォーム2024|検証編(5/21)
セキュリティ対策を実施する上では、脅威情報を活用し、想定される攻撃やリスクを特定することが重要とされています。
このような脅威インテリジェンスを支援するプラットフォームが多くのベンダーによって開発されており、SOMPO CYBER SECURITYでもサイバー先進国である以色列発の脅威インテリジェンス・プラットフォームであるCognyteや、米国製のKryptosLogicを提供しています。
一方、脅威インテリジェンス・プラットフォームには、広く利用されているオープンソースソフトウェアがいくつか存在します。
本記事では前編に続いて、実際にいくつかのオープンソース・脅威インテリジェンス・プラットフォームを導入し比較検証していきます。
前編:オープンソースの脅威インテリジェンス・プラットフォーム2024|紹介編
記事に関するご意見・お問い合わせはこちらへお寄せください。
(SOMPOホールディングス、損害保険ジャパンなどグループ各社へのお問い合わせはご遠慮下さい)
実際に3つのプラットフォームを使ってみる
前回の記事では、各プラットフォームが組織のやりたいことを実現してくれるかどうかについて、以下の要件を定めました。
大まかな用途としては、様々な部署が収集した資料を格納・整理し、社内共通の知識基盤として活用するというものになります。
①インプット
- 【必須】手動でデータを登録できること
- 【あったらいいな】RSSでフィードを取得できること(非構造化データの取り込み)
②整理・分析
- 【必須】データまたはフィードを保存できること
- 【必須】タグを手動で定義できること(データ間の関連性を定義)
- 【あったらいいな】フィード全文を構造化してデータベースに格納すること
- 【あったらいいな】フィルタリング条件を用いて、フィードにタグを自動付与できること
- 【あったらいいな】取得データから日本語・英語を単語ごとに識別し全文検索を可能とすること
- 【あったらいいな】取得データから日本語・英語の頻出単語、関連性を分析できること
③アウトプット
- 【必須】検索機能(全文検索およびタグ検索)
- 【あったらいいな】同一フィードに付与されたタグを関連性として可視化できること(関連性マップ)
- 【あったらいいな】頻出単語などを視覚的にわかりやすく表示できること(Word Cloud等)
- 【あったらいいな】キーワードやタグを参考に、AIがフィードやソースの要約を生成
本記事では、代表的なオープンソース・脅威インテリジェンス・プラットフォームであるMISP、YETI、OpenCTIの検証結果をご紹介します。
はじめに、検証に用いた環境について簡単に触れた後、各プラットフォームの使用感や、要件チェックについてまとめています。
検証に利用した入力データ
上に示したインプット、整理・分析・アウトプットを検証するため、以下のセキュリティ関連情報を実際に入力しました。
- セキュリティニュース(一般)
- ガイドラインおよびドキュメント
- セキュリティニュース(市場)
- 国内セキュリティインシデント
- 国外セキュリティインシデント
- 脅威情報
- 脆弱性
- セミナー情報
- ダークウェブ関連情報
検証環境の紹介
今回の検証にあたって、当社ラボ環境で休眠状態だったサーバーを利用し、仮想環境上にUbuntuを立てて検証しました。
チームで作成したゲストOSの概要は以下のとおりです。
項目 | 値 |
CPU | 2プロセッサ・合計2コア |
メモリ | 80GB |
ストレージ | 1TB |
検証にあたっては、Ubuntuのマスターイメージを作成しそれぞれプラットフォームを構築しました。
MISP
比較的導入しやすく、外部連携に適している
MISPは利用実績も豊富であり、コミュニティも活発であるため、導入や運用に必要な情報は比較的取得しやすいといえます。
今回検証した他のプラットフォームと比べてインストールおよびセットアップは容易でした。
入出力や可視化といった、今回私たちが定めた要件も備えており、脅威情報を組織間で連携するのに適したプラットフォームであることを確認しました。
またこのプラットフォームをフィードの受信に特化させ、多くのIoCなどのフィードを蓄積、共有するのに利用する使い方も非常に有用であり、多くの組織でも採用されているようです。
ダッシュボード(MISP)
①インプット
MISPでは手動の情報登録が可能です。またフィードによる情報の自動取り込み機能が用意されています。
MISPでは「アトリビュート」と呼ばれる個々の情報を「イベント」と呼ばれるグループで管理するため、検証用データをイベントとして登録しました。
例えば組織内で共有したいセキュリティニュースを登録し、その中に具体的なIoCや参考リンク、また「タクソノミー」(「タグ」に相当)を付与することが可能です。
入力した情報の詳細画面 (MISP)
入力したイベント一覧(MISP)
②整理・分析
MISPでは、固有のデータモデルに基づいた情報の格納と、可視化が可能です。
データモデル | 概要 |
イベント | 様々な情報をコンテキストに基づいて集約する単位です。 特定のインシデント等が該当します。 |
タクソノミー | イベントの属性やカテゴリを示す「タグ」に相当します。 |
ギャラクシー | メタデータを含むラベルです。 ギャラクシーを利用して、セクター(通信事業者)、国(発生国)、攻撃パターン(フィッシング、スピアフィッシング等)等の属性を付与します。 |
アトリビュート | IPアドレスやURL、ハッシュ値等、脅威情報を構成する基礎単位です。 |
オブジェクト | あらかじめ定義されたテンプレートを利用し、アトリビュートを構成可能な単位です。 |
リレーションシップ | イベント間、アトリビュート間やオブジェクト間の関係を定義します。 |
イベントに関連付けできるアトリビュート(IoC等)(MISP)
登録されたイベントに含まれる構成要素(アトリビュートやオブジェクト)を可視化することができます。以下のスクリーンショットでご紹介する相関図の他、時系列表示も可能です。
可視化(ビジュアリゼーション)の例(MISP)
③アウトプット
イベントやアトリビュートごとに検索が可能であり、CSV、JSON、STIX2形式等によるエクスポートが可能です。
ダッシュボードについては、ウィジェット機能やソート機能に関して、他のプラットフォームの方が優位であることを確認しました。
さらに高度な検索を行う場合は、PyMISPと呼ばれるPythonライブラリを利用します(本検証では対象外)。
YETI
導入に若干の手間がかかる。IoCを元に分析を行うことに主眼を置いたプラットフォーム
インストールに際しては、導入するPythonパッケージのバージョン依存関係について、自身で解決していく必要があります。
また本プラットフォームは、インシデントレスポンス等の際に取得したIoCの分析作業を効率化し、任意のフォーマットでエクスポートすることでセキュリティ製品に統合していくことに秀でています。
このため、社内での情報共有・蓄積を目的とした今回の要件には適合しない箇所もあることを確認しました。
これはプラットフォームの設計目的が我々の必要性と異なるということであり、YETIの評価を下げるものではありません。
また、MISPやOpenCTIと比較して話題が少ないため、必要な情報を得るのに時間を要するという印象を受けました。
①インプット
MISPと同様に手動でのデータ入力が可能です。また、指定したURLをクローリングし、記事内からIoCを自動識別・選択登録できる機能が備わっています。
検証メンバー一同の感覚になりますが、MISPよりも操作が容易です。
なおフィード取り込み機能もありますが、OpenCTIのようなエンリッチメント(既存のエンティティに対し追加情報を付与)機能はありません。
イベント(インベスティゲーション)一覧(YETI)
イベント詳細画面(YETI)
イベントに関連付け可能なエンティティ(IoC等)(YETI)
②整理・分析
検索用のタグを利用可能です(英語のみ)。ただし、タグ付与時にサジェスト表示(候補表示)がされませんでした。
登録された各エンティティの関連性は、手動でリレーションシップを追加することで可視化可能です。
関連性の検索・可視化機能(リレーションシップは手動で作成)(YETI)
③アウトプット
YETI上のデータや分析内容を出力するにはテンプレートを作成する必要があります。
また、イベント、エンティティごとに検索が可能です。
OpenCTI
ニュース・レポートの情報共有からIoCの集積・活用まで対応。インターフェースも使いやすく、活発にアップデートされている
前編でご紹介したとおり、現在OpenCTIはFiligran社によって開発・運営が進められています。アップデートの頻度は非常に多く、開発状況はGitHubおよびSlackで都度確認することが可能です。
今回、検証チームが求めた要件を満たしており、また機能も日々拡充されています。
導入においては、比較的高スペックなコンピュータが必要であること、Dockerの設定ファイルを自組織の環境に応じて書き換える点で多少時間を要しますが、活発なコミュニティや日本語での記事も多く助けとなります。
GUIは非常に洗練されており、非セキュリティ職域のメンバーであっても基本的な機能を使うことができます。
なお、生成AI利用や全文検索、アクティビティ監査等一部の機能は、エンタープライズ版でのみ利用可能であり、商用・一般利用の際は契約が必要となります。
検証中のカスタムダッシュボード(OpenCTI)
①インプット
レポートやニュースを含む様々な情報の登録が可能です。
コネクタを利用した外部フィードの自動取り込みや、既存エンティティへの追加情報付与(エンリッチメント)が可能です。
現在のバージョンでは、RSSを利用した記事の取り込みもできます。
マルウェア情報の入力と更新(OpenCTI)
データ・モデルはSTIXに準拠(OpenCTI)
②整理・分析
データモデルはSTIX2.1標準に基づいており、 以下のエンティティタイプに応じた情報の整理や関連付けが可能です。
STIX2.1の概要についてはOASISの公式サイトをご確認ください。
エンティティ相互の関係を可視化する機能や、ウィジェットのカスタマイズができます。
また、特定エンティティに対するアナリストの補足説明やコメントも取り扱うことができるため、利用者間での連携ができます。
レポートPDF等の取り込みと全文検索が可能
脅威レポートやマルウェア、脅威アクター、あるいは自身の分析を可視化(OpenCTI)
③アウトプット
バックにElasticsearchを利用しており、検索機能に優れています。
例えばレポートやガイドラインをPDFとして取り込み、インデックス化し全文検索することができます。
ラベル(タグ)機能を用いたフィルタリング等ができます。
より応用的な検索が必要な場合は、APIを利用します。
データのエクスポートについては、PDF、STIX2.1、DSV、TXT、Wordドキュメント等に対応しています。
検証結果
今回、社内における脅威情報の蓄積と共有という目的を設定し、この要件に基づいて複数のオープンソース・脅威インテリジェンス・プラットフォームを検証しました。
結果として、上述の利用目的であれば、OpenCTIがもっとも適しているという結論に至りました。
当然、組織のニーズによって最適なツールやプラットフォームは変わりますので、選定等の参考になれば幸いです。
商用脅威インテリジェンス・プラットフォームとの併用
今回検証に用いた脅威インテリジェンス・プラットフォームは、当社が取り扱っているCognyteを含む商用製品とは、その機能や用途で相違があります。
ここではCognyte LuminarおよびKryptos Logic、そして検証アプリの1つであるOpenCTIを比較します。
プラットフォーム | OpenCTI | Cognyte Luminar | Kryptos Logic |
用途 | 手動入力および自動取り込みによる脅威情報の共有とその分析 | 登録アセットやキーワードに基づく脅威情報や情報漏洩の検知 | 登録アセットに基づくマルウェア感染やランサムウェア感染の検知 |
データソース | ・自組織が収集したデータ ・公的機関やセキュリティベンダーが提供する公開脅威情報 ・RSS |
・サーフェスウェブ ・ディープウェブ ・ダークウェブ ・Telegram等メッセージアプリ ・SNS ・IoT検索エンジン |
・ボットネット ・サイバー犯罪グループのクローズドチャット |
手動データ登録 | 手動でのデータ登録が可能 | Luminarが生成するフィードに対する補足やフィードの整理がメイン | フラグ等限定的 |
整理・分析 | ウィジェットでの統計表示やグラフによるビジュアリゼーションによる分析機能あり | アナリスト向けのケースマネジメント機能を利用可能 | プラットフォームが提供する表示形式にて閲覧可能 |
アウトプット | ・様々なファイル形式による出力 ・API |
・PDF等での出力 ・API |
・API |
「脅威インテリジェンス・プラットフォーム」というカテゴリにおいても、目的や機能は様々です。
組織の必要性やリスクに応じた最適なツールを利用することを推奨します。
さいごに:OpenCTI導入設定情報
補足として、検証チームでOpenCTIを導入した際の参考情報を記載します(2024年2月時点)。
留意事項:
- Dockerコンテナ内部のログをSyslogへ出力するための設定を追加
- デフォルトのポート8080を別ポートに変更
- SSL対応として証明書のkeyファイルおよびcrtファイルの場所を指定し、volumesでホスト側ディレクトリをマウント
- セキュリティ対応
- セッションcookieのsecureフラグを設定
- セッションタイムアウト時間を指定
- SMTP認証
- アラート通知等で利用するSMTPサーバと認証情報を設定
- DockerはRootless modeで実行
version: '3'
services:
redis:
image: redis:7.2.3
restart: always
volumes:
- redisdata:/data
logging:
driver: syslog
options:
syslog-facility: daemon
tag: opencti/{{.Name}}/{{.ID}}
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:8.11.3
volumes:
- esdata:/usr/share/elasticsearch/data
environment:
- discovery.type=single-node
- xpack.ml.enabled=false
- xpack.security.enabled=false
- "ES_JAVA_OPTS=-Xms${ELASTIC_MEMORY_SIZE} -Xmx${ELASTIC_MEMORY_SIZE}"
restart: always
logging:
driver: syslog
options:
syslog-facility: daemon
tag: opencti/{{.Name}}/{{.ID}}
minio:
image: minio/minio:RELEASE.2023-11-15T20-43-25Z
volumes:
- s3data:/data
ports:
- "9000:9000"
environment:
MINIO_ROOT_USER: ${MINIO_ROOT_USER}
MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD}
command: server /data
restart: always
logging:
driver: syslog
options:
syslog-facility: daemon
tag: opencti/{{.Name}}/{{.ID}}
rabbitmq:
image: rabbitmq:3.12-management
environment:
- RABBITMQ_DEFAULT_USER=${RABBITMQ_DEFAULT_USER}
- RABBITMQ_DEFAULT_PASS=${RABBITMQ_DEFAULT_PASS}
- RABBITMQ_NODENAME=rabbit01@localhost
volumes:
- amqpdata:/var/lib/rabbitmq
restart: always
logging:
driver: syslog
options:
syslog-facility: daemon
tag: opencti/{{.Name}}/{{.ID}}
opencti:
image: opencti/platform:5.12.9
environment:
- NODE_OPTIONS=--max-old-space-size=8096
- APP__PORT={任意のポートを指定}
- APP__BASE_URL=${OPENCTI_BASE_URL}
- APP__ADMIN__EMAIL=${OPENCTI_ADMIN_EMAIL}
- APP__ADMIN__PASSWORD=${OPENCTI_ADMIN_PASSWORD}
- APP__ADMIN__TOKEN=${OPENCTI_ADMIN_TOKEN}
- APP__APP_LOGS__LOGS_LEVEL=error
- APP__HTTPS_CERT__KEY=${OPENCTI_KEY_PATH}
- APP__HTTPS_CERT__CRT=${OPENCTI_CRT_PATH}
- APP__HTTPS_CERT__REJECT_UNAUTHORIZED=true
- APP__HTTPS_CERT__COOKIE_SECURE=true
- APP__SESSION_IDLE_TIMEOUT=1200000
- REDIS__HOSTNAME=redis
- REDIS__PORT=6379
- ELASTICSEARCH__URL=http://elasticsearch:9200
- MINIO__ENDPOINT=minio
- MINIO__PORT=9000
- MINIO__USE_SSL=false
- MINIO__ACCESS_KEY=${MINIO_ROOT_USER}
- MINIO__SECRET_KEY=${MINIO_ROOT_PASSWORD}
- RABBITMQ__HOSTNAME=rabbitmq
- RABBITMQ__PORT=5672
- RABBITMQ__PORT_MANAGEMENT=15672
- RABBITMQ__MANAGEMENT_SSL=false
- RABBITMQ__USERNAME=${RABBITMQ_DEFAULT_USER}
- RABBITMQ__PASSWORD=${RABBITMQ_DEFAULT_PASS}
- SMTP__HOSTNAME=${SMTP_HOSTNAME}
- SMTP__PORT=${SMTP_PORT}
- SMTP__USERNAME=${SMTP_USERNAME}
- SMTP__PASSWORD=${SMTP_PASSWORD}
- PROVIDERS__LOCAL__STRATEGY=LocalStrategy
volumes:
- ${SSL証明書を格納したディレクトリ}
ports:
- {任意のポートを指定}
depends_on:
- redis
- elasticsearch
- minio
- rabbitmq
restart: always
logging:
driver: syslog
options:
syslog-facility: daemon
tag: opencti/{{.Name}}/{{.ID}}
worker:
image: opencti/worker:5.12.9
environment:
- OPENCTI_URL=${OPENCTI_PLATFORM_URL}
- OPENCTI_TOKEN=${OPENCTI_ADMIN_TOKEN}
- WORKER_LOG_LEVEL=info
depends_on:
- opencti
deploy:
mode: replicated
replicas: 3
restart: always
logging:
driver: syslog
options:
syslog-facility: daemon
tag: opencti/{{.Name}}/{{.ID}}
connector-export-file-stix:
image: opencti/connector-export-file-stix:5.12.9
environment:
- OPENCTI_URL=${OPENCTI_PLATFORM_URL}
- OPENCTI_TOKEN=${OPENCTI_ADMIN_TOKEN}
- CONNECTOR_ID=${CONNECTOR_EXPORT_FILE_STIX_ID} # Valid UUIDv4
- CONNECTOR_TYPE=INTERNAL_EXPORT_FILE
- CONNECTOR_NAME=ExportFileStix2
- CONNECTOR_SCOPE=application/json
- CONNECTOR_CONFIDENCE_LEVEL=15 # From 0 (Unknown) to 100 (Fully trusted)
- CONNECTOR_LOG_LEVEL=info
restart: always
depends_on:
- opencti
logging:
driver: syslog
options:
syslog-facility: daemon
tag: opencti/{{.Name}}/{{.ID}}
connector-export-file-csv:
image: opencti/connector-export-file-csv:5.12.9
environment:
- OPENCTI_URL=${OPENCTI_PLATFORM_URL}
- OPENCTI_TOKEN=${OPENCTI_ADMIN_TOKEN}
- CONNECTOR_ID=${CONNECTOR_EXPORT_FILE_CSV_ID} # Valid UUIDv4
- CONNECTOR_TYPE=INTERNAL_EXPORT_FILE
- CONNECTOR_NAME=ExportFileCsv
- CONNECTOR_SCOPE=text/csv
- CONNECTOR_CONFIDENCE_LEVEL=15 # From 0 (Unknown) to 100 (Fully trusted)
- CONNECTOR_LOG_LEVEL=info
restart: always
depends_on:
- opencti
logging:
driver: syslog
options:
syslog-facility: daemon
tag: opencti/{{.Name}}/{{.ID}}
connector-export-file-txt:
image: opencti/connector-export-file-txt:5.12.9
environment:
- OPENCTI_URL=${OPENCTI_PLATFORM_URL}
- OPENCTI_TOKEN=${OPENCTI_ADMIN_TOKEN}
- CONNECTOR_ID=${CONNECTOR_EXPORT_FILE_TXT_ID} # Valid UUIDv4
- CONNECTOR_TYPE=INTERNAL_EXPORT_FILE
- CONNECTOR_NAME=ExportFileTxt
- CONNECTOR_SCOPE=text/plain
- CONNECTOR_CONFIDENCE_LEVEL=15 # From 0 (Unknown) to 100 (Fully trusted)
- CONNECTOR_LOG_LEVEL=info
restart: always
depends_on:
- opencti
logging:
driver: syslog
options:
syslog-facility: daemon
tag: opencti/{{.Name}}/{{.ID}}
connector-import-file-stix:
image: opencti/connector-import-file-stix:5.12.9
environment:
- OPENCTI_URL=${OPENCTI_PLATFORM_URL}
- OPENCTI_TOKEN=${OPENCTI_ADMIN_TOKEN}
- CONNECTOR_ID=${CONNECTOR_IMPORT_FILE_STIX_ID} # Valid UUIDv4
- CONNECTOR_TYPE=INTERNAL_IMPORT_FILE
- CONNECTOR_NAME=ImportFileStix
- CONNECTOR_VALIDATE_BEFORE_IMPORT=true # Validate any bundle before import
- CONNECTOR_SCOPE=application/json,text/xml
- CONNECTOR_AUTO=true # Enable/disable auto-import of file
- CONNECTOR_CONFIDENCE_LEVEL=15 # From 0 (Unknown) to 100 (Fully trusted)
- CONNECTOR_LOG_LEVEL=info
restart: always
depends_on:
- opencti
logging:
driver: syslog
options:
syslog-facility: daemon
tag: opencti/{{.Name}}/{{.ID}}
connector-import-document:
image: opencti/connector-import-document:5.12.9
environment:
- OPENCTI_URL=${OPENCTI_PLATFORM_URL}
- OPENCTI_TOKEN=${OPENCTI_ADMIN_TOKEN}
- CONNECTOR_ID=${CONNECTOR_IMPORT_DOCUMENT_ID} # Valid UUIDv4
- CONNECTOR_TYPE=INTERNAL_IMPORT_FILE
- CONNECTOR_NAME=ImportDocument
- CONNECTOR_VALIDATE_BEFORE_IMPORT=true # Validate any bundle before import
- CONNECTOR_SCOPE=application/pdf,text/plain,text/html
- CONNECTOR_AUTO=true # Enable/disable auto-import of file
- CONNECTOR_ONLY_CONTEXTUAL=false # Only extract data related to an entity (a report, a threat actor, etc.)
- CONNECTOR_CONFIDENCE_LEVEL=15 # From 0 (Unknown) to 100 (Fully trusted)
- CONNECTOR_LOG_LEVEL=info
- IMPORT_DOCUMENT_CREATE_INDICATOR=true
restart: always
depends_on:
- opencti
logging:
driver: syslog
options:
syslog-facility: daemon
tag: opencti/{{.Name}}/{{.ID}}
volumes:
esdata:
s3data:
redisdata:
amqpdata:
参考サイト
今回、オープンソースの脅威インテリジェンス・プラットフォームを検証するにあたっては、以下の記事を参考にさせていただきました。ありがとうございます。
その他の参考ソースは以下となります。
- https://www.misp-project.org/misp-training/cheatsheet.pdf
- https://kravensecurity.com/threat-intelligence-with-misp-part-5-searching-and-filtering/
- https://www.helpnetsecurity.com/2023/10/12/yeti-threat-intelligence/
- https://oasis-open.github.io/cti-documentation/stix/intro.html
記事に関するご意見・お問い合わせはこちらへお寄せください。
(SOMPOホールディングス、損害保険ジャパンなどグループ各社へのお問い合わせはご遠慮下さい)
上級研究員
・自衛官時代に言われた一言「レーダー整備にそんな筋肉はいらない」