mcpField
P
performing-scada-hmi-security-assessment

performing-scada-hmi-security-assessment

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

performing-scada-hmi-security-assessment について

SCADAおよびDCS環境のHMIシステムを評価するセキュリティスキルです。認証、通信、設定、Webインターフェースのリスクを中心に、認可済みテストやコンプライアンス評価を支援します。

主な機能

  1. 01HMIの攻撃対象領域の評価
  2. 02認証と認可の確認
  3. 03HMIとPLC間の通信評価
  4. 04Webインターフェースの脆弱性確認
  5. 05IEC 62443およびNIST SP 800-82に沿った評価

活用シーン

  1. 01ラボ環境でのHMI評価
  2. 02WebベースHMIのセキュリティ確認
  3. 03IEC 62443またはNERC CIP評価の準備

インストール

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

$npx skills add https://github.com/mukul975/anthropic-cybersecurity-skills --skill performing-scada-hmi-security-assessment

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

同梱ファイル

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

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

詳細

SCADA HMI セキュリティアセスメントの実施

使用するタイミング

  • SCADA/DCS 環境における HMI システムのセキュリティ態勢を評価するとき
  • Web ベースの HMI インターフェースに一般的な Web 脆弱性がないかを評価するとき
  • HMI の認証、認可、セッション管理を監査するとき
  • HMI と PLC/RTU の間の通信セキュリティをテストするとき
  • IEC 62443 または NERC CIP のコンプライアンスアセスメントに備えるとき

使用しないでください 保守時間枠とロールバック計画がないまま稼働中の本番 HMI をテストする場合、PLC レベルのプロトコル分析(performing-s7comm-protocol-security-analysis を参照)を行う場合、または OT 以外のシステムに対する一般的な Web アプリケーションテストを行う場合。

前提条件

  • ベンダー、バージョン、ネットワーク構成の詳細を含む HMI システムのインベントリ
  • 本番の HMI 構成を再現したラボまたはテスト環境(アクティブテストに推奨)
  • 保守時間帯のテストについて、プラント運用部門からの承認
  • NIST SP 800-82 および IEC 62443 のセキュリティ要件ドキュメント
  • HMI と PLC の通信セグメントでのネットワークキャプチャ機能

ワークフロー

ステップ 1: HMI の攻撃対象領域の評価
#!/usr/bin/env python3
"""SCADA HMI Security Assessment Tool.

Evaluates HMI security across authentication, communication,
configuration, and web interface categories aligned with
IEC 62443 and NIST SP 800-82 requirements.
"""

import json
import sys
from datetime import datetime
from typing import Dict, List

try:
    import requests
except ImportError:
    print("Install requests: pip install requests")
    sys.exit(1)


