mcpField
P
performing-ot-vulnerability-assessment-with-claroty

performing-ot-vulnerability-assessment-with-claroty

github.com/mukul975セキュリティ35.2k61 回インストール8 週間前に更新
リポジトリ

performing-ot-vulnerability-assessment-with-claroty について

Claroty を使った脆弱性評価を行う OT セキュリティチーム向けの実践スキルです。資産の検出、アドバイザリとの照合、リスクの優先順位付けを扱い、コンプライアンス評価や限られた保守期間での修正計画に役立ちます。

主な機能

  1. 01OT 資産とファームウェア情報の検出
  2. 02ICS-CERT 情報と脆弱性の照合
  3. 03資産の重要度を踏まえたリスク評価
  4. 04リスクに基づく修正の優先順位付け
  5. 05脆弱性評価レポートの作成

活用シーン

  1. 01IEC 62443 または NERC CIP に沿った評価
  2. 02Claroty xDome 導入後の資産棚卸し
  3. 03OT 資産と新しい ICS アドバイザリの照合
  4. 04保守期間内の脆弱性修正計画

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/mukul975/anthropic-cybersecurity-skills --skill performing-ot-vulnerability-assessment-with-claroty

インストール後、Claude Code で/performing-ot-vulnerability-assessment-with-clarotyを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

LICENSE
references/
api-reference.md
scripts/
agent.py

詳細

Claroty を使用した OT 脆弱性評価の実施

使用する場合

  • IEC 62443 または NERC CIP の要件に従って、定期的な OT 脆弱性評価を実施する場合
  • Claroty xDome を初めて導入し、初期の資産検出とリスク評価を実施する場合
  • 新たに公開された ICS-CERT の勧告を OT 資産インベントリと照合する場合
  • メンテナンス時間が限られている中で、OT 脆弱性の修復に優先順位を付ける場合
  • CIP-010-4 の脆弱性評価要件に関するコンプライアンス証跡を作成する場合

次の場合には使用しないでください:PLC や安全システムに対するアクティブな脆弱性スキャン(パッシブな方法については performing-ot-network-security-assessment を参照)、IT のみを対象とする脆弱性管理(標準的な脆弱性スキャナーを参照)、またはペネトレーションテスト(performing-ics-penetration-testing を参照)。

前提条件

  • OT ネットワーク上にセンサーを配置した Claroty xDome または CTD(Continuous Threat Detection)
  • パッシブな資産検出のためのネットワーク SPAN/TAP アクセス
  • 脆弱性を追跡するための CISA ICS-CERT 勧告の購読
  • すべての OT デバイスのファームウェアバージョンを含む資産インベントリ
  • メンテナンス時間中のパッチ適用に関する変更管理プロセス

ワークフロー

ステップ 1:資産検出と脆弱性の照合を設定する

ファームウェアバージョンを含む完全な資産インベントリを構築し、脆弱性を照合できるよう、Claroty でパッシブ検出と安全なアクティブ検出を設定します。

#!/usr/bin/env python3
"""OT Vulnerability Assessment Manager.

Correlates OT asset inventory with ICS-CERT advisories and CVE data
to identify, prioritize, and track OT vulnerabilities. Designed to
integrate with Claroty xDome API or standalone operation.
"""

import json
import sys
from collections import defaultdict
from dataclasses import dataclass, field, asdict
from datetime import datetime

import requests


@dataclass
class OTAsset:
    asset_id: str
    name: str
    vendor: str
    model: str
    firmware_version: str
    asset_type: str  # PLC, HMI, RTU, historian, switch, etc.
    purdue_level: str
    ip_address: str
    protocol: str
    criticality: str  # critical, high, medium, low
    zone: str


@dataclass
class OTVulnerability:
    vuln_id: str
    cve_id: str
    title: str
    severity: str  # critical, high, medium, low
    cvss_score: float
    affected_vendor: str
    affected_product: str
    affected_versions: str
    description: str
    ics_cert_advisory: str = ""
    remediation: str = ""
    patch_available: bool = False
    compensating_controls: str = ""


@dataclass
class RiskAssessment:
    asset: OTAsset
    vulnerability: OTVulnerability
    risk_score: float = 0.0
    risk_rating: str = ""
    exploitability: str = ""
    operational_impact: str = ""
    compensating_controls: list = field(default_factory=list)
    remediation_priority: int = 0


