OpenCTI のAPIにPythonから Accessし、登録されたindicatorを表示できるか確認してみた

先日構築したOpenCTIに登録された indicatorにAPIからアクセスできるか確認してみました。

できれば指定した indicator をピンポイントで検索できればと思っていますが、その前に取り合えず、APIから登録した indicator をリストで表示させることができたので、ここに記録しておきます。

なお、APIの使い方については以下のサイトに記載されています。

https://github.com/OpenCTI-Platform/client-python/blob/master/docs/client_usage/getting_started.rst

1.pycti のインストール

もしOpenCTIの環境に pycti を入れていないようであれば、以下の要領でインストールしておきましょう。

sudo apt install python3-pip
pip3 install pycti

2.Indicatorの登録

冒頭で紹介したサイトにサンプルが掲載されていますので、それをすこしいじって 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リスト

3.Indicatorのリスト表示

それでは次に、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がきちんと表示されています。

OpenCTIとVirusTotal、Shodanを連携させてみた

前回、OpenCTIを構築し、MISPと連携するところまで実施しました。

http://k2-ornata.com/opencti_misp_connection/

そこで今回はさらに、VirusTotalとShodanを連携させてみて、OpenCTIから確認できる情報がどうかわるか確認してみました。

1.VirusTotalコネクタのインストール

MISPの時と同様に GitHubの以下のサイトから VirusTotalのdocker-compose.yml をコピーし、OpenCTIのdocker-compose.ymlに埋め込みます。

OpenCTI-Platform /connectors
https://github.com/OpenCTI-Platform/connectors/tree/master/internal-enrichment/virustotal

そして以下のコマンドを実行します。

 docker-compose up -d --build

すると以下の通り既存のコネクタを含めたアップデートとインストールが行われます。

docker-composeの更新

このあとOpenCTIのコンソールを見ると、VirusTotalが追加されていることが確認できました。

OpenCTIコンソール

shodanのコネクタについても同様の手順で行います。

2.インディケータのエンリッチメント

VirusTotalとShodanをインストールしたら、IoCを表示する画面の右端になる「エンリッチメント」のボタンを押してみました。

OpenCTIコンソール

すると右側からウィンドウがせり出してきて、VirusTotal とShodanの連携情報が表示されるようになっていました。(IoCによって出たり出なかったりするようですが。)

OpenCTIコンソール

しかしながら、それ以外の変化が見つけられなかったので、あとでもう少し調べてみようと思っています。

また今後は、cve や Miter ATT&CK とも連携させて、どんな情報が得られるようになるのか確認したいと思っています。

<参考情報>

以下のYoutubeでOpenCTIの操作方法が説明されていますので、OpenCTIでざっくりどんなことができるか知りたい人は参考になると思います。

Introduction to the OpenCTI platform(Filigran)

OpenCTIを構築した後、MISPと連携させる(OpenCTIをコマンドラインから導入した場合)

先日、MacのParalleles Desktop上にそれぞれ別サーバとして構築したMISPとOpenCTIを連携させてみたのでここにその方法を記載しておきます。

なお、以下に書いたとおり、OpenCTIを構築する場合、コマンドラインから構築する方法と、portainer.io経由で構築する方法があるようです。

私の場合はコマンドラインから構築しました。(portainer.io経由でもやってみましたが、今のところ私の環境では成功していません。)

コマンドラインから構築する場合は、こちらの方のサイトが参考になると思います。

Re:ゼロから始めるOpenCTI 導入編(Zenn)
https://zenn.dev/daiya/articles/658a4f4811e2fa

portainer.io 経由で構築したいという方は、こちらのサイトが参考になると思います。

OPENCTI INSTALLATION (blog agood cloud)
https://blog.agood.cloud/posts/2020/04/22/opencti-installation/

1.misp接続用のdocker-compose.ymlをコピー

OpenCTIが正常に構築できていることを確認した後、以下のGithubのサイトにmisp接続用のdocker-compose.ymlが置いてありますので、取りに行きます。

https://github.com/OpenCTI-Platform/connectors/blob/master/external-import/misp/docker-compose.yml

そのymlの3行目から最後(47行目)までをコピーします。

1  version: '3'
2  services:
3    connector-misp:
4      image: opencti/connector-misp:5.8.7
5      environment:
  ・・・