class HMISecurityAssessment:
    """Performs security assessment of SCADA HMI systems."""

    def __init__(self, hmi_info: dict):
        self.hmi_info = hmi_info
        self.findings = []
        self.checks_run = 0
        self.checks_passed = 0

    def check_authentication(self):
        """Assess HMI authentication mechanisms."""
        checks = [
            {
                "id": "AUTH-01",
                "name": "Password complexity enforcement",
                "iec62443_ref": "ISA-62443-3-3 SR 1.7",
                "description": "HMI must enforce minimum password complexity requirements",
                "test": "Verify minimum length >= 8, complexity rules, history >= 5",
            },
            {
                "id": "AUTH-02",
                "name": "Account lockout policy",
                "iec62443_ref": "ISA-62443-3-3 SR 1.11",
                "description": "HMI must lock accounts after failed login attempts",
                "test": "Verify lockout after 5 failed attempts, lockout duration >= 15 min",
            },
            {
                "id": "AUTH-03",
                "name": "Default credentials changed",
                "iec62443_ref": "ISA-62443-3-3 SR 1.5",
                "description": "All default vendor credentials must be changed",
                "test": "Attempt login with known vendor defaults (admin/admin, operator/operator)",
            },
            {
                "id": "AUTH-04",
                "name": "Role-based access control",
                "iec62443_ref": "ISA-62443-3-3 SR 2.1",
                "description": "HMI must separate operator, engineer, and admin roles",
                "test": "Verify operator role cannot access engineering functions",
            },
            {
                "id": "AUTH-05",
                "name": "Session timeout enforcement",
                "iec62443_ref": "ISA-62443-3-3 SR 1.12",
                "description": "HMI sessions must time out after inactivity",
                "test": "Verify session timeout <= 15 minutes for operator, <= 5 for admin",
            },
            {
                "id": "AUTH-06",
                "name": "Multi-factor authentication for remote access",
                "iec62443_ref": "ISA-62443-3-3 SR 1.13",
                "description": "Remote HMI access requires MFA",
                "test": "Verify MFA is enforced for all non-local HMI connections",
            },
        ]

        print(f"\n--- AUTHENTICATION ASSESSMENT ---")
        for check in checks:
            self.checks_run += 1
            print(f"  [{check['id']}] {check['name']}")
            print(f"    Ref: {check['iec62443_ref']}")
            print(f"    Test: {check['test']}")

    def check_communication_security(self):
        """Assess HMI-to-PLC communication security."""
        checks = [
            {
                "id": "COMM-01",
                "name": "Encrypted HMI-PLC communication",
                "description": "Traffic between HMI and PLCs should use encrypted protocols (OPC UA with TLS)",
                "test": "Capture HMI-PLC traffic and verify encryption (Wireshark TLS handshake)",
            },
            {
                "id": "COMM-02",
                "name": "HMI write command authentication",
                "description": "Write commands from HMI to PLC should be authenticated",
                "test": "Verify that write operations require operator confirmation/authentication",
            },
            {
                "id": "COMM-03",
                "name": "Web HMI uses HTTPS",
                "description": "Web-based HMI interfaces must use TLS 1.2+ with valid certificates",
                "test": "Check TLS version, cipher suites, certificate validity",
            },
            {
                "id": "COMM-04",
                "name": "No cleartext protocols in use",
                "description": "Telnet, FTP, HTTP must not be used for HMI access or management",
                "test": "Port scan HMI for cleartext protocol services",
            },
        ]

        print(f"\n--- COMMUNICATION SECURITY ASSESSMENT ---")
        for check in checks:
            self.checks_run += 1
            print(f"  [{check['id']}] {check['name']}")
            print(f"    Test: {check['test']}")

    def check_web_hmi_security(self):
        """Assess web-based HMI for common web vulnerabilities."""
        hmi_url = self.hmi_info.get("url", "")
        if not hmi_url:
            print(f"\n  [SKIP] No web HMI URL provided")
            return

        checks = [
            {
                "id": "WEB-01",
                "name": "Cross-Site Scripting (XSS)",
                "owasp": "A7:2017",
                "test": "Test input fields with XSS payloads in tag names, alarm messages",
            },
            {
                "id": "WEB-02",
                "name": "Cross-Site Request Forgery (CSRF)",
                "owasp": "A8:2013",
                "test": "Verify CSRF tokens on state-changing operations (setpoint changes)",
            },
            {
                "id": "WEB-03",
                "name": "Insecure Direct Object References",
                "owasp": "A4:2013",
                "test": "Manipulate URL parameters to access other users HMI views",
            },
            {
                "id": "WEB-04",
                "name": "Security Headers",
                "test": "Verify X-Frame-Options, CSP, X-Content-Type-Options headers",
            },
            {
                "id": "WEB-05",
                "name": "Privileged file system access (CVE-2025-0921)",
                "test": "Check Ignition SCADA for privileged file system vulnerability via project files",
            },
        ]

        print(f"\n--- WEB HMI SECURITY ASSESSMENT ---")
        print(f"  Target: {hmi_url}")
        for check in checks:
            self.checks_run += 1
            print(f"  [{check['id']}] {check['name']}")
            print(f"    Test: {check['test']}")

    def check_hardening(self):
        """Assess HMI operating system and application hardening."""
        checks = [
            {
                "id": "HARD-01",
                "name": "OS patch level",
                "test": "Verify HMI OS is patched within SLA (typically 90 days for OT)",
            },
            {
                "id": "HARD-02",
                "name": "Unnecessary services disabled",
                "test": "Verify no unnecessary network services running (RDP if not needed, SMB, etc)",
            },
            {
                "id": "HARD-03",
                "name": "USB port restrictions",
                "test": "Verify USB mass storage is blocked on HMI terminals",
            },
            {
                "id": "HARD-04",
                "name": "Application whitelisting",
                "test": "Verify only authorized HMI applications can execute",
            },
            {
                "id": "HARD-05",
                "name": "Audit logging enabled",
                "test": "Verify operator actions, login events, and setpoint changes are logged",
            },
        ]

        print(f"\n--- HMI HARDENING ASSESSMENT ---")
        for check in checks:
            self.checks_run += 1
            print(f"  [{check['id']}] {check['name']}")
            print(f"    Test: {check['test']}")

    def generate_report(self):
        """Generate assessment report."""
        self.check_authentication()
        self.check_communication_security()
        self.check_web_hmi_security()
        self.check_hardening()

        print(f"\n{'='*70}")
        print("SCADA HMI SECURITY ASSESSMENT SUMMARY")
        print(f"{'='*70}")
        print(f"Date: {datetime.now().isoformat()}")
        print(f"HMI: {self.hmi_info.get('name', 'Unknown')}")
        print(f"Vendor: {self.hmi_info.get('vendor', 'Unknown')}")
        print(f"Version: {self.hmi_info.get('version', 'Unknown')}")
        print(f"Total Checks: {self.checks_run}")
        print(f"Findings: {len(self.findings)}")


if __name__ == "__main__":
    assessment = HMISecurityAssessment(hmi_info={
        "name": "Plant-HMI-01",
        "vendor": "Siemens WinCC",
        "version": "7.5 SP2",
        "ip": "10.10.2.10",
        "url": "https://10.10.2.10:8080",
        "os": "Windows 10 LTSC 2021",
    })
    assessment.generate_report()

主要な概念

用語定義
HMIオペレーターに産業プロセスの視覚的表示と制御を提供するヒューマンマシンインターフェース
Web HMIHTTP/HTTPS でアクセスできるブラウザベースの HMI インターフェースで、一般的な Web 脆弱性の影響を受ける
セットポイントオペレーターが HMI を通じて変更できるプロセス変数の目標値。不正な変更はプロセスの乱れを引き起こす可能性がある
アラーム抑制悪意のあるプロセス操作を隠蔽するために HMI のアラームを無効化または非表示にする攻撃者の手法
WinCC製造業およびプロセス産業で広く導入されている Siemens 製 SCADA/HMI ソフトウェア
CVE-2025-0921悪意のあるプロジェクトのアップロードを通じて悪用可能な Ignition SCADA の特権ファイルシステムの脆弱性

出力形式

HMI SECURITY ASSESSMENT REPORT
=================================
Date: YYYY-MM-DD
HMI: [name] | Vendor: [vendor] | Version: [version]

FINDINGS BY CATEGORY:
  Authentication: [pass/fail count]
  Communication: [pass/fail count]
  Web Security: [pass/fail count]
  Hardening: [pass/fail count]

CRITICAL FINDINGS:
  1. [finding with remediation]

COMPLIANCE STATUS:
  IEC 62443 SL-T: [target level]
  IEC 62443 SL-A: [achieved level]

コメント