class OTVulnerabilityAssessment:
    """OT vulnerability assessment and prioritization engine."""

    def __init__(self):
        self.assets = []
        self.vulnerabilities = []
        self.risk_assessments = []

    def load_assets(self, assets_data):
        """Load asset inventory from Claroty export or manual inventory."""
        for a in assets_data:
            self.assets.append(OTAsset(**a))
        print(f"[*] Loaded {len(self.assets)} OT assets")

    def fetch_ics_advisories(self):
        """Fetch latest ICS-CERT advisories from CISA."""
        print("[*] Fetching ICS-CERT advisories from CISA...")
        try:
            # CISA Known Exploited Vulnerabilities catalog
            url = "https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json"
            resp = requests.get(url, timeout=30)
            resp.raise_for_status()
            data = resp.json()

            ics_vulns = []
            for vuln in data.get("vulnerabilities", []):
                # Filter for ICS-relevant vendors
                ics_vendors = [
                    "siemens", "schneider", "rockwell", "honeywell",
                    "abb", "ge", "emerson", "yokogawa", "omron",
                    "mitsubishi", "phoenix", "moxa", "advantech",
                ]
                vendor = vuln.get("vendorProject", "").lower()
                if any(v in vendor for v in ics_vendors):
                    ics_vulns.append(vuln)

            print(f"  Found {len(ics_vulns)} ICS-relevant known exploited vulnerabilities")
            return ics_vulns

        except Exception as e:
            print(f"[WARN] Could not fetch advisories: {e}")
            return []

    def correlate_vulnerabilities(self):
        """Match vulnerabilities to assets based on vendor/model/firmware."""
        print("[*] Correlating vulnerabilities to assets...")

        for asset in self.assets:
            for vuln in self.vulnerabilities:
                if (vuln.affected_vendor.lower() in asset.vendor.lower() and
                    vuln.affected_product.lower() in asset.model.lower()):
                    # Check firmware version if specified
                    ra = RiskAssessment(asset=asset, vulnerability=vuln)
                    self._calculate_risk_score(ra)
                    self.risk_assessments.append(ra)

        print(f"  Correlated {len(self.risk_assessments)} asset-vulnerability pairs")

    def _calculate_risk_score(self, ra):
        """Calculate OT-specific risk score considering operational impact."""
        # Base score from CVSS
        base = ra.vulnerability.cvss_score

        # Criticality multiplier based on asset function
        criticality_weights = {
            "critical": 1.5,  # SIS, safety systems
            "high": 1.3,      # PLCs, primary control
            "medium": 1.0,    # HMIs, historians
            "low": 0.7,       # non-critical support systems
        }
        criticality = criticality_weights.get(ra.asset.criticality, 1.0)

        # Purdue level proximity factor (lower levels = higher risk)
        level_weights = {
            "Level 0-1": 1.5,
            "Level 2": 1.3,
            "Level 3": 1.0,
            "Level 3.5": 0.8,
            "Level 4": 0.6,
        }
        level_factor = level_weights.get(ra.asset.purdue_level, 1.0)

        # Network exposure reduction if compensating controls exist
        comp_reduction = 0.8 if ra.compensating_controls else 1.0

        ra.risk_score = round(base * criticality * level_factor * comp_reduction, 1)
        ra.risk_score = min(ra.risk_score, 10.0)

        if ra.risk_score >= 9.0:
            ra.risk_rating = "critical"
            ra.remediation_priority = 1
        elif ra.risk_score >= 7.0:
            ra.risk_rating = "high"
            ra.remediation_priority = 2
        elif ra.risk_score >= 4.0:
            ra.risk_rating = "medium"
            ra.remediation_priority = 3
        else:
            ra.risk_rating = "low"
            ra.remediation_priority = 4

    def generate_report(self):
        """Generate vulnerability assessment report."""
        # Sort by risk score descending
        sorted_ra = sorted(self.risk_assessments, key=lambda x: -x.risk_score)

        report = []
        report.append("=" * 70)
        report.append("OT VULNERABILITY ASSESSMENT REPORT")
        report.append(f"Date: {datetime.now().isoformat()}")
        report.append(f"Assets: {len(self.assets)} | Vulnerabilities: {len(self.vulnerabilities)}")
        report.append(f"Risk Assessments: {len(self.risk_assessments)}")
        report.append("=" * 70)

        for sev in ["critical", "high", "medium", "low"]:
            findings = [ra for ra in sorted_ra if ra.risk_rating == sev]
            if findings:
                report.append(f"\n--- {sev.upper()} RISK ({len(findings)}) ---")
                for ra in findings[:10]:
                    report.append(f"\n  Risk Score: {ra.risk_score}/10.0")
                    report.append(f"  Asset: {ra.asset.name} ({ra.asset.vendor} {ra.asset.model})")
                    report.append(f"  Zone: {ra.asset.zone} ({ra.asset.purdue_level})")
                    report.append(f"  CVE: {ra.vulnerability.cve_id} (CVSS: {ra.vulnerability.cvss_score})")
                    report.append(f"  Title: {ra.vulnerability.title}")
                    if ra.vulnerability.patch_available:
                        report.append(f"  Patch: Available - schedule for next maintenance window")
                    else:
                        report.append(f"  Patch: Not available - apply compensating controls")

        return "\n".join(report)

    def export_json(self, output_file):
        """Export assessment to JSON."""
        data = {
            "assessment_date": datetime.now().isoformat(),
            "asset_count": len(self.assets),
            "vulnerability_count": len(self.vulnerabilities),
            "risk_assessments": [
                {
                    "asset_name": ra.asset.name,
                    "asset_ip": ra.asset.ip_address,
                    "cve": ra.vulnerability.cve_id,
                    "risk_score": ra.risk_score,
                    "risk_rating": ra.risk_rating,
                    "priority": ra.remediation_priority,
                }
                for ra in sorted(self.risk_assessments, key=lambda x: -x.risk_score)
            ],
        }
        with open(output_file, "w") as f:
            json.dump(data, f, indent=2)