46       - MISP_INTERVAL=5 # Required, in minutes
47    restart: always

2.OpenCTI用のdocker-compose.ymlに貼り付ける

1.でコピーしたデータを OpenCTI用のdocker-compose.ymlの中に貼り付けます。

なお、docker-compose.ymlの場所は、openctiをどのディレクトリ配下に構築したかに依存しますが、私の場合、/usr/local/openctiというディレクトリを作って構築したので、その下のdockerディレクトリ の中にありました。

docker-compose.ymlをviなどで開いた後、以下のように「connector-import-document」のセクションの直後に先ほどコピーした「connector-misp」のセクションを挿入します。

・・・
 connector-import-document:
    image: opencti/connector-import-document:5.8.3
    environment:
      - OPENCTI_URL=http://opencti:8080
      - OPENCTI_TOKEN=${OPENCTI_ADMIN_TOKEN}
      - CONNECTOR_ID=${CONNECTOR_IMPORT_DOCUMENT_ID} # Valid UUIDv4
・・・
    restart: always
    depends_on:
      - opencti
  connector-misp:
    image: opencti/connector-misp:5.8.3
    environment:
      - OPENCTI_URL=http://opencti:8080
      - OPENCTI_TOKEN=${OPENCTI_ADMIN_TOKEN}
      - CONNECTOR_ID=(UUIDv4を取得し設定)⭐️
      - CONNECTOR_TYPE=EXTERNAL_IMPORT
・・・
      - CONNECTOR_LOG_LEVEL=info
      - MISP_URL=https://(MISPサーバのIPアドレスを設定)⭐️
      - MISP_REFERENCE_URL= # Optional, will be used to create external reference to MISP event (default is "url")
      - MISP_KEY=(MISPのAPIキーを設定)⭐️
      - MISP_SSL_VERIFY=false # Required
・・・
      - MISP_INTERVAL=1 # Required, in minutes
    restart: always
    depends_on:
      - opencti
volumes:
  esdata:
  s3data:
  redisdata:
  amqpdata:

「connector-misp」のセクションを挿入したら、環境に合わせて修正をしますが、通常は⭐️をつけた3つの部分だけ変更した方がよいです。

なお、最初の⭐️の部分のUUIDv4ってなに?って感じの人(私もそんな1人です)もいると思いますが、以下のサイトから生成した世界に一つ?のIDをコピーしてくるだけで大丈夫です。

Online UUID Generator
https://www.uuidgenerator.net/version4

それ以外を編集するとたぶんハマると思います。

たとえば「OPENCTI_URL」「OPENCTI_TOKEN」あたりを変えたくなるかもしれませんが、それを変えてしまった為に私はすこしハマりました。

3.OpenCTIを再ビルドする

上記のymlファイルを編集した後、 OpenCTIを再起動すれば変更が反映されるとおもっていました。

しかし実はそうではなく、再ビルドのコマンドを実行する必要があるようです。そのコマンドがこちらです。

$ docker-compose up -d --build

これを知らなかったが為に、いくらymlファイルを修正してもうまくいかず、かなりハマってしまいました。

以下のZenn様のページが参考になりました、ありがとうございました。

Re:ゼロから始めるOpenCTI External Input Connector編(Zenn)
https://zenn.dev/daiya/articles/ce1c3ad92c53aa

4.OpenCTIのダッシュボードを確認してみる

うまく設定できていれば OpenCTIダッシュボードの「Data」-「Connector」に以下のとおりMISPが表示されその横のマークがグリーンになっているはずです。

OpenCTIダッシュボード

もしうまくいかない場合は、、、

以下を試してみるといいかもしれません。

A. portainer.ioをインストールしてみる

OpenCTIをインストールしたマシンに、portainer.ioを入れてみましょう。これによりDockerの状態がGUIで見れるようになり、問題点がわかりやすくなります。

portainer.io

B. 以下のコマンドを打って環境を整え直してみる

正直あまり根拠はありません(MISPとの接続にhttps接続が必要だったので関係あるかなと思っているくらいです)が、以下のコマンドをOpenCTIのサーバ上で打ってみるといいかもしれません。

sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg-agent \
    software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

それぞれのコマンドの詳しい説明は冒頭に紹介した「OPENCTI INSTALLATION (blog agood cloud)」を見てください。