ServiceNow Security ログを収集する
このドキュメントでは、ビジネスルールで構成されたアウトバウンド Webhook を使用して、ServiceNow Security イベントを Google Security Operations にエクスポートする方法について説明します。取り込みラベルによって、未加工のログデータを構造化 UDM 形式に正規化するパーサーが識別されます。
統合アーキテクチャ
この統合では、ServiceNow ビジネスルールを使用して、セキュリティ イベントを Google SecOps にリアルタイムでプッシュします。
ServiceNow Security Tables ↓ (Business Rules trigger on insert/update) ServiceNow RESTMessageV2 API ↓ (HTTP POST) Google Security Operations Webhook Endpoint ↓ (Parser: SERVICENOW_SECURITY) Unified Data Model (UDM)
統合の特徴:
- イベント ドリブン プッシュ: 作成または更新されたときにすぐに送信されるイベント
- リアルタイム: 低レイテンシ(秒)
- 選択的エクスポート: エクスポートするテーブルとイベントを構成する
- 一括エクスポートではない: 過去のデータは送信されません
始める前に
次の前提条件を満たしていることを確認してください。
- Google SecOps インスタンス
- セキュリティ インシデント対応(SIR)プラグインがインストールされている ServiceNow インスタンス
- 次のロールを持つ ServiceNow ユーザー アカウント:
adminまたはsn_si.admin(ビジネスルールを作成する場合)- [System Definition] > [Business Rules] へのアクセス権
- システム定義 > スクリプト インクルードへのアクセス
- Google Google Cloud コンソールへの特権アクセス(API キーの作成用)
エクスポート用の ServiceNow Security テーブル
次の表に、SIEM 分析に関連するセキュリティ データを示します。
| テーブル | API 名 | 説明 | 優先度 |
|---|---|---|---|
| セキュリティ インシデント | sn_si_incident |
セキュリティ インシデント、調査 | HIGH |
| 観測可能 | sn_si_observable |
IOC: IP アドレス、ドメイン、ファイル ハッシュ | HIGH |
| システムログ | syslog |
認証イベント、ログイン失敗 | MEDIUM |
| 監査 | sys_audit |
フィールド レベルの変更、権限の変更 | MEDIUM |
| ユーザーロールの割り当て | sys_user_has_role |
ロールの付与/取り消し | LOW |
| セキュリティの検出結果 | sn_si_finding |
セキュリティの検出と検出結果 | LOW |
このガイドでは、優先度「HIGH」のテーブルのビジネスルールの例を示します。同じパターンを使用して、統合を他のテーブルに拡張できます。
ServiceNow Security イベントを取り込むように Google SecOps でフィードを構成する
Webhook フィードを設定する
- [SIEM 設定] > [フィード] に移動します。
- [Add New Feed] をクリックします。
- 次のページで [単一のフィードを設定] をクリックします。
- [フィード名] フィールドに、フィードの名前を入力します(例:
ServiceNow Security Events)。 - [Source type] として [Webhook] を選択します。
- [ログタイプ] として [ServiceNow Security] を選択します。
- [次へ] をクリックします。
フィード パラメータを構成する
次の入力パラメータの値を指定します。
- Split delimiter: ログ行を区切るには、
\nと入力します。 - アセットの名前空間: アセットの名前空間。
- Ingestion labels: このフィードのすべてのイベントに適用されるラベル。
- Split delimiter: ログ行を区切るには、
[次へ] をクリックします。
[Finalize] 画面で新しいフィードの設定を確認し、[送信] をクリックします。
秘密鍵を生成してエンドポイント URL を取得する
- [秘密鍵を生成する] をクリックして、このフィードを認証するためのシークレット キーを生成します。
シークレット キーをコピーして安全な場所に保存します。
[詳細] タブに移動します。
[エンドポイント情報] フィールドから、フィードのエンドポイント URL をコピーします。
- エンドポイント URL の例:
https://malachiteingestion-pa.googleapis.com/v2/unstructured/projects/PROJECT_ID/locations/LOCATION/instances/INSTANCE_ID/logTypes/SERVICENOW_SECURITY:import
- エンドポイント URL の例:
[完了] をクリックします。
認証用の API キーを作成する
- Google Cloud コンソールの [認証情報] ページに移動します。
- [認証情報を作成] をクリックして [API キー] を選択します。
- [キーを制限] をクリックします。
- [API の制限] で次の操作を行います。
- [キーを制限] を選択します。
- [Google SecOps API](Chronicle API)を選択します。
- [保存] をクリックします。
- API キーをコピーして、安全な場所に保存します。
ServiceNow 統合の認証情報を構成する
安全なアクセスを実現するため、Google SecOps の認証情報を ServiceNow システム プロパティとして保存します。
- ServiceNow で、[System Properties] > sys_properties.list に移動します。
- [New] をクリックします。
- 最初のプロパティを作成します。
- 名前:
x_chronicle.endpoint_url - 値: 前の手順でコピーしたフィードのエンドポイント URL を貼り付けます。
- タイプ:
string
- 名前:
- [送信] をクリックします。
- [新規] をクリックして、2 つ目のプロパティを作成します。
- 名前:
x_chronicle.api_key - 値: Google Cloud API キーを貼り付けます。
- 型:
password(値を暗号化します)
- 名前:
- [送信] をクリックします。
- [新規] をクリックして、3 つ目のプロパティを作成します。
- 名前:
x_chronicle.secret_key - 値: Google SecOps フィードの秘密鍵を貼り付けます。
- 型:
password(値を暗号化します)
- 名前:
- [送信] をクリックします。
再利用可能な Webhook ユーティリティのスクリプト インクルードを作成する
このスクリプト インクルードは、任意のビジネスルールから Google SecOps にイベントを送信するための再利用可能な関数を提供します。
- [System Definition> Script Includes] に移動します。
- [New] をクリックします。
- 次の構成の詳細を指定します。
- 名前:
ChronicleWebhookUtil - API 名:
ChronicleWebhookUtil - クライアント呼び出し可能: チェックを外します
- 有効: チェックボックスをオンにする
- 名前:
[スクリプト] フィールドに次のコードを入力します。
var ChronicleWebhookUtil = Class.create(); ChronicleWebhookUtil.prototype = { initialize: function() { // Read credentials from System Properties this.endpointURL = gs.getProperty('x_chronicle.endpoint_url'); this.apiKey = gs.getProperty('x_chronicle.api_key'); this.secretKey = gs.getProperty('x_chronicle.secret_key'); }, sendEvent: function(eventData, eventType) { try { // Validate credentials if (!this.endpointURL || !this.apiKey || !this.secretKey) { gs.error('[Chronicle] Missing configuration. Check System Properties: x_chronicle.*'); return false; } // Prepare payload var payload = { event_type: eventType, timestamp: new GlideDateTime().getDisplayValue(), data: eventData, source: "ServiceNow", source_instance: gs.getProperty('instance_name') }; // Create REST message var request = new sn_ws.RESTMessageV2(); request.setEndpoint(this.endpointURL + '?key=' + this.apiKey); request.setHttpMethod('POST'); // Set headers request.setRequestHeader('Content-Type', 'application/json'); request.setRequestHeader('x-chronicle-auth', this.secretKey); // Set request body request.setRequestBody(JSON.stringify(payload)); // Execute request var response = request.execute(); var statusCode = response.getStatusCode(); var responseBody = response.getBody(); // Check response if (statusCode == 200 || statusCode == 201 || statusCode == 204) { gs.info('[Chronicle] Event sent successfully: ' + eventType + ' | Status: ' + statusCode); return true; } else { gs.error('[Chronicle] Failed to send event: ' + eventType + ' | Status: ' + statusCode + ' | Response: ' + responseBody); return false; } } catch (ex) { gs.error('[Chronicle] Exception sending event: ' + ex.message); return false; } }, type: 'ChronicleWebhookUtil' };[送信] をクリックします。
イベント エクスポートのビジネスルールを作成する
ビジネスルールは、ServiceNow テーブルでレコードが作成または更新されると自動的にトリガーされます。Google SecOps にエクスポートするテーブルごとにビジネスルールを作成します。
ビジネスルール: セキュリティ インシデント
このビジネスルールは、セキュリティ インシデント イベントを Google SecOps にエクスポートします。
- [System Definition] > [Business Rules] に移動します。
- [New] をクリックします。
次の構成情報を提供してください。
実行するタイミング:
フィールド 値 名前 Chronicle - Export Security Incidentテーブル Security Incident [sn_si_incident]有効 オン 上級 オン 日時 after挿入 オン 更新 オン 削除 省略可(削除を追跡する場合はオンにします) Order 100[詳細設定] タブをクリックし、[スクリプト] フィールドに次のコードを入力します。
(function executeRule(current, previous /*null when async*/) { // Extract incident data var incidentData = { sys_id: current.getValue('sys_id'), number: current.getValue('number'), short_description: current.getValue('short_description'), description: current.getValue('description'), state: current.getDisplayValue('state'), priority: current.getDisplayValue('priority'), severity: current.getDisplayValue('severity'), risk_score: current.getValue('risk_score'), category: current.getDisplayValue('category'), subcategory: current.getDisplayValue('subcategory'), assigned_to: current.getDisplayValue('assigned_to'), assignment_group: current.getDisplayValue('assignment_group'), caller: current.getDisplayValue('caller'), affected_user: current.getDisplayValue('affected_user'), opened_at: current.getValue('opened_at'), closed_at: current.getValue('closed_at'), resolved_at: current.getValue('resolved_at'), sys_created_on: current.getValue('sys_created_on'), sys_updated_on: current.getValue('sys_updated_on'), sys_created_by: current.getValue('sys_created_by'), sys_updated_by: current.getValue('sys_updated_by'), work_notes: current.getValue('work_notes'), close_notes: current.getValue('close_notes') }; // Send to Chronicle var chronicleUtil = new ChronicleWebhookUtil(); chronicleUtil.sendEvent(incidentData, 'security_incident'); })(current, previous);[送信] をクリックします。
ビジネスルール: オブザーバブル(IOC)
このビジネスルールは、オブザーバブル データ(IP アドレス、ドメイン、ファイル ハッシュ)を Google SecOps にエクスポートします。
- [System Definition] > [Business Rules] に移動します。
- [New] をクリックします。
次の構成情報を提供してください。
フィールド 値 名前 Chronicle - Export Observableテーブル Observable [sn_si_observable]有効 オン 上級 オン 日時 after挿入 オン 更新 オン Order 100[詳細設定] タブをクリックし、[スクリプト] フィールドに次のコードを入力します。
(function executeRule(current, previous) { var observableData = { sys_id: current.getValue('sys_id'), value: current.getValue('value'), type: current.getDisplayValue('type'), finding: current.getDisplayValue('finding'), sighting_count: current.getValue('sighting_count'), notes: current.getValue('notes'), security_tags: current.getValue('security_tags'), mitre_technique: current.getDisplayValue('mitre_technique'), mitre_tactic: current.getDisplayValue('mitre_tactic'), mitre_malware: current.getDisplayValue('mitre_malware'), sys_created_on: current.getValue('sys_created_on'), sys_created_by: current.getValue('sys_created_by') }; var chronicleUtil = new ChronicleWebhookUtil(); chronicleUtil.sendEvent(observableData, 'observable'); })(current, previous);[送信] をクリックします。
ビジネスルール: システム ログイン イベント
このビジネスルールは、認証イベントとログイン イベントを Google SecOps にエクスポートします。
- [System Definition] > [Business Rules] に移動します。
- [New] をクリックします。
次の構成情報を提供してください。
フィールド 値 名前 Chronicle - Export System Logテーブル System Log [syslog]有効 オン 上級 オン 日時 after挿入 オン Order 100条件 current.level == "error" || current.source.indexOf("login") != -1[詳細設定] タブをクリックし、[スクリプト] フィールドに次のコードを入力します。
(function executeRule(current, previous) { var logData = { sys_id: current.getValue('sys_id'), level: current.getValue('level'), source: current.getValue('source'), message: current.getValue('message'), sys_created_on: current.getValue('sys_created_on'), sys_created_by: current.getValue('sys_created_by') }; var chronicleUtil = new ChronicleWebhookUtil(); chronicleUtil.sendEvent(logData, 'system_log'); })(current, previous);[送信] をクリックします。
ビジネスルール: 監査証跡(権限の変更)
このビジネスルールは、監査証跡の目的でフィールド レベルの変更をエクスポートします。
- [System Definition] > [Business Rules] に移動します。
- [New] をクリックします。
次の構成情報を提供してください。
フィールド 値 名前 Chronicle - Export Audit Changesテーブル Audit [sys_audit]有効 オン 上級 オン 日時 after挿入 オン Order 100条件 次のスクリプトをご覧ください。 条件(重大な変更のみをフィルタ):
```javascript current.tablename == 'sys_user_has_role' || current.tablename == 'sys_user_group_member' || current.tablename == 'sn_si_incident' || current.fieldname == 'active' || current.fieldname == 'locked_out' ```[詳細設定] タブをクリックし、[スクリプト] フィールドに次のコードを入力します。
(function executeRule(current, previous) { var auditData = { sys_id: current.getValue('sys_id'), tablename: current.getValue('tablename'), documentkey: current.getValue('documentkey'), fieldname: current.getValue('fieldname'), oldvalue: current.getValue('oldvalue'), newvalue: current.getValue('newvalue'), user: current.getDisplayValue('user'), reason: current.getValue('reason'), sys_created_on: current.getValue('sys_created_on') }; var chronicleUtil = new ChronicleWebhookUtil(); chronicleUtil.sendEvent(auditData, 'audit_change'); })(current, previous);[送信] をクリックします。
省略可: エクスポートする追加のテーブル
ユーザーロールの割り当ての変更
セキュリティ監査のためにロールの付与と取り消しをエクスポートします。
sys_user_has_roleテーブルにビジネスルールを作成します。(function executeRule(current, previous) { var roleData = { sys_id: current.getValue('sys_id'), user: current.getDisplayValue('user'), role: current.getDisplayValue('role'), granted_by: current.getDisplayValue('granted_by'), state: current.getValue('state'), sys_created_on: current.getValue('sys_created_on') }; var chronicleUtil = new ChronicleWebhookUtil(); chronicleUtil.sendEvent(roleData, 'role_assignment'); })(current, previous);
セキュリティの検出結果
セキュリティの検出と検出結果をエクスポートします。
sn_si_findingテーブルにビジネスルールを作成します。(function executeRule(current, previous) { var findingData = { sys_id: current.getValue('sys_id'), finding: current.getValue('finding'), confidence: current.getValue('confidence'), severity: current.getDisplayValue('severity'), observable: current.getDisplayValue('observable'), sys_created_on: current.getValue('sys_created_on') }; var chronicleUtil = new ChronicleWebhookUtil(); chronicleUtil.sendEvent(findingData, 'finding'); })(current, previous);
Google SecOps フィードの詳細については、Google SecOps フィードのドキュメントをご覧ください。各フィードタイプの要件については、タイプ別のフィード構成をご覧ください。
フィードの作成時に問題が発生した場合は、Google SecOps サポートにお問い合わせください。
UDM マッピング テーブル
| ServiceNow フィールド | UDM マッピング | ロジック |
|---|---|---|
number |
metadata.product_event_type |
インシデント番号またはイベント番号 |
short_description |
security_result.summary |
セキュリティ イベントの簡単な説明 |
severity |
security_result.severity |
イベントの重大度レベル |
priority |
security_result.priority |
イベントの優先度 |
caller |
principal.user.userid |
イベントを報告またはトリガーしたユーザー |
affected_user |
target.user.userid |
セキュリティ イベントの影響を受けたユーザー |
assigned_to |
security_result.action_details |
インシデントに割り当てられたアナリスト |
sys_created_on |
metadata.event_timestamp |
イベント作成のタイムスタンプ |
value(観測可能) |
network.ip または network.dns.questions.name |
オブザーバブル値(IP、ドメイン、ハッシュ) |
type(観測可能) |
security_result.detection_fields.value |
オブザーバブルのタイプ(IP アドレス、ドメイン、ファイル ハッシュ) |
さらにサポートが必要な場合 コミュニティ メンバーや Google SecOps のプロフェッショナルから回答を得ることができます。