if __name__ == "__main__":
    assessment = OTVulnerabilityAssessment()
    advisories = assessment.fetch_ics_advisories()
    print(f"Fetched {len(advisories)} ICS advisories from CISA KEV catalog")

主な概念

用語定義
Claroty xDomeOT/IoT 環境向けに資産検出、脆弱性管理、脅威検出を提供するサイバーフィジカルシステム保護プラットフォーム
パッシブ検出パケットを送信せずにネットワークトラフィックを分析して OT 資産を特定する方法。本番環境でも安全に使用できます
安全なアクティブクエリ運用を妨げない安全な速度で、ネイティブの産業用プロトコルを使用して OT デバイスに問い合わせ、詳細な資産情報を収集する方法
OT リスクスコアCVSS 基本スコア、資産の重要度、Purdue レベル、補完的な制御を考慮し、OT に適した優先順位付けを行うリスク評価
ICS-CERT 勧告産業用制御システムの脆弱性に関する、CISA が公開するセキュリティ勧告。ベンダー固有の修復ガイダンスが含まれます
仮想パッチファームウェアパッチをすぐに適用できない場合に、既知の脆弱性の悪用をブロックするための IPS/ファイアウォールルールを導入すること

ツールとシステム

  • Claroty xDome:OT/IoT 資産の包括的な検出、脆弱性管理、継続的な脅威検出を提供するプラットフォーム
  • Claroty CTD:OT 環境のパッシブなネットワーク監視を行う、継続的脅威検出センサー
  • CISA ICS-CERT:ICS の脆弱性通知と緩和ガイダンスを公開する米国政府の勧告サービス
  • Dragos Platform:資産の可視化と脆弱性管理機能を備えた、OT セキュリティプラットフォームの代替製品
  • Nozomi Networks Guardian:脆弱性の照合とリスクスコアリング機能を備えた OT 監視プラットフォーム

出力形式

OT Vulnerability Assessment Report
=====================================
Tool: Claroty xDome / Manual Assessment
Date: YYYY-MM-DD
Assets Scanned: [N]

RISK SUMMARY:
  Critical Risk: [N] vulnerabilities on [N] assets
  High Risk: [N] vulnerabilities on [N] assets
  Medium Risk: [N] vulnerabilities on [N] assets
  Low Risk: [N] vulnerabilities on [N] assets

TOP RISKS:
  [Risk Score] [CVE-ID] on [Asset Name] ([Zone])
    Remediation: [Patch/Compensating Control]
    Timeline: [Next maintenance window / Immediate]

コメント