[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6GZFWCXXYYY5NJXV3WBZSW6":3,"skill-same:01M6GZFWCXXYYY5NJXV3WBZSW6":88},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":17,"publishedAt":38,"linkOnly":39,"markdownContent":40,"markdownBody":41,"frontMatter":42,"refName":50,"commitSha":51,"skillDirectory":52,"forksCount":53,"repositoryHtmlUrl":54,"repositoryHomepageUrl":6,"ownerHtmlUrl":55,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":56,"install":57,"resources":70},"01M6GZFWCXXYYY5NJXV3WBZSW6","performing-s7comm-protocol-security-analysis",null,"Perform security analysis of Siemens S7comm and S7CommPlus protocols used by SIMATIC S7 PLCs to identify vulnerabilities including replay attacks, integrity bypass, unauthorized CPU stop commands, and program download manipulation exploiting weaknesses in S7-300, S7-400, S7-1200, and S7-1500 controllers.","micsapp\u002Fmicstec-skills","micsapp","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F82411001?v=4","01M6GWCFQ6D3PV8EHNY62NN5VW","01M6GWCFVE1PA5HG0DKC7AMFJ3",4,"Apache-2.0","https:\u002F\u002Fgithub.com\u002Fmicsapp\u002Fmicstec-skills\u002Fblob\u002Fmaster\u002F_universal\u002Fcybersecurity-skills\u002Fskills\u002Fperforming-s7comm-protocol-security-analysis\u002FSKILL.md",[],[18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"performing","security analysis","protocol","performing s7comm protocol security analysis","s7comm","security","analysis","scada","attacks","CPU","replay","siemens","vulnerability","ics","ot-security","protocol-analysis","s7","protocols","assessment","cybersecurity","2026-11-10 10:12:30",false,"---\nname: performing-s7comm-protocol-security-analysis\ndescription: >\n  Perform security analysis of Siemens S7comm and S7CommPlus protocols used by\n  SIMATIC S7 PLCs to identify vulnerabilities including replay attacks, integrity\n  bypass, unauthorized CPU stop commands, and program download manipulation\n  exploiting weaknesses in S7-300, S7-400, S7-1200, and S7-1500 controllers.\ndomain: cybersecurity\nsubdomain: ot-ics-security\ntags: [ot-security, ics, s7comm, siemens, plc-security, protocol-analysis, scada, vulnerability-assessment]\nversion: \"1.0\"\nauthor: mahipal\nlicense: Apache-2.0\n---\n\n# Performing S7comm Protocol Security Analysis\n\n## When to Use\n\n- When assessing the security posture of Siemens SIMATIC S7 PLC environments\n- When building detection rules for S7comm-based attacks against S7-300\u002F400\u002F1200\u002F1500 controllers\n- When performing a security audit of Siemens Step 7\u002FTIA Portal communications\n- When investigating suspected unauthorized access to Siemens PLC programs\n- When evaluating S7CommPlus integrity mechanisms and their bypass potential\n\n**Do not use** for scanning production Siemens PLCs without authorization and a test plan (this can crash controllers), for non-Siemens protocol analysis (see detecting-modbus-command-injection-attacks for Modbus), or for modifying PLC programs in a production environment.\n\n## Prerequisites\n\n- Network access to the S7comm communication segment (TCP port 102)\n- Wireshark with S7comm dissector or Zeek with S7comm protocol analyzer\n- Authorized access for security testing (never scan production PLCs without authorization)\n- Knowledge of the Siemens PLC models and firmware versions in scope\n- Understanding of S7comm protocol structure (COTP, S7 PDU, function codes)\n\n## Workflow\n\n### Step 1: Analyze S7comm Traffic and Identify Vulnerabilities\n\n```python\n#!\u002Fusr\u002Fbin\u002Fenv python3\n\"\"\"S7comm Protocol Security Analyzer.\n\nAnalyzes Siemens S7comm protocol traffic to identify security\nvulnerabilities, unauthorized access patterns, and potential\nattack indicators against SIMATIC S7 PLCs.\n\"\"\"\n\nimport struct\nimport sys\nimport json\nfrom collections import defaultdict\nfrom datetime import datetime\nfrom typing import Dict, List, Optional\n\ntry:\n    from scapy.all import rdpcap, IP, TCP\nexcept ImportError:\n    print(\"Install scapy: pip install scapy\")\n    sys.exit(1)\n\n\n# S7comm ROSCTR (PDU type) definitions\nS7_ROSCTR = {\n    0x01: \"Job (Request)\",\n    0x02: \"Ack\",\n    0x03: \"Ack_Data (Response)\",\n    0x07: \"Userdata\",\n}\n\n# S7comm function codes\nS7_FUNCTIONS = {\n    0x00: \"CPU services\",\n    0x04: \"Read Variable\",\n    0x05: \"Write Variable\",\n    0x1A: \"Request Download (Program)\",\n    0x1B: \"Download Block\",\n    0x1C: \"Download Ended\",\n    0x1D: \"Start Upload (Read Program)\",\n    0x1E: \"Upload Block\",\n    0x1F: \"Upload Ended\",\n    0x28: \"PI Service (Start\u002FStop CPU)\",\n    0x29: \"PLC Stop\",\n    0xF0: \"Setup Communication\",\n}\n\n# Critical security-relevant operations\nCRITICAL_FUNCTIONS = {0x1A, 0x1B, 0x1C, 0x28, 0x29, 0x05}\nPROGRAM_FUNCTIONS = {0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F}\n\n\nclass S7commSecurityFinding:\n    \"\"\"Represents a security finding in S7comm traffic.\"\"\"\n\n    def __init__(self, severity: str, finding_type: str, src_ip: str,\n                 dst_ip: str, function: str, description: str,\n                 cve: str = \"\", recommendation: str = \"\"):\n        self.timestamp = datetime.now().isoformat()\n        self.severity = severity\n        self.finding_type = finding_type\n        self.src_ip = src_ip\n        self.dst_ip = dst_ip\n        self.function = function\n        self.description = description\n        self.cve = cve\n        self.recommendation = recommendation\n\n\nclass S7commAnalyzer:\n    \"\"\"Analyzes S7comm protocol traffic for security vulnerabilities.\"\"\"\n\n    def __init__(self):\n        self.findings: List[S7commSecurityFinding] = []\n        self.sessions: Dict[str, dict] = defaultdict(lambda: {\n            \"packets\": 0,\n            \"functions_seen\": set(),\n            \"writes\": 0,\n            \"program_downloads\": 0,\n            \"cpu_commands\": 0,\n            \"first_seen\": None,\n            \"last_seen\": None,\n        })\n        self.authorized_engineering: set = set()\n        self.packet_count = 0\n\n    def set_authorized_stations(self, ips: List[str]):\n        \"\"\"Set list of authorized engineering workstation IPs.\"\"\"\n        self.authorized_engineering = set(ips)\n\n    def parse_s7comm(self, payload: bytes) -> Optional[dict]:\n        \"\"\"Parse S7comm protocol data from TCP payload.\"\"\"\n        # TPKT header: version(1) + reserved(1) + length(2)\n        if len(payload) \u003C 4:\n            return None\n\n        tpkt_version = payload[0]\n        if tpkt_version != 3:\n            return None\n\n        tpkt_length = struct.unpack(\">H\", payload[2:4])[0]\n\n        # COTP header follows TPKT\n        if len(payload) \u003C 7:\n            return None\n\n        cotp_length = payload[4]\n        cotp_type = payload[5]\n\n        # S7comm starts after COTP\n        s7_offset = 4 + 1 + cotp_length\n        if len(payload) \u003C s7_offset + 10:\n            return None\n\n        # S7comm header\n        protocol_id = payload[s7_offset]\n        if protocol_id != 0x32:  # S7comm magic byte\n            return None\n\n        rosctr = payload[s7_offset + 1]\n        redundancy = struct.unpack(\">H\", payload[s7_offset + 2:s7_offset + 4])[0]\n        pdu_ref = struct.unpack(\">H\", payload[s7_offset + 4:s7_offset + 6])[0]\n        param_length = struct.unpack(\">H\", payload[s7_offset + 6:s7_offset + 8])[0]\n        data_length = struct.unpack(\">H\", payload[s7_offset + 8:s7_offset + 10])[0]\n\n        result = {\n            \"rosctr\": rosctr,\n            \"rosctr_name\": S7_ROSCTR.get(rosctr, f\"Unknown (0x{rosctr:02x})\"),\n            \"pdu_ref\": pdu_ref,\n            \"param_length\": param_length,\n            \"data_length\": data_length,\n        }\n\n        # Parse function code from parameters\n        param_offset = s7_offset + 10\n        if rosctr in (0x01, 0x03) and param_length > 0 and len(payload) > param_offset:\n            func_code = payload[param_offset]\n            result[\"function_code\"] = func_code\n            result[\"function_name\"] = S7_FUNCTIONS.get(func_code, f\"Unknown (0x{func_code:02x})\")\n\n        return result\n\n    def analyze_packet(self, pkt):\n        \"\"\"Analyze a packet for S7comm security issues.\"\"\"\n        self.packet_count += 1\n\n        if not pkt.haslayer(IP) or not pkt.haslayer(TCP):\n            return\n\n        tcp = pkt[TCP]\n        if tcp.dport != 102 and tcp.sport != 102:\n            return\n\n        payload = bytes(tcp.payload)\n        if not payload:\n            return\n\n        s7 = self.parse_s7comm(payload)\n        if not s7:\n            return\n\n        src_ip = pkt[IP].src\n        dst_ip = pkt[IP].dst\n        session_key = f\"{src_ip}->{dst_ip}\"\n        session = self.sessions[session_key]\n        session[\"packets\"] += 1\n\n        if session[\"first_seen\"] is None:\n            session[\"first_seen\"] = float(pkt.time)\n        session[\"last_seen\"] = float(pkt.time)\n\n        func_code = s7.get(\"function_code\")\n        if func_code is not None:\n            session[\"functions_seen\"].add(func_code)\n\n            # Check 1: Unauthorized engineering station\n            if tcp.dport == 102 and func_code in CRITICAL_FUNCTIONS:\n                if self.authorized_engineering and src_ip not in self.authorized_engineering:\n                    self.findings.append(S7commSecurityFinding(\n                        severity=\"CRITICAL\",\n                        finding_type=\"UNAUTHORIZED_ENGINEERING_ACCESS\",\n                        src_ip=src_ip, dst_ip=dst_ip,\n                        function=s7.get(\"function_name\", \"Unknown\"),\n                        description=(\n                            f\"Critical S7comm operation from unauthorized source {src_ip}. \"\n                            f\"Function: {s7.get('function_name')}. Only authorized TIA Portal \"\n                            f\"workstations should issue these commands.\"\n                        ),\n                        recommendation=\"Block unauthorized sources at industrial firewall. Investigate source host for compromise.\",\n                    ))\n\n            # Check 2: CPU Stop command\n            if func_code == 0x29:\n                session[\"cpu_commands\"] += 1\n                self.findings.append(S7commSecurityFinding(\n                    severity=\"CRITICAL\",\n                    finding_type=\"CPU_STOP_COMMAND\",\n                    src_ip=src_ip, dst_ip=dst_ip,\n                    function=\"PLC CPU Stop (0x29)\",\n                    description=f\"CPU STOP command sent to PLC at {dst_ip}. This halts PLC program execution.\",\n                    cve=\"MITRE T0881 - Service Stop\",\n                    recommendation=\"Verify if this is an authorized maintenance action. If not, isolate source immediately.\",\n                ))\n\n            # Check 3: Program download\n            if func_code in (0x1A, 0x1B, 0x1C):\n                session[\"program_downloads\"] += 1\n                self.findings.append(S7commSecurityFinding(\n                    severity=\"CRITICAL\",\n                    finding_type=\"PROGRAM_DOWNLOAD\",\n                    src_ip=src_ip, dst_ip=dst_ip,\n                    function=s7.get(\"function_name\", \"Download\"),\n                    description=(\n                        f\"PLC program download operation to {dst_ip}. \"\n                        f\"This modifies the running control logic on the PLC.\"\n                    ),\n                    cve=\"MITRE T0843 - Program Download\",\n                    recommendation=\"Verify against change management records. Compare with known-good program backup.\",\n                ))\n\n            # Check 4: Write variable operation\n            if func_code == 0x05:\n                session[\"writes\"] += 1\n\n            # Check 5: Program upload (exfiltration of PLC code)\n            if func_code in (0x1D, 0x1E, 0x1F):\n                self.findings.append(S7commSecurityFinding(\n                    severity=\"HIGH\",\n                    finding_type=\"PROGRAM_UPLOAD_EXFILTRATION\",\n                    src_ip=src_ip, dst_ip=dst_ip,\n                    function=s7.get(\"function_name\", \"Upload\"),\n                    description=f\"PLC program upload (read) from {dst_ip}. Source {src_ip} is extracting PLC control logic.\",\n                    recommendation=\"Verify if this is authorized maintenance. Unauthorized uploads indicate reconnaissance.\",\n                ))\n\n    def check_known_vulnerabilities(self):\n        \"\"\"Check for known Siemens S7 vulnerabilities based on observed behavior.\"\"\"\n        vuln_checks = [\n            {\n                \"name\": \"S7-300\u002F400 Replay Attack Vulnerability\",\n                \"cve\": \"CVE-2019-13945\",\n                \"description\": \"S7-300\u002F400 PLCs lack integrity checks on S7comm sessions, allowing replay attacks\",\n                \"affected\": \"S7-300, S7-400 (all firmware versions)\",\n                \"severity\": \"HIGH\",\n            },\n            {\n                \"name\": \"S7CommPlus Integrity Bypass\",\n                \"cve\": \"Research finding (Biham et al.)\",\n                \"description\": \"S7CommPlusV3 integrity mechanism can be bypassed by attackers who can observe one legitimate session\",\n                \"affected\": \"S7-1200 (\u003C V4.5), S7-1500 (\u003C V2.9)\",\n                \"severity\": \"HIGH\",\n            },\n            {\n                \"name\": \"Unpatchable Hardware Root of Trust\",\n                \"cve\": \"CVE-2022-38773\",\n                \"description\": \"Hardware vulnerability allows bypassing protected boot and persistent firmware modification\",\n                \"affected\": \"S7-1500 (specific hardware revisions)\",\n                \"severity\": \"CRITICAL\",\n            },\n            {\n                \"name\": \"Remote DoS via Port 102\",\n                \"cve\": \"CVE-2019-10929\",\n                \"description\": \"Specially crafted packets on TCP port 102 can crash S7 PLCs remotely\",\n                \"affected\": \"S7-300, S7-400, S7-1200, S7-1500 (specific firmware)\",\n                \"severity\": \"HIGH\",\n            },\n        ]\n        return vuln_checks\n\n    def generate_report(self):\n        \"\"\"Generate comprehensive S7comm security analysis report.\"\"\"\n        print(f\"\\n{'='*70}\")\n        print(\"S7COMM PROTOCOL SECURITY ANALYSIS REPORT\")\n        print(f\"{'='*70}\")\n        print(f\"Analysis Time: {datetime.now().isoformat()}\")\n        print(f\"Packets Analyzed: {self.packet_count}\")\n        print(f\"S7comm Sessions: {len(self.sessions)}\")\n        print(f\"Security Findings: {len(self.findings)}\")\n\n        print(f\"\\n--- SESSION SUMMARY ---\")\n        for key, session in self.sessions.items():\n            funcs = [S7_FUNCTIONS.get(f, f\"0x{f:02x}\") for f in session[\"functions_seen\"]]\n            print(f\"\\n  {key}\")\n            print(f\"    Packets: {session['packets']}\")\n            print(f\"    Functions: {', '.join(funcs)}\")\n            print(f\"    Writes: {session['writes']}\")\n            print(f\"    Program Downloads: {session['program_downloads']}\")\n            print(f\"    CPU Commands: {session['cpu_commands']}\")\n\n        if self.findings:\n            print(f\"\\n--- SECURITY FINDINGS ---\")\n            for f in self.findings:\n                print(f\"\\n  [{f.severity}] {f.finding_type}\")\n                print(f\"    Source: {f.src_ip} -> {f.dst_ip}\")\n                print(f\"    Function: {f.function}\")\n                print(f\"    Detail: {f.description}\")\n                if f.cve:\n                    print(f\"    Reference: {f.cve}\")\n                if f.recommendation:\n                    print(f\"    Action: {f.recommendation}\")\n\n        print(f\"\\n--- KNOWN VULNERABILITY ASSESSMENT ---\")\n        for vuln in self.check_known_vulnerabilities():\n            print(f\"\\n  [{vuln['severity']}] {vuln['name']}\")\n            print(f\"    CVE: {vuln['cve']}\")\n            print(f\"    Affected: {vuln['affected']}\")\n            print(f\"    Detail: {vuln['description']}\")\n\n\nif __name__ == \"__main__\":\n    analyzer = S7commAnalyzer()\n    analyzer.set_authorized_stations([\"10.10.2.50\", \"10.10.2.51\"])\n\n    if len(sys.argv) >= 2:\n        print(f\"[*] Analyzing capture: {sys.argv[1]}\")\n        packets = rdpcap(sys.argv[1])\n        for pkt in packets:\n            analyzer.analyze_packet(pkt)\n        analyzer.generate_report()\n    else:\n        print(\"Usage: python s7comm_analyzer.py \u003Ccapture.pcap>\")\n        print(\"  Analyzes S7comm traffic for security vulnerabilities\")\n```\n\n## Key Concepts\n\n| Term | Definition |\n|------|------------|\n| S7comm | Siemens proprietary protocol for communication with SIMATIC S7 PLCs over TCP port 102, layered on COTP\u002FTPKT |\n| S7CommPlus | Enhanced version of S7comm used by S7-1200\u002F1500 with integrity protection mechanisms |\n| ROSCTR | Remote Operating Service Control field in S7comm header indicating PDU type (Job, Ack, Ack_Data, Userdata) |\n| TIA Portal | Totally Integrated Automation Portal -- Siemens engineering software for programming S7 PLCs |\n| CPU Stop (0x29) | S7comm function that halts PLC program execution, a critical denial-of-service operation |\n| Program Download (0x1A) | S7comm function initiating transfer of new control logic to a PLC, representing the highest risk operation |\n\n## Common Scenarios\n\n### Scenario: Unauthorized PLC Program Modification\n\n**Context**: A Dragos sensor alerts on S7comm program download traffic from an IP address that is not the authorized TIA Portal engineering workstation.\n\n**Approach**:\n1. Capture the complete S7comm session for forensic analysis\n2. Identify the source host and determine if it is compromised or rogue\n3. Compare the current PLC program against the last known-good backup\n4. Check if the PLC CPU mode was changed (RUN to STOP to PROGRAM)\n5. If the program was modified, restore from verified backup\n6. Investigate the attack chain -- how did the attacker reach the S7comm network segment\n7. Implement S7comm access protection (know-how protection, access passwords) on all PLCs\n\n**Pitfalls**: S7-300\u002F400 PLCs have no cryptographic integrity protection -- any device that can reach TCP port 102 can send commands. Do not rely solely on PLC passwords as they are transmitted in cleartext in S7comm (not S7CommPlus). Network segmentation is the primary defense.\n\n## Output Format\n\n```\nS7COMM SECURITY ANALYSIS REPORT\n===================================\nDate: YYYY-MM-DD\nScope: [Network segments analyzed]\n\nSESSION INVENTORY:\n  Engineering stations: [count and IPs]\n  PLCs communicating: [count and IPs]\n  Unauthorized sources: [count]\n\nCRITICAL FINDINGS:\n  CPU Stop commands: [count]\n  Program downloads: [count from unauthorized sources]\n  Replay attack potential: [assessment]\n\nVULNERABILITY ASSESSMENT:\n  S7-300\u002F400 (no integrity): [count of affected PLCs]\n  S7-1200\u002F1500 (S7CommPlus): [firmware assessment]\n  Known CVEs applicable: [list]\n\nRECOMMENDATIONS:\n  1. [Highest priority remediation]\n  2. [Network segmentation improvement]\n  3. [Monitoring enhancement]\n```\n","# Performing S7comm Protocol Security Analysis\n\n## When to Use\n\n- When assessing the security posture of Siemens SIMATIC S7 PLC environments\n- When building detection rules for S7comm-based attacks against S7-300\u002F400\u002F1200\u002F1500 controllers\n- When performing a security audit of Siemens Step 7\u002FTIA Portal communications\n- When investigating suspected unauthorized access to Siemens PLC programs\n- When evaluating S7CommPlus integrity mechanisms and their bypass potential\n\n**Do not use** for scanning production Siemens PLCs without authorization and a test plan (this can crash controllers), for non-Siemens protocol analysis (see detecting-modbus-command-injection-attacks for Modbus), or for modifying PLC programs in a production environment.\n\n## Prerequisites\n\n- Network access to the S7comm communication segment (TCP port 102)\n- Wireshark with S7comm dissector or Zeek with S7comm protocol analyzer\n- Authorized access for security testing (never scan production PLCs without authorization)\n- Knowledge of the Siemens PLC models and firmware versions in scope\n- Understanding of S7comm protocol structure (COTP, S7 PDU, function codes)\n\n## Workflow\n\n### Step 1: Analyze S7comm Traffic and Identify Vulnerabilities\n\n```python\n#!\u002Fusr\u002Fbin\u002Fenv python3\n\"\"\"S7comm Protocol Security Analyzer.\n\nAnalyzes Siemens S7comm protocol traffic to identify security\nvulnerabilities, unauthorized access patterns, and potential\nattack indicators against SIMATIC S7 PLCs.\n\"\"\"\n\nimport struct\nimport sys\nimport json\nfrom collections import defaultdict\nfrom datetime import datetime\nfrom typing import Dict, List, Optional\n\ntry:\n    from scapy.all import rdpcap, IP, TCP\nexcept ImportError:\n    print(\"Install scapy: pip install scapy\")\n    sys.exit(1)\n\n\n# S7comm ROSCTR (PDU type) definitions\nS7_ROSCTR = {\n    0x01: \"Job (Request)\",\n    0x02: \"Ack\",\n    0x03: \"Ack_Data (Response)\",\n    0x07: \"Userdata\",\n}\n\n# S7comm function codes\nS7_FUNCTIONS = {\n    0x00: \"CPU services\",\n    0x04: \"Read Variable\",\n    0x05: \"Write Variable\",\n    0x1A: \"Request Download (Program)\",\n    0x1B: \"Download Block\",\n    0x1C: \"Download Ended\",\n    0x1D: \"Start Upload (Read Program)\",\n    0x1E: \"Upload Block\",\n    0x1F: \"Upload Ended\",\n    0x28: \"PI Service (Start\u002FStop CPU)\",\n    0x29: \"PLC Stop\",\n    0xF0: \"Setup Communication\",\n}\n\n# Critical security-relevant operations\nCRITICAL_FUNCTIONS = {0x1A, 0x1B, 0x1C, 0x28, 0x29, 0x05}\nPROGRAM_FUNCTIONS = {0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F}\n\n\nclass S7commSecurityFinding:\n    \"\"\"Represents a security finding in S7comm traffic.\"\"\"\n\n    def __init__(self, severity: str, finding_type: str, src_ip: str,\n                 dst_ip: str, function: str, description: str,\n                 cve: str = \"\", recommendation: str = \"\"):\n        self.timestamp = datetime.now().isoformat()\n        self.severity = severity\n        self.finding_type = finding_type\n        self.src_ip = src_ip\n        self.dst_ip = dst_ip\n        self.function = function\n        self.description = description\n        self.cve = cve\n        self.recommendation = recommendation\n\n\nclass S7commAnalyzer:\n    \"\"\"Analyzes S7comm protocol traffic for security vulnerabilities.\"\"\"\n\n    def __init__(self):\n        self.findings: List[S7commSecurityFinding] = []\n        self.sessions: Dict[str, dict] = defaultdict(lambda: {\n            \"packets\": 0,\n            \"functions_seen\": set(),\n            \"writes\": 0,\n            \"program_downloads\": 0,\n            \"cpu_commands\": 0,\n            \"first_seen\": None,\n            \"last_seen\": None,\n        })\n        self.authorized_engineering: set = set()\n        self.packet_count = 0\n\n    def set_authorized_stations(self, ips: List[str]):\n        \"\"\"Set list of authorized engineering workstation IPs.\"\"\"\n        self.authorized_engineering = set(ips)\n\n    def parse_s7comm(self, payload: bytes) -> Optional[dict]:\n        \"\"\"Parse S7comm protocol data from TCP payload.\"\"\"\n        # TPKT header: version(1) + reserved(1) + length(2)\n        if len(payload) \u003C 4:\n            return None\n\n        tpkt_version = payload[0]\n        if tpkt_version != 3:\n            return None\n\n        tpkt_length = struct.unpack(\">H\", payload[2:4])[0]\n\n        # COTP header follows TPKT\n        if len(payload) \u003C 7:\n            return None\n\n        cotp_length = payload[4]\n        cotp_type = payload[5]\n\n        # S7comm starts after COTP\n        s7_offset = 4 + 1 + cotp_length\n        if len(payload) \u003C s7_offset + 10:\n            return None\n\n        # S7comm header\n        protocol_id = payload[s7_offset]\n        if protocol_id != 0x32:  # S7comm magic byte\n            return None\n\n        rosctr = payload[s7_offset + 1]\n        redundancy = struct.unpack(\">H\", payload[s7_offset + 2:s7_offset + 4])[0]\n        pdu_ref = struct.unpack(\">H\", payload[s7_offset + 4:s7_offset + 6])[0]\n        param_length = struct.unpack(\">H\", payload[s7_offset + 6:s7_offset + 8])[0]\n        data_length = struct.unpack(\">H\", payload[s7_offset + 8:s7_offset + 10])[0]\n\n        result = {\n            \"rosctr\": rosctr,\n            \"rosctr_name\": S7_ROSCTR.get(rosctr, f\"Unknown (0x{rosctr:02x})\"),\n            \"pdu_ref\": pdu_ref,\n            \"param_length\": param_length,\n            \"data_length\": data_length,\n        }\n\n        # Parse function code from parameters\n        param_offset = s7_offset + 10\n        if rosctr in (0x01, 0x03) and param_length > 0 and len(payload) > param_offset:\n            func_code = payload[param_offset]\n            result[\"function_code\"] = func_code\n            result[\"function_name\"] = S7_FUNCTIONS.get(func_code, f\"Unknown (0x{func_code:02x})\")\n\n        return result\n\n    def analyze_packet(self, pkt):\n        \"\"\"Analyze a packet for S7comm security issues.\"\"\"\n        self.packet_count += 1\n\n        if not pkt.haslayer(IP) or not pkt.haslayer(TCP):\n            return\n\n        tcp = pkt[TCP]\n        if tcp.dport != 102 and tcp.sport != 102:\n            return\n\n        payload = bytes(tcp.payload)\n        if not payload:\n            return\n\n        s7 = self.parse_s7comm(payload)\n        if not s7:\n            return\n\n        src_ip = pkt[IP].src\n        dst_ip = pkt[IP].dst\n        session_key = f\"{src_ip}->{dst_ip}\"\n        session = self.sessions[session_key]\n        session[\"packets\"] += 1\n\n        if session[\"first_seen\"] is None:\n            session[\"first_seen\"] = float(pkt.time)\n        session[\"last_seen\"] = float(pkt.time)\n\n        func_code = s7.get(\"function_code\")\n        if func_code is not None:\n            session[\"functions_seen\"].add(func_code)\n\n            # Check 1: Unauthorized engineering station\n            if tcp.dport == 102 and func_code in CRITICAL_FUNCTIONS:\n                if self.authorized_engineering and src_ip not in self.authorized_engineering:\n                    self.findings.append(S7commSecurityFinding(\n                        severity=\"CRITICAL\",\n                        finding_type=\"UNAUTHORIZED_ENGINEERING_ACCESS\",\n                        src_ip=src_ip, dst_ip=dst_ip,\n                        function=s7.get(\"function_name\", \"Unknown\"),\n                        description=(\n                            f\"Critical S7comm operation from unauthorized source {src_ip}. \"\n                            f\"Function: {s7.get('function_name')}. Only authorized TIA Portal \"\n                            f\"workstations should issue these commands.\"\n                        ),\n                        recommendation=\"Block unauthorized sources at industrial firewall. Investigate source host for compromise.\",\n                    ))\n\n            # Check 2: CPU Stop command\n            if func_code == 0x29:\n                session[\"cpu_commands\"] += 1\n                self.findings.append(S7commSecurityFinding(\n                    severity=\"CRITICAL\",\n                    finding_type=\"CPU_STOP_COMMAND\",\n                    src_ip=src_ip, dst_ip=dst_ip,\n                    function=\"PLC CPU Stop (0x29)\",\n                    description=f\"CPU STOP command sent to PLC at {dst_ip}. This halts PLC program execution.\",\n                    cve=\"MITRE T0881 - Service Stop\",\n                    recommendation=\"Verify if this is an authorized maintenance action. If not, isolate source immediately.\",\n                ))\n\n            # Check 3: Program download\n            if func_code in (0x1A, 0x1B, 0x1C):\n                session[\"program_downloads\"] += 1\n                self.findings.append(S7commSecurityFinding(\n                    severity=\"CRITICAL\",\n                    finding_type=\"PROGRAM_DOWNLOAD\",\n                    src_ip=src_ip, dst_ip=dst_ip,\n                    function=s7.get(\"function_name\", \"Download\"),\n                    description=(\n                        f\"PLC program download operation to {dst_ip}. \"\n                        f\"This modifies the running control logic on the PLC.\"\n                    ),\n                    cve=\"MITRE T0843 - Program Download\",\n                    recommendation=\"Verify against change management records. Compare with known-good program backup.\",\n                ))\n\n            # Check 4: Write variable operation\n            if func_code == 0x05:\n                session[\"writes\"] += 1\n\n            # Check 5: Program upload (exfiltration of PLC code)\n            if func_code in (0x1D, 0x1E, 0x1F):\n                self.findings.append(S7commSecurityFinding(\n                    severity=\"HIGH\",\n                    finding_type=\"PROGRAM_UPLOAD_EXFILTRATION\",\n                    src_ip=src_ip, dst_ip=dst_ip,\n                    function=s7.get(\"function_name\", \"Upload\"),\n                    description=f\"PLC program upload (read) from {dst_ip}. Source {src_ip} is extracting PLC control logic.\",\n                    recommendation=\"Verify if this is authorized maintenance. Unauthorized uploads indicate reconnaissance.\",\n                ))\n\n    def check_known_vulnerabilities(self):\n        \"\"\"Check for known Siemens S7 vulnerabilities based on observed behavior.\"\"\"\n        vuln_checks = [\n            {\n                \"name\": \"S7-300\u002F400 Replay Attack Vulnerability\",\n                \"cve\": \"CVE-2019-13945\",\n                \"description\": \"S7-300\u002F400 PLCs lack integrity checks on S7comm sessions, allowing replay attacks\",\n                \"affected\": \"S7-300, S7-400 (all firmware versions)\",\n                \"severity\": \"HIGH\",\n            },\n            {\n                \"name\": \"S7CommPlus Integrity Bypass\",\n                \"cve\": \"Research finding (Biham et al.)\",\n                \"description\": \"S7CommPlusV3 integrity mechanism can be bypassed by attackers who can observe one legitimate session\",\n                \"affected\": \"S7-1200 (\u003C V4.5), S7-1500 (\u003C V2.9)\",\n                \"severity\": \"HIGH\",\n            },\n            {\n                \"name\": \"Unpatchable Hardware Root of Trust\",\n                \"cve\": \"CVE-2022-38773\",\n                \"description\": \"Hardware vulnerability allows bypassing protected boot and persistent firmware modification\",\n                \"affected\": \"S7-1500 (specific hardware revisions)\",\n                \"severity\": \"CRITICAL\",\n            },\n            {\n                \"name\": \"Remote DoS via Port 102\",\n                \"cve\": \"CVE-2019-10929\",\n                \"description\": \"Specially crafted packets on TCP port 102 can crash S7 PLCs remotely\",\n                \"affected\": \"S7-300, S7-400, S7-1200, S7-1500 (specific firmware)\",\n                \"severity\": \"HIGH\",\n            },\n        ]\n        return vuln_checks\n\n    def generate_report(self):\n        \"\"\"Generate comprehensive S7comm security analysis report.\"\"\"\n        print(f\"\\n{'='*70}\")\n        print(\"S7COMM PROTOCOL SECURITY ANALYSIS REPORT\")\n        print(f\"{'='*70}\")\n        print(f\"Analysis Time: {datetime.now().isoformat()}\")\n        print(f\"Packets Analyzed: {self.packet_count}\")\n        print(f\"S7comm Sessions: {len(self.sessions)}\")\n        print(f\"Security Findings: {len(self.findings)}\")\n\n        print(f\"\\n--- SESSION SUMMARY ---\")\n        for key, session in self.sessions.items():\n            funcs = [S7_FUNCTIONS.get(f, f\"0x{f:02x}\") for f in session[\"functions_seen\"]]\n            print(f\"\\n  {key}\")\n            print(f\"    Packets: {session['packets']}\")\n            print(f\"    Functions: {', '.join(funcs)}\")\n            print(f\"    Writes: {session['writes']}\")\n            print(f\"    Program Downloads: {session['program_downloads']}\")\n            print(f\"    CPU Commands: {session['cpu_commands']}\")\n\n        if self.findings:\n            print(f\"\\n--- SECURITY FINDINGS ---\")\n            for f in self.findings:\n                print(f\"\\n  [{f.severity}] {f.finding_type}\")\n                print(f\"    Source: {f.src_ip} -> {f.dst_ip}\")\n                print(f\"    Function: {f.function}\")\n                print(f\"    Detail: {f.description}\")\n                if f.cve:\n                    print(f\"    Reference: {f.cve}\")\n                if f.recommendation:\n                    print(f\"    Action: {f.recommendation}\")\n\n        print(f\"\\n--- KNOWN VULNERABILITY ASSESSMENT ---\")\n        for vuln in self.check_known_vulnerabilities():\n            print(f\"\\n  [{vuln['severity']}] {vuln['name']}\")\n            print(f\"    CVE: {vuln['cve']}\")\n            print(f\"    Affected: {vuln['affected']}\")\n            print(f\"    Detail: {vuln['description']}\")\n\n\nif __name__ == \"__main__\":\n    analyzer = S7commAnalyzer()\n    analyzer.set_authorized_stations([\"10.10.2.50\", \"10.10.2.51\"])\n\n    if len(sys.argv) >= 2:\n        print(f\"[*] Analyzing capture: {sys.argv[1]}\")\n        packets = rdpcap(sys.argv[1])\n        for pkt in packets:\n            analyzer.analyze_packet(pkt)\n        analyzer.generate_report()\n    else:\n        print(\"Usage: python s7comm_analyzer.py \u003Ccapture.pcap>\")\n        print(\"  Analyzes S7comm traffic for security vulnerabilities\")\n```\n\n## Key Concepts\n\n| Term | Definition |\n|------|------------|\n| S7comm | Siemens proprietary protocol for communication with SIMATIC S7 PLCs over TCP port 102, layered on COTP\u002FTPKT |\n| S7CommPlus | Enhanced version of S7comm used by S7-1200\u002F1500 with integrity protection mechanisms |\n| ROSCTR | Remote Operating Service Control field in S7comm header indicating PDU type (Job, Ack, Ack_Data, Userdata) |\n| TIA Portal | Totally Integrated Automation Portal -- Siemens engineering software for programming S7 PLCs |\n| CPU Stop (0x29) | S7comm function that halts PLC program execution, a critical denial-of-service operation |\n| Program Download (0x1A) | S7comm function initiating transfer of new control logic to a PLC, representing the highest risk operation |\n\n## Common Scenarios\n\n### Scenario: Unauthorized PLC Program Modification\n\n**Context**: A Dragos sensor alerts on S7comm program download traffic from an IP address that is not the authorized TIA Portal engineering workstation.\n\n**Approach**:\n1. Capture the complete S7comm session for forensic analysis\n2. Identify the source host and determine if it is compromised or rogue\n3. Compare the current PLC program against the last known-good backup\n4. Check if the PLC CPU mode was changed (RUN to STOP to PROGRAM)\n5. If the program was modified, restore from verified backup\n6. Investigate the attack chain -- how did the attacker reach the S7comm network segment\n7. Implement S7comm access protection (know-how protection, access passwords) on all PLCs\n\n**Pitfalls**: S7-300\u002F400 PLCs have no cryptographic integrity protection -- any device that can reach TCP port 102 can send commands. Do not rely solely on PLC passwords as they are transmitted in cleartext in S7comm (not S7CommPlus). Network segmentation is the primary defense.\n\n## Output Format\n\n```\nS7COMM SECURITY ANALYSIS REPORT\n===================================\nDate: YYYY-MM-DD\nScope: [Network segments analyzed]\n\nSESSION INVENTORY:\n  Engineering stations: [count and IPs]\n  PLCs communicating: [count and IPs]\n  Unauthorized sources: [count]\n\nCRITICAL FINDINGS:\n  CPU Stop commands: [count]\n  Program downloads: [count from unauthorized sources]\n  Replay attack potential: [assessment]\n\nVULNERABILITY ASSESSMENT:\n  S7-300\u002F400 (no integrity): [count of affected PLCs]\n  S7-1200\u002F1500 (S7CommPlus): [firmware assessment]\n  Known CVEs applicable: [list]\n\nRECOMMENDATIONS:\n  1. [Highest priority remediation]\n  2. [Network segmentation improvement]\n  3. [Monitoring enhancement]\n```\n",{"name":5,"tags":43,"author":46,"domain":37,"license":14,"version":47,"subdomain":48,"description":49},[32,31,22,29,44,33,25,45],"plc-security","vulnerability-assessment","mahipal","1.0","ot-ics-security","Perform security analysis of Siemens S7comm and S7CommPlus protocols used by SIMATIC S7 PLCs to identify vulnerabilities including replay attacks, integrity bypass, unauthorized CPU stop commands, and program download manipulation exploiting weaknesses in S7-300, S7-400, S7-1200, and S7-1500 controllers.\n","master","3f5d983eb4ef375b749adcd6b07ec03bd82ae8a8","_universal\u002Fcybersecurity-skills\u002Fskills\u002Fperforming-s7comm-protocol-security-analysis",0,"https:\u002F\u002Fgithub.com\u002Fmicsapp\u002Fmicstec-skills","https:\u002F\u002Fgithub.com\u002Fmicsapp","2026-03-20 11:24:18",{"source":8,"skillName":5,"commands":58,"prompt":68,"zipAvailable":69},[59,62,65],{"tool":60,"command":61},"npx","npx skills add micsapp\u002Fmicstec-skills --skill performing-s7comm-protocol-security-analysis",{"tool":63,"command":64},"bunx","bunx skills add micsapp\u002Fmicstec-skills --skill performing-s7comm-protocol-security-analysis",{"tool":66,"command":67},"pnpm","pnpm dlx skills add micsapp\u002Fmicstec-skills --skill performing-s7comm-protocol-security-analysis","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fmicsapp\u002Fmicstec-skills\u002Fblob\u002Fmaster\u002F_universal\u002Fcybersecurity-skills\u002Fskills\u002Fperforming-s7comm-protocol-security-analysis\u002FSKILL.md",true,[71,76,82],{"path":72,"resourceType":72,"resourceTypeDesc":73,"sizeBytes":74,"sourceHtmlUrl":75},"LICENSE","许可证",11255,"https:\u002F\u002Fgithub.com\u002Fmicsapp\u002Fmicstec-skills\u002Fblob\u002Fmaster\u002F_universal\u002Fcybersecurity-skills\u002Fskills\u002Fperforming-s7comm-protocol-security-analysis\u002FLICENSE",{"path":77,"resourceType":78,"resourceTypeDesc":79,"sizeBytes":80,"sourceHtmlUrl":81},"references\u002Fapi-reference.md","REFERENCE","参考文档",2406,"https:\u002F\u002Fgithub.com\u002Fmicsapp\u002Fmicstec-skills\u002Fblob\u002Fmaster\u002F_universal\u002Fcybersecurity-skills\u002Fskills\u002Fperforming-s7comm-protocol-security-analysis\u002Freferences\u002Fapi-reference.md",{"path":83,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":86,"sourceHtmlUrl":87},"scripts\u002Fagent.py","SCRIPT","脚本",6280,"https:\u002F\u002Fgithub.com\u002Fmicsapp\u002Fmicstec-skills\u002Fblob\u002Fmaster\u002F_universal\u002Fcybersecurity-skills\u002Fskills\u002Fperforming-s7comm-protocol-security-analysis\u002Fscripts\u002Fagent.py",[89,127,157,177,197,222],{"skillNo":90,"name":91,"nameZh":6,"description":92,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":93,"licenseFileUrl":6,"sourceHtmlUrl":94,"categories":95,"keywords":106,"publishedAt":38},"01M6HBTJ02FXBFG9NYEHHYAP52","azure-apim-architecture","Analyzes and explains Azure API Management architecture decisions for enterprise API marketplace implementations using VNet Internal mode, Front Door, hybrid authentication, and multi-environment strategies. Use when discussing APIM component selection, network topology, cost optimization, or comparing alternatives like workspaces vs instances, VNet Internal vs External mode, or Front Door vs Application Gateway.","MIT","https:\u002F\u002Fgithub.com\u002Fmicsapp\u002Fmicstec-skills\u002Fblob\u002Fmaster\u002Fcopilot-cli\u002Fcopilot-agent-skills\u002F.github\u002Fskills\u002Fazure-apim-architecture\u002FSKILL.md",[96,101],{"categoryNo":97,"categoryName":98,"taxonomyType":99,"taxonomyTypeDesc":100},"01JBSEEDCAT000000000000010","后端与接口","SCENARIO","使用场景",{"categoryNo":102,"categoryName":103,"taxonomyType":104,"taxonomyTypeDesc":105},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126],"architecture","azure","azure apim architecture","component","authentication","gateway","topology","Optimization","network","api","team","environment","multi-environment","workspaces","instances","selection","strategies","azure api management","mode","for",{"skillNo":128,"name":129,"nameZh":6,"description":130,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":93,"licenseFileUrl":6,"sourceHtmlUrl":131,"categories":132,"keywords":141,"publishedAt":38},"01M6HBT7J4H082JEEA670B3EQ9","apiops-deployment","Guides deployment of Azure API Management infrastructure using Infrastructure as Code (Bicep\u002FTerraform), CI\u002FCD pipelines (GitHub Actions\u002FAzure DevOps), and APIOps workflows. Use when deploying APIM, creating pipelines, or implementing dev→test→prod promotion strategies.","https:\u002F\u002Fgithub.com\u002Fmicsapp\u002Fmicstec-skills\u002Fblob\u002Fmaster\u002Fcopilot-cli\u002Fcopilot-agent-skills\u002F.github\u002Fskills\u002Fapiops-deployment\u002FSKILL.md",[133,134,137,140],{"categoryNo":97,"categoryName":98,"taxonomyType":99,"taxonomyTypeDesc":100},{"categoryNo":135,"categoryName":136,"taxonomyType":99,"taxonomyTypeDesc":100},"01JBSEEDCAT000000000000011","运维与部署",{"categoryNo":138,"categoryName":139,"taxonomyType":99,"taxonomyTypeDesc":100},"01JBSEEDCAT000000000000023","Skill与智能体开发",{"categoryNo":102,"categoryName":103,"taxonomyType":104,"taxonomyTypeDesc":105},[142,143,144,145,108,146,147,148,149,150,151,152,116,117,123,153,154,124,155,156],"deployment","apiops deployment","workflows","azure devops","infrastructure","code","infrastructure as code","actions","ci","github actions","github-actions","as","guides","CI\u002FCD","implementing",{"skillNo":158,"name":159,"nameZh":6,"description":160,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":93,"licenseFileUrl":6,"sourceHtmlUrl":161,"categories":162,"keywords":164,"publishedAt":38},"01M6HBT2HEA23THNE9E00GYQBE","apim-policy-authoring","Creates production-ready Azure API Management policy XML for authentication (OAuth 2.0, JWT validation, subscription keys), rate limiting, CORS configuration, error handling, and API transformations. Use when implementing API security, access control, or request\u002Fresponse processing logic.","https:\u002F\u002Fgithub.com\u002Fmicsapp\u002Fmicstec-skills\u002Fblob\u002Fmaster\u002Fcopilot-cli\u002Fcopilot-agent-skills\u002F.github\u002Fskills\u002Fapim-policy-authoring\u002FSKILL.md",[163],{"categoryNo":97,"categoryName":98,"taxonomyType":99,"taxonomyTypeDesc":100},[165,166,167,23,108,111,116,117,168,169,170,171,172,173,174,124,175,176,156,126],"policy","authoring","apim policy authoring","access","use","ready","api security","Access Control","error","processing","cors configuration","production-ready",{"skillNo":178,"name":179,"nameZh":6,"description":180,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":93,"licenseFileUrl":6,"sourceHtmlUrl":181,"categories":182,"keywords":185,"publishedAt":38},"01M6HBSY65SB29J9WE9KYD0K6T","api-security-review","Reviews Azure API Management configurations for security vulnerabilities, OWASP API Security Top 10 compliance, VNet Internal mode validation, Private Link verification, and Azure Security Benchmark alignment. Use when performing security audits, pre-deployment validation, or compliance reviews.","https:\u002F\u002Fgithub.com\u002Fmicsapp\u002Fmicstec-skills\u002Fblob\u002Fmaster\u002Fcopilot-cli\u002Fcopilot-agent-skills\u002F.github\u002Fskills\u002Fapi-security-review\u002FSKILL.md",[183,184],{"categoryNo":97,"categoryName":98,"taxonomyType":99,"taxonomyTypeDesc":100},{"categoryNo":102,"categoryName":103,"taxonomyType":104,"taxonomyTypeDesc":105},[186,23,187,116,171,188,108,142,189,190,191,192,117,193,124,194,195,196,125,126],"review","security review","api security review","benchmark","verification","owasp","owasp-api","alignment","azure security","reviews","top",{"skillNo":198,"name":199,"nameZh":6,"description":200,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":93,"licenseFileUrl":6,"sourceHtmlUrl":201,"categories":202,"keywords":203,"publishedAt":38},"01M6HBSRW4PDFE6K4F8JYPZQ05","jira-cli","Interact with Jira from the command line to create, list, view, edit, and transition issues, manage sprints and epics, and perform common Jira workflows. Use when the user asks about Jira tasks, tickets, issues, sprints, or needs to manage project work items.","https:\u002F\u002Fgithub.com\u002Fmicsapp\u002Fmicstec-skills\u002Fblob\u002Fmaster\u002Fcopilot-cli\u002Fawesome-copilot-agents\u002Fskills\u002Fjira-cli\u002FSKILL.md",[],[204,205,206,144,207,208,209,210,116,211,212,213,214,215,216,217,218,219,220,221],"cli","jira","jira cli","init","tasks","create","issues","common","work","command","edit","list","view","project","project work","token","line","sprints",{"skillNo":223,"name":224,"nameZh":6,"description":225,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":93,"licenseFileUrl":6,"sourceHtmlUrl":226,"categories":227,"keywords":228,"publishedAt":38},"01M6HBSNS3JHMW603G47TWE31H","calculator","Performs arbitrary-precision arithmetic calculations including addition, subtraction, multiplication, division, and exponents. Use when the user asks to calculate, compute, or evaluate math expressions, or when precise decimal arithmetic is needed to avoid floating-point errors.","https:\u002F\u002Fgithub.com\u002Fmicsapp\u002Fmicstec-skills\u002Fblob\u002Fmaster\u002Fcopilot-cli\u002Fawesome-copilot-agents\u002Fskills\u002Fcalculator\u002FSKILL.md",[],[224,229,230,231,232,233,234,169,235,236],"npm","js","calculate","node","math","user","compute","errors"]