Group-IB 脅威インテリジェンス のログを収集する
このドキュメントでは、Google Cloud Storage を使用して Group-IB 脅威インテリジェンス ログを Google Security Operations に取り込む方法について説明します。
Group-IB Threat Intelligence & Attribution(TI&A)は、脅威アクター、セキュリティ侵害インジケーター(IOC)、マルウェア、コマンド&コントロール(C2)インフラストラクチャ、漏洩した認証情報、フィッシング キャンペーン、脆弱性に関するリアルタイム データを提供するサイバー脅威インテリジェンス プラットフォームです。オープン Web、ディープ Web、ダーク Web のソースからインテリジェンスを集約し、セキュリティ チームが脅威を事前に検出して対応できるようにします。
始める前に
次の前提条件を満たしていることを確認してください。
- Google SecOps インスタンス
- API アクセスが有効になっている Group-IB TI&A アカウント
- Group-IB TI&A ポータルへのアクセス(
tap.group-ib.com) - 次の API が有効になっている Google Cloud プロジェクト。
- Cloud Storage API
- Cloud Functions API
- Cloud Scheduler API
- Cloud Build API
Group-IB API キーを生成する
https://tap.group-ib.comで Group-IB TI&A ポータルにログインします。- 右上の名前をクリックし、[プロフィール] を選択します。
- [設定に移動] をクリックします。
- [Security and Access] タブに移動します。
- [Personal token] セクションで、[Generate new token] をクリックします。
API キーをコピーして安全に保存します。
Google Cloud Storage バケットを作成する
- Google Cloud コンソールに移動します。
- プロジェクトを選択するか、新しいプロジェクトを作成します。
- ナビゲーション メニューで、[Cloud Storage > バケット] に移動します。
- [バケットを作成] をクリックします。
次の構成情報を提供してください。
設定 値 バケットに名前を付ける グローバルに一意の名前( groupib-ti-logsなど)を入力します。ロケーション タイプ ニーズに応じて選択します(リージョン、デュアルリージョン、マルチリージョン)。 ロケーション 場所を選択します(例: us-central1)。ストレージ クラス Standard(アクセス頻度の高いログにおすすめ) アクセス制御 均一(推奨) [作成] をクリックします。
Group-IB データを取得する Cloud Functions をデプロイする
Group-IB TI&A API から脅威インテリジェンス データを取得し、Google SecOps が取り込むための NDJSON ファイルとして GCS バケットに書き込む Cloud Functions の関数を作成します。
Cloud Functions の関数を作成する
- Google Cloud コンソールに移動します。
- Cloud Functions に移動します。
- [関数を作成] をクリックします。
次の構成情報を提供してください。
設定 値 環境 第 2 世代 関数名 groupib-to-gcsリージョン GCS バケットに最も近いリージョンを選択します。 トリガーのタイプ HTTPS 認証 認証が必要です 割り当てられたメモリ 512 MB(大規模なコレクションを取得する場合は増やす) タイムアウト 540 秒 [次へ] をクリックします。
[ランタイム] を
Python 3.11(以降)に設定します。[エントリ ポイント] を
mainに設定します。main.pyの内容を次のコードに置き換えます。import json import os import requests import functions_framework from datetime import datetime, timedelta, timezone from urllib.parse import urljoin from requests.auth import HTTPBasicAuth from google.cloud import storage GIB_API_URL = os.environ.get('GIB_API_URL', 'https://tap.group-ib.com/api/v2/') GIB_USERNAME = os.environ.get('GIB_USERNAME') GIB_API_KEY = os.environ.get('GIB_API_KEY') GCS_BUCKET = os.environ.get('GCS_BUCKET') GCS_PREFIX = os.environ.get('GCS_PREFIX', 'groupib-ti') COLLECTIONS = os.environ.get('GIB_COLLECTIONS', 'compromised/account,malware/cnc,apt/threat,hi/threat').split(',') DEFAULT_DAYS_BACK = int(os.environ.get('DEFAULT_DAYS_BACK', '3')) # Max items per request: 100 for most collections, 20 for apt/threat and hi/threat BIG_DATA_COLLECTIONS = ['apt/threat', 'hi/threat'] # File to persist seqUpdate values between runs (use GCS for durability) STATE_BLOB = '_state/seq_updates.json' def load_state(): """Load seqUpdate state from GCS.""" client = storage.Client() bucket = client.bucket(GCS_BUCKET) blob = bucket.blob(f"{GCS_PREFIX}/{STATE_BLOB}") if blob.exists(): return json.loads(blob.download_as_text()) return {} def save_state(state): """Save seqUpdate state to GCS.""" client = storage.Client() bucket = client.bucket(GCS_BUCKET) blob = bucket.blob(f"{GCS_PREFIX}/{STATE_BLOB}") blob.upload_from_string(json.dumps(state), content_type='application/json') def gib_request(session, url, params=None): """Send authenticated GET request to Group-IB API.""" resp = session.get(url, params=params) if resp.status_code == 301: raise Exception('IP not whitelisted by Group-IB. Contact Group-IB support.') resp.raise_for_status() return resp.json() def get_seq_update_by_date(session, collection, date_str): """Get seqUpdate value for a collection starting from a given date.""" url = urljoin(GIB_API_URL, 'sequence_list') data = gib_request(session, url, {'date': date_str, 'collection': collection}) return data.get('list', {}).get(collection) def fetch_collection(session, collection, seq_update): """Fetch all new items from a collection starting after the given seqUpdate.""" limit = 20 if collection in BIG_DATA_COLLECTIONS else 100 url = urljoin(GIB_API_URL, f"{collection}/updated") all_items = [] last_seq = seq_update while True: data = gib_request(session, url, {'seqUpdate': str(last_seq), 'limit': limit}) items = data.get('items', []) if not items: break all_items.extend(items) last_seq = items[-1].get('seqUpdate') return all_items, last_seq def write_to_gcs(items, collection_name): """Write items to GCS as NDJSON.""" if not items: return 0 client = storage.Client() bucket = client.bucket(GCS_BUCKET) timestamp = datetime.now(timezone.utc).strftime('%Y%m%d_%H%M%S') safe_name = collection_name.replace('/', '_') blob_path = f"{GCS_PREFIX}/{safe_name}_{timestamp}.ndjson" blob = bucket.blob(blob_path) ndjson = '\n'.join(json.dumps(item, ensure_ascii=False) for item in items) + '\n' blob.upload_from_string(ndjson, content_type='application/x-ndjson') return len(items) @functions_framework.http def main(request): """Cloud Function entry point.""" session = requests.Session() session.auth = HTTPBasicAuth(GIB_USERNAME, GIB_API_KEY) session.headers.update({'Accept': '*/*'}) state = load_state() total = 0 for collection in COLLECTIONS: collection = collection.strip() seq_update = state.get(collection) if seq_update is None: default_date = (datetime.now(timezone.utc) - timedelta(days=DEFAULT_DAYS_BACK)).strftime('%Y-%m-%d') seq_update = get_seq_update_by_date(session, collection, default_date) if seq_update is None: continue items, last_seq = fetch_collection(session, collection, seq_update) if items: write_to_gcs(items, collection) total += len(items) state[collection] = last_seq save_state(state) return json.dumps({'status': 'success', 'total_items': total}), 200requirements.txtの内容を次の依存関係に置き換えます。functions-framework==3.* requests>=2.28.0 google-cloud-storage>=2.0.0[デプロイ] をクリックします。
環境変数を構成する
- デプロイ後、関数の詳細ページに移動します。
- [編集] をクリックします。
- [ランタイム、ビルド、接続、セキュリティの設定] セクションを開きます。
[ランタイム環境変数] で、次の変数を追加します。
変数 値 GIB_API_URLhttps://tap.group-ib.com/api/v2/(または地域に応じてhttps://bt.group-ib.com/api/v2/)GIB_USERNAMEGroup-IB アカウントのメールアドレス GIB_API_KEYGroup-IB API キー(個人用トークン) GCS_BUCKETGCS バケット名(例: groupib-ti-logs)GCS_PREFIXログファイルの接頭辞(例: groupib-ti)GIB_COLLECTIONS取得するコレクションのカンマ区切りのリスト(下記参照) DEFAULT_DAYS_BACK最初の実行で遡る日数(デフォルト: 3)[デプロイ] をクリックします。
利用可能な Group-IB コレクション
ユースケースに関連するコレクションを使用して GIB_COLLECTIONS 変数を構成します。
| コレクション | 説明 | 最大値 |
|---|---|---|
compromised/account |
不正使用されたアカウント認証情報(ログイン、パスワード、ドメイン) | 100 |
compromised/card |
不正使用された銀行カード | 100 |
compromised/mule |
マネー ミュールのアカウント | 100 |
compromised/imei |
不正使用されたモバイル デバイスの IMEI | 100 |
compromised/file |
マルウェアの属性を持つ侵害されたファイル | 100 |
attacks/ddos |
DDoS 攻撃データ(ターゲット IP、ドメイン) | 100 |
attacks/deface |
ウェブサイトの改ざんインシデント | 100 |
attacks/phishing |
フィッシング URL とドメイン | 100 |
attacks/phishing_kit |
フィッシング キットのハッシュとターゲット ブランド | 100 |
bp/phishing |
ブランド保護 - フィッシング インシデント | 100 |
bp/phishing_kit |
ブランド保護 - フィッシング キット | 100 |
hi/threat |
IOC と MITRE ATT&CK マッピングを含むサイバー犯罪者(HI)の脅威レポート | 20 |
hi/threat_actor |
サイバー犯罪者の脅威アクター プロファイル | 100 |
apt/threat |
IOC と MITRE ATT&CK マッピングを含む APT(国家)脅威レポート | 20 |
apt/threat_actor |
APT 脅威アクターのプロファイル | 100 |
malware/cnc |
コマンド&コントロール(C&C)サーバーのインジケーター(IP、ドメイン) | 100 |
malware/malware |
マルウェアの説明と脅威レベル | 100 |
malware/targeted_malware |
標的型マルウェアのサンプル(ハッシュ、ファイル名) | 100 |
osi/git_leak |
Git リポジトリのデータ漏洩 | 100 |
osi/public_leak |
一般公開データの漏洩(貼り付け、ダンプ) | 100 |
osi/vulnerability |
CVSS スコアを含む脆弱性データ | 100 |
suspicious_ip/tor_node |
Tor 出口ノードの IP アドレス | 100 |
suspicious_ip/open_proxy |
オープン プロキシの IP アドレス | 100 |
suspicious_ip/socks_proxy |
SOCKS プロキシの IP アドレス | 100 |
例: 侵害された認証情報、C2 インフラストラクチャ、APT データを収集するには:
compromised/account,malware/cnc,apt/threat,hi/threat
Cloud Functions のスケジュールを設定する
Cloud Scheduler を使用して、関数を定期的にトリガーする。
- Google Cloud コンソールで [Cloud Scheduler] に移動します。
- [ジョブを作成] をクリックします。
次の構成情報を提供してください。
設定 値 名前 groupib-to-gcs-scheduleリージョン Cloud Functions の関数と同じリージョン 周波数 0 */1 * * *(1 時間ごと)または0 0 * * *(毎日)タイムゾーン タイムゾーンを選択する [実行内容を構成する] で、次の操作を行います。
- ターゲット タイプ: [HTTP] を選択します。
- URL: Cloud Functions のトリガー URL を入力します。
- HTTP メソッド: [POST] を選択します。
- Auth ヘッダー: [OIDC トークンを追加] を選択します。
- サービス アカウント:
roles/cloudfunctions.invoker権限を持つサービス アカウントを選択します。
[作成] をクリックします。
データ エクスポートをテストする
- Cloud Scheduler コンソールで、ジョブの横にある [強制実行] をクリックして、関数を手動でトリガーします。
- Cloud Logging で Cloud Functions のログを確認し、Group-IB からデータが取得されたことを確認します。
- Google Cloud コンソールで、[Cloud Storage] > [バケット] に移動します。
- バケット名(
groupib-ti-logsなど)をクリックします。 - 接頭辞フォルダ(
groupib-ti/など)に移動します。 新しい
.ndjsonファイルがバケットに表示されていることを確認します。
Google SecOps サービス アカウントを取得する
Google SecOps は、一意のサービス アカウントを使用して GCS バケットからデータを読み取ります。このサービス アカウントにバケットへのアクセス権を付与する必要があります。
サービス アカウントのメールアドレスを取得する
- [SIEM 設定] > [フィード] に移動します。
- [Add New Feed] をクリックします。
- [単一フィードを設定] をクリックします。
- [フィード名] フィールドに、フィードの名前を入力します(例:
Group-IB Threat Intelligence)。 - [ソースタイプ] として [Google Cloud Storage V2] を選択します。
- [ログタイプ] として [Group-IB 脅威インテリジェンス] を選択します。
[サービス アカウントを取得する] をクリックします。一意のサービス アカウントのメールアドレスが表示されます。例:
chronicle-12345678@chronicle-gcp-prod.iam.gserviceaccount.comこのメールアドレスをコピーして、次のステップで使用します。
Google SecOps サービス アカウントに IAM 権限を付与する
Google SecOps サービス アカウントには、GCS バケットに対する Storage オブジェクト閲覧者のロールが必要です。
- [Cloud Storage] > [バケット] に移動します。
- バケット名(
groupib-ti-logsなど)をクリックします。 - [権限] タブに移動します。
- [アクセス権を付与] をクリックします。
- 次の構成情報を指定します。
- プリンシパルを追加: Google SecOps サービス アカウントのメールアドレスを貼り付けます。
- ロールを割り当てる: [Storage オブジェクト閲覧者] を選択します。
[保存] をクリックします。
Group-IB 脅威インテリジェンスのログを取り込むように Google SecOps でフィードを構成する
- [SIEM 設定] > [フィード] に移動します。
- [Add New Feed] をクリックします。
- [単一フィードを設定] をクリックします。
- [フィード名] フィールドに、フィードの名前を入力します(例:
Group-IB Threat Intelligence)。 - [ソースタイプ] として [Google Cloud Storage V2] を選択します。
- [ログタイプ] として [Group-IB 脅威インテリジェンス] を選択します。
- [次へ] をクリックします。
次の入力パラメータの値を指定します。
ストレージ バケットの URL: 接頭辞パスを含む GCS バケット URI を入力します。
gs://groupib-ti-logs/groupib-ti/次のように置き換えます。
groupib-ti-logs: GCS バケット名。groupib-ti: ログが保存される接頭辞/フォルダパス。
Source deletion option: 必要に応じて削除オプションを選択します。
- なし: 転送後にファイルを削除しません(テストに推奨)。
- 転送されたファイルを削除する: 転送が完了した後にファイルを削除します。
- 転送されたファイルと空のディレクトリを削除する: 転送が完了した後にファイルと空のディレクトリを削除します。
ファイルの最長存続期間: 過去数日間に変更されたファイルを含めます。デフォルトは 180 日です。
Asset namespace: アセットの名前空間。
Ingestion labels: このフィードのイベントに適用されるラベル。
[次へ] をクリックします。
[Finalize] 画面で新しいフィードの設定を確認し、[送信] をクリックします。
さらにサポートが必要な場合 コミュニティ メンバーや Google SecOps のプロフェッショナルから回答を得ることができます。