[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6AFZJ23KBPF31J7BQMWV7K1":3,"skill-same:01M6AFZJ23KBPF31J7BQMWV7K1":119},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":23,"publishedAt":44,"linkOnly":45,"markdownContent":46,"markdownBody":47,"frontMatter":48,"refName":70,"commitSha":71,"skillDirectory":72,"forksCount":73,"repositoryHtmlUrl":74,"repositoryHomepageUrl":75,"ownerHtmlUrl":76,"ownerBlogUrl":77,"ownerDescription":78,"updatedAt":79,"install":80,"resources":93},"01M6AFZJ23KBPF31J7BQMWV7K1","performing-plc-firmware-security-analysis",null,"This skill covers analyzing Programmable Logic Controller (PLC) firmware for security vulnerabilities including hardcoded credentials, insecure update mechanisms, backdoor functions, memory corruption flaws, and undocumented debug interfaces. It addresses firmware extraction from common PLC platforms (Siemens S7, Allen-Bradley, Schneider Modicon), static analysis of firmware images, dynamic analysis in emulated environments, and comparison against known-good baselines to detect tampering.","mukul975\u002FAnthropic-Cybersecurity-Skills","mukul975","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F42860185?v=4","01M6ADEQR8T5M4EEG6C67BQCWF","Mahipal","01M6ADJPMYWG1E5GM1FWBE3128",35990,"Apache-2.0","https:\u002F\u002Fgithub.com\u002Fmukul975\u002FAnthropic-Cybersecurity-Skills\u002Fblob\u002Fmain\u002Fskills\u002Fperforming-plc-firmware-security-analysis\u002FSKILL.md",[18],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发","SCENARIO","使用场景",[24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43],"performing plc firmware security analysis","security analysis","analysis","firmware","security","controller","plc-security","firmware-analysis","credentials","ICS-security","t1059","t1078","t1003","analyzing","s7","update","pr","cybersecurity","memory","static analysis","2026-11-10 10:12:30",false,"---\nname: performing-plc-firmware-security-analysis\ndescription: 'This skill covers analyzing Programmable Logic Controller (PLC) firmware\n  for security vulnerabilities including hardcoded credentials, insecure update mechanisms,\n  backdoor functions, memory corruption flaws, and undocumented debug interfaces.\n  It addresses firmware extraction from common PLC platforms (Siemens S7, Allen-Bradley,\n  Schneider Modicon), static analysis of firmware images, dynamic analysis in emulated\n  environments, and comparison against known-good baselines to detect tampering.\n\n  '\ndomain: cybersecurity\nsubdomain: ot-ics-security\ntags:\n- ot-security\n- ics\n- scada\n- industrial-control\n- iec62443\n- firmware-analysis\n- plc-security\nversion: 1.0.0\nauthor: mahipal\nlicense: Apache-2.0\nnist_csf:\n- PR.IR-01\n- DE.CM-01\n- ID.AM-05\n- GV.OC-02\nmitre_attack:\n- T1078\n- T1190\n- T1059\n- T1003\n- T1110\n---\n\n# Performing PLC Firmware Security Analysis\n\n## When to Use\n\n- When assessing PLC security as part of an IEC 62443 component security evaluation (IEC 62443-4-2)\n- When validating firmware integrity after a suspected compromise or supply chain attack\n- When evaluating the security of a new PLC platform before deployment in critical infrastructure\n- When performing vulnerability research on industrial control system devices in an authorized lab\n- When responding to an incident where PLC logic or firmware tampering is suspected\n\n**Do not use** on live production PLCs without explicit authorization and safety controls in place. Firmware extraction and analysis should be performed on lab devices or offline backups. Never upload PLC firmware to public analysis services. See performing-ics-penetration-testing for authorized live testing procedures.\n\n## Prerequisites\n\n- Isolated lab environment with the target PLC hardware or an emulated environment\n- PLC programming software for the target platform (Siemens TIA Portal, Rockwell Studio 5000, Schneider EcoStruxure)\n- Firmware extraction tools (binwalk, firmware-mod-kit, JTAG\u002FSWD debugger)\n- Static analysis tools (Ghidra, IDA Pro, Binary Ninja with ARM\u002FMIPS\u002FPowerPC support)\n- Understanding of PLC architecture (real-time OS, ladder logic execution, I\u002FO scanning)\n- Reference copy of known-good firmware for integrity comparison\n\n## Workflow\n\n### Step 1: Acquire PLC Firmware for Analysis\n\nExtract or obtain PLC firmware through authorized methods. This can be done by downloading from the vendor, extracting from a lab device, or obtaining from a project backup.\n\n```python\n#!\u002Fusr\u002Fbin\u002Fenv python3\n\"\"\"PLC Firmware Acquisition and Integrity Verification.\n\nSupports firmware extraction from project files, network downloads,\nand binary image comparison against known-good baselines.\n\"\"\"\n\nimport hashlib\nimport json\nimport os\nimport struct\nimport sys\nimport zipfile\nfrom datetime import datetime\nfrom pathlib import Path\n\n\nclass PLCFirmwareAcquisition:\n    \"\"\"Handles PLC firmware acquisition from various sources.\"\"\"\n\n    def __init__(self, output_dir=\"firmware_analysis\"):\n        self.output_dir = Path(output_dir)\n        self.output_dir.mkdir(exist_ok=True)\n        self.manifest = {\n            \"acquisition_date\": datetime.now().isoformat(),\n            \"firmware_samples\": [],\n        }\n\n    def extract_from_siemens_project(self, project_path):\n        \"\"\"Extract firmware\u002Fprogram blocks from Siemens TIA Portal project.\n\n        TIA Portal projects (.ap16\u002F.ap17) are ZIP archives containing\n        XML-encoded PLC program blocks and system configuration.\n        \"\"\"\n        print(f\"[*] Analyzing Siemens project: {project_path}\")\n        results = {\"platform\": \"Siemens\", \"blocks\": []}\n\n        if zipfile.is_zipfile(project_path):\n            with zipfile.ZipFile(project_path, \"r\") as zf:\n                for info in zf.infolist():\n                    # Program blocks are stored as XML in specific paths\n                    if \"ProgramBlocks\" in info.filename or \"SystemBlocks\" in info.filename:\n                        block_data = zf.read(info.filename)\n                        block_hash = hashlib.sha256(block_data).hexdigest()\n\n                        block_path = self.output_dir \u002F info.filename.replace(\"\u002F\", \"_\")\n                        block_path.write_bytes(block_data)\n\n                        results[\"blocks\"].append({\n                            \"name\": info.filename,\n                            \"size\": info.file_size,\n                            \"sha256\": block_hash,\n                            \"extracted_to\": str(block_path),\n                        })\n                        print(f\"  [+] Extracted: {info.filename} ({info.file_size} bytes)\")\n\n        self.manifest[\"firmware_samples\"].append(results)\n        return results\n\n    def extract_from_rockwell_project(self, acd_path):\n        \"\"\"Extract program data from Rockwell Studio 5000 ACD file.\n\n        ACD files contain controller program, tags, and configuration.\n        \"\"\"\n        print(f\"[*] Analyzing Rockwell project: {acd_path}\")\n        results = {\"platform\": \"Rockwell\u002FAllen-Bradley\", \"blocks\": []}\n\n        with open(acd_path, \"rb\") as f:\n            header = f.read(256)\n            # ACD files have a specific signature\n            if b\"RSLogix\" in header or b\"Studio 5000\" in header:\n                f.seek(0)\n                full_data = f.read()\n                file_hash = hashlib.sha256(full_data).hexdigest()\n\n                results[\"blocks\"].append({\n                    \"name\": os.path.basename(acd_path),\n                    \"size\": len(full_data),\n                    \"sha256\": file_hash,\n                    \"header_signature\": header[:16].hex(),\n                })\n                print(f\"  [+] Project hash: {file_hash}\")\n\n        self.manifest[\"firmware_samples\"].append(results)\n        return results\n\n    def compute_firmware_hash(self, firmware_path):\n        \"\"\"Compute multiple hashes of a firmware image for integrity tracking.\"\"\"\n        data = Path(firmware_path).read_bytes()\n        return {\n            \"file\": str(firmware_path),\n            \"size\": len(data),\n            \"md5\": hashlib.md5(data).hexdigest(),\n            \"sha256\": hashlib.sha256(data).hexdigest(),\n            \"sha512\": hashlib.sha512(data).hexdigest(),\n        }\n\n    def compare_firmware_integrity(self, current_fw, baseline_fw):\n        \"\"\"Compare current firmware against known-good baseline.\"\"\"\n        current_hash = self.compute_firmware_hash(current_fw)\n        baseline_hash = self.compute_firmware_hash(baseline_fw)\n\n        match = current_hash[\"sha256\"] == baseline_hash[\"sha256\"]\n\n        result = {\n            \"comparison_date\": datetime.now().isoformat(),\n            \"current_firmware\": current_hash,\n            \"baseline_firmware\": baseline_hash,\n            \"integrity_match\": match,\n            \"verdict\": \"PASS - Firmware matches baseline\" if match else \"FAIL - Firmware modified!\",\n        }\n\n        if not match:\n            # Find the offset where files diverge\n            current_data = Path(current_fw).read_bytes()\n            baseline_data = Path(baseline_fw).read_bytes()\n            min_len = min(len(current_data), len(baseline_data))\n\n            first_diff = None\n            diff_count = 0\n            for i in range(min_len):\n                if current_data[i] != baseline_data[i]:\n                    if first_diff is None:\n                        first_diff = i\n                    diff_count += 1\n\n            result[\"first_difference_offset\"] = f\"0x{first_diff:08x}\" if first_diff else None\n            result[\"total_different_bytes\"] = diff_count\n            result[\"size_difference\"] = len(current_data) - len(baseline_data)\n\n        return result\n\n    def save_manifest(self):\n        \"\"\"Save acquisition manifest.\"\"\"\n        manifest_path = self.output_dir \u002F \"acquisition_manifest.json\"\n        with open(manifest_path, \"w\") as f:\n            json.dump(self.manifest, f, indent=2)\n        print(f\"\\n[*] Manifest saved: {manifest_path}\")\n\n\nif __name__ == \"__main__\":\n    acq = PLCFirmwareAcquisition()\n\n    if len(sys.argv) \u003C 2:\n        print(\"Usage:\")\n        print(\"  python process.py extract-siemens \u003Cproject.ap17>\")\n        print(\"  python process.py extract-rockwell \u003Cproject.acd>\")\n        print(\"  python process.py compare \u003Ccurrent.bin> \u003Cbaseline.bin>\")\n        sys.exit(1)\n\n    cmd = sys.argv[1]\n    if cmd == \"extract-siemens\" and len(sys.argv) > 2:\n        acq.extract_from_siemens_project(sys.argv[2])\n    elif cmd == \"extract-rockwell\" and len(sys.argv) > 2:\n        acq.extract_from_rockwell_project(sys.argv[2])\n    elif cmd == \"compare\" and len(sys.argv) > 3:\n        result = acq.compare_firmware_integrity(sys.argv[2], sys.argv[3])\n        print(json.dumps(result, indent=2))\n    else:\n        print(\"Invalid command\")\n        sys.exit(1)\n\n    acq.save_manifest()\n```\n\n### Step 2: Perform Static Analysis of Firmware Image\n\nUse binwalk for firmware unpacking and Ghidra for disassembly to identify security issues in the firmware binary.\n\n```bash\n# Step 2a: Unpack firmware image with binwalk\nbinwalk -e firmware.bin\n# Output: _firmware.bin.extracted\u002F\n\n# Identify firmware components\nbinwalk firmware.bin\n# Look for: file system images, compressed sections, bootloader, RTOS kernel\n\n# Extract strings for credential and configuration analysis\nstrings -n 8 firmware.bin > firmware_strings.txt\n\n# Search for hardcoded credentials\ngrep -iE \"(password|passwd|pwd|secret|key|credential|login|admin|root)\" firmware_strings.txt\n\n# Search for network configuration\ngrep -iE \"(http|ftp|telnet|ssh|snmp|modbus|192\\.168|10\\.|172\\.)\" firmware_strings.txt\n\n# Search for debug\u002Fbackdoor indicators\ngrep -iE \"(debug|backdoor|test_mode|factory|service_port|hidden)\" firmware_strings.txt\n\n# Search for cryptographic material\ngrep -iE \"(BEGIN RSA|BEGIN CERTIFICATE|AES|DES|private.key)\" firmware_strings.txt\n\n# Step 2b: Entropy analysis to detect encrypted\u002Fcompressed sections\nbinwalk -E firmware.bin\n# High entropy sections may contain encrypted payloads or compressed data\n\n# Step 2c: Analyze with Ghidra (headless mode)\nanalyzeHeadless \u002Ftmp\u002Fghidra_project PLC_FW \\\n  -import firmware.bin \\\n  -processor ARM:LE:32:Cortex \\\n  -postScript FindCryptoConstants.java \\\n  -postScript FindHardcodedStrings.java \\\n  -log \u002Ftmp\u002Fghidra_analysis.log\n```\n\n### Step 3: Analyze PLC Communication Stack Security\n\nExamine how the PLC handles industrial protocol requests, focusing on authentication bypass, buffer overflows in packet parsing, and command injection vulnerabilities.\n\n```python\n#!\u002Fusr\u002Fbin\u002Fenv python3\n\"\"\"PLC Protocol Security Analyzer.\n\nTests PLC protocol implementation for common vulnerabilities\nincluding authentication bypass, malformed packet handling,\nand function code access control.\n\nWARNING: Only run against lab\u002Ftest PLCs, never production systems.\n\"\"\"\n\nimport socket\nimport struct\nimport sys\nimport time\nfrom dataclasses import dataclass\n\n\n@dataclass\nclass ProtocolTestResult:\n    test_name: str\n    target: str\n    protocol: str\n    result: str  # PASS, FAIL, ERROR\n    severity: str\n    detail: str\n\n\nclass ModbusSecurityTester:\n    \"\"\"Tests Modbus\u002FTCP implementation security.\"\"\"\n\n    def __init__(self, target_ip, target_port=502):\n        self.target = target_ip\n        self.port = target_port\n        self.results = []\n\n    def _send_modbus(self, unit_id, func_code, data=b\"\"):\n        \"\"\"Send a Modbus\u002FTCP request and return response.\"\"\"\n        # MBAP Header: transaction_id(2) + protocol_id(2) + length(2) + unit_id(1)\n        mbap = struct.pack(\">HHHB\", 0x0001, 0x0000, len(data) + 2, unit_id)\n        pdu = struct.pack(\"B\", func_code) + data\n\n        try:\n            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n            sock.settimeout(5)\n            sock.connect((self.target, self.port))\n            sock.send(mbap + pdu)\n            response = sock.recv(1024)\n            sock.close()\n            return response\n        except Exception as e:\n            return None\n\n    def test_authentication_required(self):\n        \"\"\"Test if PLC requires authentication for read\u002Fwrite operations.\"\"\"\n        # Test unauthenticated read\n        read_data = struct.pack(\">HH\", 0, 10)  # Read 10 registers from address 0\n        response = self._send_modbus(1, 3, read_data)\n\n        if response and len(response) > 8 and response[7] != 0x83:\n            self.results.append(ProtocolTestResult(\n                test_name=\"Modbus Authentication - Read\",\n                target=self.target,\n                protocol=\"Modbus\u002FTCP\",\n                result=\"FAIL\",\n                severity=\"high\",\n                detail=\"PLC accepts unauthenticated Modbus read commands. No authentication required.\",\n            ))\n\n        # Test unauthenticated write\n        write_data = struct.pack(\">HH\", 100, 0)  # Write 0 to register 100\n        response = self._send_modbus(1, 6, write_data)\n\n        if response and len(response) > 8 and response[7] != 0x86:\n            self.results.append(ProtocolTestResult(\n                test_name=\"Modbus Authentication - Write\",\n                target=self.target,\n                protocol=\"Modbus\u002FTCP\",\n                result=\"FAIL\",\n                severity=\"critical\",\n                detail=\"PLC accepts unauthenticated Modbus WRITE commands. Any host can modify registers.\",\n            ))\n\n    def test_function_code_access_control(self):\n        \"\"\"Test if PLC restricts dangerous function codes.\"\"\"\n        dangerous_funcs = {\n            8: \"Diagnostics (can restart communications)\",\n            17: \"Report Slave ID (information disclosure)\",\n            43: \"Encapsulated Interface Transport (device identification)\",\n        }\n\n        for fc, desc in dangerous_funcs.items():\n            response = self._send_modbus(1, fc, b\"\\x00\\x00\")\n            if response and len(response) > 8:\n                error_code = response[7]\n                if error_code != (fc | 0x80):  # Not an exception response\n                    self.results.append(ProtocolTestResult(\n                        test_name=f\"Function Code Access - FC{fc}\",\n                        target=self.target,\n                        protocol=\"Modbus\u002FTCP\",\n                        result=\"FAIL\",\n                        severity=\"medium\",\n                        detail=f\"PLC responds to FC{fc} ({desc}) without access control\",\n                    ))\n\n    def test_invalid_unit_id(self):\n        \"\"\"Test PLC response to broadcast and invalid unit IDs.\"\"\"\n        # Broadcast (unit ID 0) - should be carefully handled\n        read_data = struct.pack(\">HH\", 0, 1)\n        response = self._send_modbus(0, 3, read_data)\n\n        if response and len(response) > 8 and response[7] != 0x83:\n            self.results.append(ProtocolTestResult(\n                test_name=\"Broadcast Unit ID Handling\",\n                target=self.target,\n                protocol=\"Modbus\u002FTCP\",\n                result=\"FAIL\",\n                severity=\"high\",\n                detail=\"PLC responds to broadcast unit ID 0. This enables broadcast write attacks.\",\n            ))\n\n    def test_malformed_packet_handling(self):\n        \"\"\"Test PLC resilience against malformed Modbus packets.\"\"\"\n        # Oversized length field\n        malformed = struct.pack(\">HHH\", 0x0001, 0x0000, 0xFFFF) + b\"\\x01\\x03\\x00\\x00\\x00\\x01\"\n        try:\n            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n            sock.settimeout(5)\n            sock.connect((self.target, self.port))\n            sock.send(malformed)\n            time.sleep(1)\n\n            # Verify PLC is still responsive\n            read_data = struct.pack(\">HH\", 0, 1)\n            response = self._send_modbus(1, 3, read_data)\n            sock.close()\n\n            if response is None:\n                self.results.append(ProtocolTestResult(\n                    test_name=\"Malformed Packet - Oversized Length\",\n                    target=self.target,\n                    protocol=\"Modbus\u002FTCP\",\n                    result=\"FAIL\",\n                    severity=\"critical\",\n                    detail=\"PLC became unresponsive after receiving oversized length field. Possible DoS vulnerability.\",\n                ))\n            else:\n                self.results.append(ProtocolTestResult(\n                    test_name=\"Malformed Packet - Oversized Length\",\n                    target=self.target,\n                    protocol=\"Modbus\u002FTCP\",\n                    result=\"PASS\",\n                    severity=\"info\",\n                    detail=\"PLC correctly handles oversized length field without crashing\",\n                ))\n        except Exception as e:\n            pass\n\n    def run_all_tests(self):\n        \"\"\"Run all Modbus security tests.\"\"\"\n        print(f\"\\n{'='*60}\")\n        print(f\"PLC MODBUS SECURITY ANALYSIS - {self.target}:{self.port}\")\n        print(f\"{'='*60}\")\n\n        self.test_authentication_required()\n        self.test_function_code_access_control()\n        self.test_invalid_unit_id()\n        self.test_malformed_packet_handling()\n\n        for r in self.results:\n            icon = \"[FAIL]\" if r.result == \"FAIL\" else \"[PASS]\"\n            print(f\"\\n  {icon} {r.test_name}\")\n            print(f\"    Severity: {r.severity}\")\n            print(f\"    Detail: {r.detail}\")\n\n        return self.results\n\n\nif __name__ == \"__main__\":\n    if len(sys.argv) \u003C 2:\n        print(\"Usage: python plc_protocol_tester.py \u003Ctarget_plc_ip> [port]\")\n        print(\"WARNING: Only use against lab\u002Ftest PLCs!\")\n        sys.exit(1)\n\n    target = sys.argv[1]\n    port = int(sys.argv[2]) if len(sys.argv) > 2 else 502\n\n    tester = ModbusSecurityTester(target, port)\n    tester.run_all_tests()\n```\n\n## Key Concepts\n\n| Term | Definition |\n|------|------------|\n| PLC Firmware | The embedded software running on a Programmable Logic Controller, including the real-time operating system, protocol stacks, and I\u002FO drivers |\n| Ladder Logic | Graphical programming language for PLCs that represents relay logic circuits, stored as program blocks in PLC memory |\n| Function Block | Reusable PLC programming element that encapsulates logic with defined inputs\u002Foutputs, can be analyzed for malicious modifications |\n| Firmware Integrity | Verification that PLC firmware has not been modified from the vendor-supplied or approved version using cryptographic hash comparison |\n| IEC 62443-4-2 | Component security requirements in the IEC 62443 standard, defining security capabilities required for IACS components including PLCs |\n| JTAG\u002FSWD | Hardware debug interfaces (Joint Test Action Group \u002F Serial Wire Debug) used for firmware extraction and low-level analysis |\n\n## Tools & Systems\n\n- **Binwalk**: Firmware analysis tool for scanning, extracting, and analyzing embedded firmware images\n- **Ghidra**: NSA-developed reverse engineering framework supporting ARM, MIPS, PowerPC architectures common in PLCs\n- **EMUX\u002FFIRMADYNE**: Firmware emulation frameworks for dynamic analysis of embedded device firmware\n- **PLCinject**: Research tool for analyzing PLC logic injection vulnerabilities (use only in authorized lab settings)\n- **OpenPLC**: Open-source PLC platform useful as a test target for security research\n\n## Output Format\n\n```\nPLC Firmware Security Analysis Report\n=======================================\nDevice: [PLC Model and Firmware Version]\nAnalysis Date: YYYY-MM-DD\nMethodology: Static + Dynamic Analysis\n\nFIRMWARE INTEGRITY:\n  SHA-256: [hash]\n  Baseline Match: [Yes\u002FNo]\n  Vendor Signature Valid: [Yes\u002FNo\u002FNot Signed]\n\nVULNERABILITIES FOUND:\n  [PLC-001] [Severity] [Title]\n    CWE: [CWE-ID]\n    Detail: [Technical description]\n    Impact: [Operational impact]\n    Remediation: [Fix or mitigation]\n```\n","# Performing PLC Firmware Security Analysis\n\n## When to Use\n\n- When assessing PLC security as part of an IEC 62443 component security evaluation (IEC 62443-4-2)\n- When validating firmware integrity after a suspected compromise or supply chain attack\n- When evaluating the security of a new PLC platform before deployment in critical infrastructure\n- When performing vulnerability research on industrial control system devices in an authorized lab\n- When responding to an incident where PLC logic or firmware tampering is suspected\n\n**Do not use** on live production PLCs without explicit authorization and safety controls in place. Firmware extraction and analysis should be performed on lab devices or offline backups. Never upload PLC firmware to public analysis services. See performing-ics-penetration-testing for authorized live testing procedures.\n\n## Prerequisites\n\n- Isolated lab environment with the target PLC hardware or an emulated environment\n- PLC programming software for the target platform (Siemens TIA Portal, Rockwell Studio 5000, Schneider EcoStruxure)\n- Firmware extraction tools (binwalk, firmware-mod-kit, JTAG\u002FSWD debugger)\n- Static analysis tools (Ghidra, IDA Pro, Binary Ninja with ARM\u002FMIPS\u002FPowerPC support)\n- Understanding of PLC architecture (real-time OS, ladder logic execution, I\u002FO scanning)\n- Reference copy of known-good firmware for integrity comparison\n\n## Workflow\n\n### Step 1: Acquire PLC Firmware for Analysis\n\nExtract or obtain PLC firmware through authorized methods. This can be done by downloading from the vendor, extracting from a lab device, or obtaining from a project backup.\n\n```python\n#!\u002Fusr\u002Fbin\u002Fenv python3\n\"\"\"PLC Firmware Acquisition and Integrity Verification.\n\nSupports firmware extraction from project files, network downloads,\nand binary image comparison against known-good baselines.\n\"\"\"\n\nimport hashlib\nimport json\nimport os\nimport struct\nimport sys\nimport zipfile\nfrom datetime import datetime\nfrom pathlib import Path\n\n\nclass PLCFirmwareAcquisition:\n    \"\"\"Handles PLC firmware acquisition from various sources.\"\"\"\n\n    def __init__(self, output_dir=\"firmware_analysis\"):\n        self.output_dir = Path(output_dir)\n        self.output_dir.mkdir(exist_ok=True)\n        self.manifest = {\n            \"acquisition_date\": datetime.now().isoformat(),\n            \"firmware_samples\": [],\n        }\n\n    def extract_from_siemens_project(self, project_path):\n        \"\"\"Extract firmware\u002Fprogram blocks from Siemens TIA Portal project.\n\n        TIA Portal projects (.ap16\u002F.ap17) are ZIP archives containing\n        XML-encoded PLC program blocks and system configuration.\n        \"\"\"\n        print(f\"[*] Analyzing Siemens project: {project_path}\")\n        results = {\"platform\": \"Siemens\", \"blocks\": []}\n\n        if zipfile.is_zipfile(project_path):\n            with zipfile.ZipFile(project_path, \"r\") as zf:\n                for info in zf.infolist():\n                    # Program blocks are stored as XML in specific paths\n                    if \"ProgramBlocks\" in info.filename or \"SystemBlocks\" in info.filename:\n                        block_data = zf.read(info.filename)\n                        block_hash = hashlib.sha256(block_data).hexdigest()\n\n                        block_path = self.output_dir \u002F info.filename.replace(\"\u002F\", \"_\")\n                        block_path.write_bytes(block_data)\n\n                        results[\"blocks\"].append({\n                            \"name\": info.filename,\n                            \"size\": info.file_size,\n                            \"sha256\": block_hash,\n                            \"extracted_to\": str(block_path),\n                        })\n                        print(f\"  [+] Extracted: {info.filename} ({info.file_size} bytes)\")\n\n        self.manifest[\"firmware_samples\"].append(results)\n        return results\n\n    def extract_from_rockwell_project(self, acd_path):\n        \"\"\"Extract program data from Rockwell Studio 5000 ACD file.\n\n        ACD files contain controller program, tags, and configuration.\n        \"\"\"\n        print(f\"[*] Analyzing Rockwell project: {acd_path}\")\n        results = {\"platform\": \"Rockwell\u002FAllen-Bradley\", \"blocks\": []}\n\n        with open(acd_path, \"rb\") as f:\n            header = f.read(256)\n            # ACD files have a specific signature\n            if b\"RSLogix\" in header or b\"Studio 5000\" in header:\n                f.seek(0)\n                full_data = f.read()\n                file_hash = hashlib.sha256(full_data).hexdigest()\n\n                results[\"blocks\"].append({\n                    \"name\": os.path.basename(acd_path),\n                    \"size\": len(full_data),\n                    \"sha256\": file_hash,\n                    \"header_signature\": header[:16].hex(),\n                })\n                print(f\"  [+] Project hash: {file_hash}\")\n\n        self.manifest[\"firmware_samples\"].append(results)\n        return results\n\n    def compute_firmware_hash(self, firmware_path):\n        \"\"\"Compute multiple hashes of a firmware image for integrity tracking.\"\"\"\n        data = Path(firmware_path).read_bytes()\n        return {\n            \"file\": str(firmware_path),\n            \"size\": len(data),\n            \"md5\": hashlib.md5(data).hexdigest(),\n            \"sha256\": hashlib.sha256(data).hexdigest(),\n            \"sha512\": hashlib.sha512(data).hexdigest(),\n        }\n\n    def compare_firmware_integrity(self, current_fw, baseline_fw):\n        \"\"\"Compare current firmware against known-good baseline.\"\"\"\n        current_hash = self.compute_firmware_hash(current_fw)\n        baseline_hash = self.compute_firmware_hash(baseline_fw)\n\n        match = current_hash[\"sha256\"] == baseline_hash[\"sha256\"]\n\n        result = {\n            \"comparison_date\": datetime.now().isoformat(),\n            \"current_firmware\": current_hash,\n            \"baseline_firmware\": baseline_hash,\n            \"integrity_match\": match,\n            \"verdict\": \"PASS - Firmware matches baseline\" if match else \"FAIL - Firmware modified!\",\n        }\n\n        if not match:\n            # Find the offset where files diverge\n            current_data = Path(current_fw).read_bytes()\n            baseline_data = Path(baseline_fw).read_bytes()\n            min_len = min(len(current_data), len(baseline_data))\n\n            first_diff = None\n            diff_count = 0\n            for i in range(min_len):\n                if current_data[i] != baseline_data[i]:\n                    if first_diff is None:\n                        first_diff = i\n                    diff_count += 1\n\n            result[\"first_difference_offset\"] = f\"0x{first_diff:08x}\" if first_diff else None\n            result[\"total_different_bytes\"] = diff_count\n            result[\"size_difference\"] = len(current_data) - len(baseline_data)\n\n        return result\n\n    def save_manifest(self):\n        \"\"\"Save acquisition manifest.\"\"\"\n        manifest_path = self.output_dir \u002F \"acquisition_manifest.json\"\n        with open(manifest_path, \"w\") as f:\n            json.dump(self.manifest, f, indent=2)\n        print(f\"\\n[*] Manifest saved: {manifest_path}\")\n\n\nif __name__ == \"__main__\":\n    acq = PLCFirmwareAcquisition()\n\n    if len(sys.argv) \u003C 2:\n        print(\"Usage:\")\n        print(\"  python process.py extract-siemens \u003Cproject.ap17>\")\n        print(\"  python process.py extract-rockwell \u003Cproject.acd>\")\n        print(\"  python process.py compare \u003Ccurrent.bin> \u003Cbaseline.bin>\")\n        sys.exit(1)\n\n    cmd = sys.argv[1]\n    if cmd == \"extract-siemens\" and len(sys.argv) > 2:\n        acq.extract_from_siemens_project(sys.argv[2])\n    elif cmd == \"extract-rockwell\" and len(sys.argv) > 2:\n        acq.extract_from_rockwell_project(sys.argv[2])\n    elif cmd == \"compare\" and len(sys.argv) > 3:\n        result = acq.compare_firmware_integrity(sys.argv[2], sys.argv[3])\n        print(json.dumps(result, indent=2))\n    else:\n        print(\"Invalid command\")\n        sys.exit(1)\n\n    acq.save_manifest()\n```\n\n### Step 2: Perform Static Analysis of Firmware Image\n\nUse binwalk for firmware unpacking and Ghidra for disassembly to identify security issues in the firmware binary.\n\n```bash\n# Step 2a: Unpack firmware image with binwalk\nbinwalk -e firmware.bin\n# Output: _firmware.bin.extracted\u002F\n\n# Identify firmware components\nbinwalk firmware.bin\n# Look for: file system images, compressed sections, bootloader, RTOS kernel\n\n# Extract strings for credential and configuration analysis\nstrings -n 8 firmware.bin > firmware_strings.txt\n\n# Search for hardcoded credentials\ngrep -iE \"(password|passwd|pwd|secret|key|credential|login|admin|root)\" firmware_strings.txt\n\n# Search for network configuration\ngrep -iE \"(http|ftp|telnet|ssh|snmp|modbus|192\\.168|10\\.|172\\.)\" firmware_strings.txt\n\n# Search for debug\u002Fbackdoor indicators\ngrep -iE \"(debug|backdoor|test_mode|factory|service_port|hidden)\" firmware_strings.txt\n\n# Search for cryptographic material\ngrep -iE \"(BEGIN RSA|BEGIN CERTIFICATE|AES|DES|private.key)\" firmware_strings.txt\n\n# Step 2b: Entropy analysis to detect encrypted\u002Fcompressed sections\nbinwalk -E firmware.bin\n# High entropy sections may contain encrypted payloads or compressed data\n\n# Step 2c: Analyze with Ghidra (headless mode)\nanalyzeHeadless \u002Ftmp\u002Fghidra_project PLC_FW \\\n  -import firmware.bin \\\n  -processor ARM:LE:32:Cortex \\\n  -postScript FindCryptoConstants.java \\\n  -postScript FindHardcodedStrings.java \\\n  -log \u002Ftmp\u002Fghidra_analysis.log\n```\n\n### Step 3: Analyze PLC Communication Stack Security\n\nExamine how the PLC handles industrial protocol requests, focusing on authentication bypass, buffer overflows in packet parsing, and command injection vulnerabilities.\n\n```python\n#!\u002Fusr\u002Fbin\u002Fenv python3\n\"\"\"PLC Protocol Security Analyzer.\n\nTests PLC protocol implementation for common vulnerabilities\nincluding authentication bypass, malformed packet handling,\nand function code access control.\n\nWARNING: Only run against lab\u002Ftest PLCs, never production systems.\n\"\"\"\n\nimport socket\nimport struct\nimport sys\nimport time\nfrom dataclasses import dataclass\n\n\n@dataclass\nclass ProtocolTestResult:\n    test_name: str\n    target: str\n    protocol: str\n    result: str  # PASS, FAIL, ERROR\n    severity: str\n    detail: str\n\n\nclass ModbusSecurityTester:\n    \"\"\"Tests Modbus\u002FTCP implementation security.\"\"\"\n\n    def __init__(self, target_ip, target_port=502):\n        self.target = target_ip\n        self.port = target_port\n        self.results = []\n\n    def _send_modbus(self, unit_id, func_code, data=b\"\"):\n        \"\"\"Send a Modbus\u002FTCP request and return response.\"\"\"\n        # MBAP Header: transaction_id(2) + protocol_id(2) + length(2) + unit_id(1)\n        mbap = struct.pack(\">HHHB\", 0x0001, 0x0000, len(data) + 2, unit_id)\n        pdu = struct.pack(\"B\", func_code) + data\n\n        try:\n            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n            sock.settimeout(5)\n            sock.connect((self.target, self.port))\n            sock.send(mbap + pdu)\n            response = sock.recv(1024)\n            sock.close()\n            return response\n        except Exception as e:\n            return None\n\n    def test_authentication_required(self):\n        \"\"\"Test if PLC requires authentication for read\u002Fwrite operations.\"\"\"\n        # Test unauthenticated read\n        read_data = struct.pack(\">HH\", 0, 10)  # Read 10 registers from address 0\n        response = self._send_modbus(1, 3, read_data)\n\n        if response and len(response) > 8 and response[7] != 0x83:\n            self.results.append(ProtocolTestResult(\n                test_name=\"Modbus Authentication - Read\",\n                target=self.target,\n                protocol=\"Modbus\u002FTCP\",\n                result=\"FAIL\",\n                severity=\"high\",\n                detail=\"PLC accepts unauthenticated Modbus read commands. No authentication required.\",\n            ))\n\n        # Test unauthenticated write\n        write_data = struct.pack(\">HH\", 100, 0)  # Write 0 to register 100\n        response = self._send_modbus(1, 6, write_data)\n\n        if response and len(response) > 8 and response[7] != 0x86:\n            self.results.append(ProtocolTestResult(\n                test_name=\"Modbus Authentication - Write\",\n                target=self.target,\n                protocol=\"Modbus\u002FTCP\",\n                result=\"FAIL\",\n                severity=\"critical\",\n                detail=\"PLC accepts unauthenticated Modbus WRITE commands. Any host can modify registers.\",\n            ))\n\n    def test_function_code_access_control(self):\n        \"\"\"Test if PLC restricts dangerous function codes.\"\"\"\n        dangerous_funcs = {\n            8: \"Diagnostics (can restart communications)\",\n            17: \"Report Slave ID (information disclosure)\",\n            43: \"Encapsulated Interface Transport (device identification)\",\n        }\n\n        for fc, desc in dangerous_funcs.items():\n            response = self._send_modbus(1, fc, b\"\\x00\\x00\")\n            if response and len(response) > 8:\n                error_code = response[7]\n                if error_code != (fc | 0x80):  # Not an exception response\n                    self.results.append(ProtocolTestResult(\n                        test_name=f\"Function Code Access - FC{fc}\",\n                        target=self.target,\n                        protocol=\"Modbus\u002FTCP\",\n                        result=\"FAIL\",\n                        severity=\"medium\",\n                        detail=f\"PLC responds to FC{fc} ({desc}) without access control\",\n                    ))\n\n    def test_invalid_unit_id(self):\n        \"\"\"Test PLC response to broadcast and invalid unit IDs.\"\"\"\n        # Broadcast (unit ID 0) - should be carefully handled\n        read_data = struct.pack(\">HH\", 0, 1)\n        response = self._send_modbus(0, 3, read_data)\n\n        if response and len(response) > 8 and response[7] != 0x83:\n            self.results.append(ProtocolTestResult(\n                test_name=\"Broadcast Unit ID Handling\",\n                target=self.target,\n                protocol=\"Modbus\u002FTCP\",\n                result=\"FAIL\",\n                severity=\"high\",\n                detail=\"PLC responds to broadcast unit ID 0. This enables broadcast write attacks.\",\n            ))\n\n    def test_malformed_packet_handling(self):\n        \"\"\"Test PLC resilience against malformed Modbus packets.\"\"\"\n        # Oversized length field\n        malformed = struct.pack(\">HHH\", 0x0001, 0x0000, 0xFFFF) + b\"\\x01\\x03\\x00\\x00\\x00\\x01\"\n        try:\n            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n            sock.settimeout(5)\n            sock.connect((self.target, self.port))\n            sock.send(malformed)\n            time.sleep(1)\n\n            # Verify PLC is still responsive\n            read_data = struct.pack(\">HH\", 0, 1)\n            response = self._send_modbus(1, 3, read_data)\n            sock.close()\n\n            if response is None:\n                self.results.append(ProtocolTestResult(\n                    test_name=\"Malformed Packet - Oversized Length\",\n                    target=self.target,\n                    protocol=\"Modbus\u002FTCP\",\n                    result=\"FAIL\",\n                    severity=\"critical\",\n                    detail=\"PLC became unresponsive after receiving oversized length field. Possible DoS vulnerability.\",\n                ))\n            else:\n                self.results.append(ProtocolTestResult(\n                    test_name=\"Malformed Packet - Oversized Length\",\n                    target=self.target,\n                    protocol=\"Modbus\u002FTCP\",\n                    result=\"PASS\",\n                    severity=\"info\",\n                    detail=\"PLC correctly handles oversized length field without crashing\",\n                ))\n        except Exception as e:\n            pass\n\n    def run_all_tests(self):\n        \"\"\"Run all Modbus security tests.\"\"\"\n        print(f\"\\n{'='*60}\")\n        print(f\"PLC MODBUS SECURITY ANALYSIS - {self.target}:{self.port}\")\n        print(f\"{'='*60}\")\n\n        self.test_authentication_required()\n        self.test_function_code_access_control()\n        self.test_invalid_unit_id()\n        self.test_malformed_packet_handling()\n\n        for r in self.results:\n            icon = \"[FAIL]\" if r.result == \"FAIL\" else \"[PASS]\"\n            print(f\"\\n  {icon} {r.test_name}\")\n            print(f\"    Severity: {r.severity}\")\n            print(f\"    Detail: {r.detail}\")\n\n        return self.results\n\n\nif __name__ == \"__main__\":\n    if len(sys.argv) \u003C 2:\n        print(\"Usage: python plc_protocol_tester.py \u003Ctarget_plc_ip> [port]\")\n        print(\"WARNING: Only use against lab\u002Ftest PLCs!\")\n        sys.exit(1)\n\n    target = sys.argv[1]\n    port = int(sys.argv[2]) if len(sys.argv) > 2 else 502\n\n    tester = ModbusSecurityTester(target, port)\n    tester.run_all_tests()\n```\n\n## Key Concepts\n\n| Term | Definition |\n|------|------------|\n| PLC Firmware | The embedded software running on a Programmable Logic Controller, including the real-time operating system, protocol stacks, and I\u002FO drivers |\n| Ladder Logic | Graphical programming language for PLCs that represents relay logic circuits, stored as program blocks in PLC memory |\n| Function Block | Reusable PLC programming element that encapsulates logic with defined inputs\u002Foutputs, can be analyzed for malicious modifications |\n| Firmware Integrity | Verification that PLC firmware has not been modified from the vendor-supplied or approved version using cryptographic hash comparison |\n| IEC 62443-4-2 | Component security requirements in the IEC 62443 standard, defining security capabilities required for IACS components including PLCs |\n| JTAG\u002FSWD | Hardware debug interfaces (Joint Test Action Group \u002F Serial Wire Debug) used for firmware extraction and low-level analysis |\n\n## Tools & Systems\n\n- **Binwalk**: Firmware analysis tool for scanning, extracting, and analyzing embedded firmware images\n- **Ghidra**: NSA-developed reverse engineering framework supporting ARM, MIPS, PowerPC architectures common in PLCs\n- **EMUX\u002FFIRMADYNE**: Firmware emulation frameworks for dynamic analysis of embedded device firmware\n- **PLCinject**: Research tool for analyzing PLC logic injection vulnerabilities (use only in authorized lab settings)\n- **OpenPLC**: Open-source PLC platform useful as a test target for security research\n\n## Output Format\n\n```\nPLC Firmware Security Analysis Report\n=======================================\nDevice: [PLC Model and Firmware Version]\nAnalysis Date: YYYY-MM-DD\nMethodology: Static + Dynamic Analysis\n\nFIRMWARE INTEGRITY:\n  SHA-256: [hash]\n  Baseline Match: [Yes\u002FNo]\n  Vendor Signature Valid: [Yes\u002FNo\u002FNot Signed]\n\nVULNERABILITIES FOUND:\n  [PLC-001] [Severity] [Title]\n    CWE: [CWE-ID]\n    Detail: [Technical description]\n    Impact: [Operational impact]\n    Remediation: [Fix or mitigation]\n```\n",{"name":5,"tags":49,"author":55,"domain":41,"license":15,"version":56,"nist_csf":57,"subdomain":62,"description":63,"mitre_attack":64},[50,51,52,53,54,31,30],"ot-security","ics","scada","industrial-control","iec62443","mahipal","1.0.0",[58,59,60,61],"PR.IR-01","DE.CM-01","ID.AM-05","GV.OC-02","ot-ics-security","This skill covers analyzing Programmable Logic Controller (PLC) firmware for security vulnerabilities including hardcoded credentials, insecure update mechanisms, backdoor functions, memory corruption flaws, and undocumented debug interfaces. It addresses firmware extraction from common PLC platforms (Siemens S7, Allen-Bradley, Schneider Modicon), static analysis of firmware images, dynamic analysis in emulated environments, and comparison against known-good baselines to detect tampering.\n",[65,66,67,68,69],"T1078","T1190","T1059","T1003","T1110","main","54a798831d2266a3ca61ce68a7acb80b81160d57","skills\u002Fperforming-plc-firmware-security-analysis",4395,"https:\u002F\u002Fgithub.com\u002Fmukul975\u002FAnthropic-Cybersecurity-Skills","https:\u002F\u002Fmahipal.engineer\u002FAnthropic-Cybersecurity-Skills\u002F","https:\u002F\u002Fgithub.com\u002Fmukul975","Mahipal.engineer","🔐 Cybersecurity | 💻 Dev | 📷 Street Photographer\r\n🎓 MSc | 📚 Research & AI Security","2026-08-31 12:32:44",{"source":8,"skillName":5,"commands":81,"prompt":91,"zipAvailable":92},[82,85,88],{"tool":83,"command":84},"npx","npx skills add mukul975\u002FAnthropic-Cybersecurity-Skills --skill performing-plc-firmware-security-analysis",{"tool":86,"command":87},"bunx","bunx skills add mukul975\u002FAnthropic-Cybersecurity-Skills --skill performing-plc-firmware-security-analysis",{"tool":89,"command":90},"pnpm","pnpm dlx skills add mukul975\u002FAnthropic-Cybersecurity-Skills --skill performing-plc-firmware-security-analysis","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fmukul975\u002FAnthropic-Cybersecurity-Skills\u002Fblob\u002Fmain\u002Fskills\u002Fperforming-plc-firmware-security-analysis\u002FSKILL.md",true,[94,99,105,109,113],{"path":95,"resourceType":95,"resourceTypeDesc":96,"sizeBytes":97,"sourceHtmlUrl":98},"LICENSE","许可证",11255,"https:\u002F\u002Fgithub.com\u002Fmukul975\u002FAnthropic-Cybersecurity-Skills\u002Fblob\u002Fmain\u002Fskills\u002Fperforming-plc-firmware-security-analysis\u002FLICENSE",{"path":100,"resourceType":101,"resourceTypeDesc":102,"sizeBytes":103,"sourceHtmlUrl":104},"references\u002Fapi-reference.md","REFERENCE","参考文档",1760,"https:\u002F\u002Fgithub.com\u002Fmukul975\u002FAnthropic-Cybersecurity-Skills\u002Fblob\u002Fmain\u002Fskills\u002Fperforming-plc-firmware-security-analysis\u002Freferences\u002Fapi-reference.md",{"path":106,"resourceType":101,"resourceTypeDesc":102,"sizeBytes":107,"sourceHtmlUrl":108},"references\u002Fdirected.md",945,"https:\u002F\u002Fgithub.com\u002Fasermax\u002Fclaude-plugins\u002Fblob\u002Fmaster\u002Fmahou\u002Fskills\u002Flearn\u002Freferences\u002Fdirected.md",{"path":110,"resourceType":101,"resourceTypeDesc":102,"sizeBytes":111,"sourceHtmlUrl":112},"references\u002Fdiscover.md",2119,"https:\u002F\u002Fgithub.com\u002Fasermax\u002Fclaude-plugins\u002Fblob\u002Fmaster\u002Fmahou\u002Fskills\u002Flearn\u002Freferences\u002Fdiscover.md",{"path":114,"resourceType":115,"resourceTypeDesc":116,"sizeBytes":117,"sourceHtmlUrl":118},"scripts\u002Fagent.py","SCRIPT","脚本",7482,"https:\u002F\u002Fgithub.com\u002Fmukul975\u002FAnthropic-Cybersecurity-Skills\u002Fblob\u002Fmain\u002Fskills\u002Fperforming-plc-firmware-security-analysis\u002Fscripts\u002Fagent.py",[120,145,168,195,221,248],{"skillNo":121,"name":122,"nameZh":6,"description":123,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":124,"categories":125,"keywords":127,"publishedAt":44},"01M6AGDM3HJXTKXX15ZZ0ZVCJ3","verifying-build-provenance-with-slsa-sigstore","Verifies artifact signatures and SLSA provenance using Sigstore's cosign (verify, verify-attestation, verify-blob-attestation) and slsa-verifier (verify-artifact), enforcing keyless OIDC builder identity and source repo against SLSA Build levels. Use in CI\u002FCD before deploying artifacts, when consuming third-party attestations, establishing a SLSA Build L3 pipeline, or confirming provenance during incident response or admission control.","https:\u002F\u002Fgithub.com\u002Fmukul975\u002FAnthropic-Cybersecurity-Skills\u002Fblob\u002Fmain\u002Fskills\u002Fverifying-build-provenance-with-slsa-sigstore\u002FSKILL.md",[126],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},[128,129,130,131,28,41,132,133,40,134,135,136,137,138,139,140,141,142,143,144],"sigstore","provenance","slsa","verifying build provenance with slsa sigstore","incident response","identity","code","artifacts","ci","supply-chain","pipeline","supply-chain-security","t1195","attestation","code-signing","cosign","keyless",{"skillNo":146,"name":147,"nameZh":6,"description":148,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":149,"categories":150,"keywords":152,"publishedAt":44},"01M6AGDGBPWYVZ2F11GFKJ4HZ9","validating-tpm-measured-boot-attestation","Verifies TPM 2.0 measured-boot integrity and remote attestation with tpm2-tools -- reading PCRs (tpm2_pcrread), replaying the boot event log, generating and checking signed quotes (tpm2_quote\u002Ftpm2_checkquote), and sealing secrets to a PCR policy. Use to confirm a system booted trusted firmware\u002Fkernel for Zero Trust device posture, detect boot-chain tampering via PCR drift, or build a golden-value baseline for fleet attestation.","https:\u002F\u002Fgithub.com\u002Fmukul975\u002FAnthropic-Cybersecurity-Skills\u002Fblob\u002Fmain\u002Fskills\u002Fvalidating-tpm-measured-boot-attestation\u002FSKILL.md",[151],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},[153,141,154,155,28,156,41,40,157,158,27,159,160,161,162,163,164,165,166,167],"boot","TPM","validating tpm measured boot attestation","policy","verification","ZeRO","Tools","measured-boot","PCR","integrity","secrets","remote-attestation","tpm2-tools","integrity-verification","trusted-computing",{"skillNo":169,"name":170,"nameZh":6,"description":171,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":172,"categories":173,"keywords":178,"publishedAt":44},"01M6AGDCW0Y4FXZ3362GT1941M","validating-backup-integrity-for-recovery","Validates backup integrity through cryptographic hash verification, automated restore testing, corruption detection, and recoverability checks to confirm backups are reliable for disaster recovery and ransomware response. Use before relying on backups for recovery, when building post-backup validation pipelines, auditing backup infrastructure for compliance, or checking immutable\u002Fair-gapped backups for silent corruption or tampering.","https:\u002F\u002Fgithub.com\u002Fmukul975\u002FAnthropic-Cybersecurity-Skills\u002Fblob\u002Fmain\u002Fskills\u002Fvalidating-backup-integrity-for-recovery\u002FSKILL.md",[174,177],{"categoryNo":175,"categoryName":176,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000008","测试与质量",{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},[162,179,180,181,182,41,183,184,157,185,186,187,188,189,190,35,191,192,193,194],"backup","recovery","validating backup integrity for recovery","testing","infrastructure","validation","compliance","hash-verification","incident-response","ransomware","cryptocurrency","detection","t1490","immutable","disaster-recovery","restore-testing",{"skillNo":196,"name":197,"nameZh":6,"description":198,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":199,"categories":200,"keywords":202,"publishedAt":44},"01M6AGD9GBG2KZ336AE763J3WH","triaging-windows-with-kape","Runs KAPE (Kroll Artifact Parser and Extractor) to collect targeted forensic artifacts (registry hives, $MFT, event logs, prefetch, browser data) via Targets and parse them with Modules wrapping Eric Zimmerman's EZ Tools (PECmd, MFTECmd, RECmd). Use during early incident containment\u002Ftriage when full disk imaging is impractical but a defensible, parseable Windows artifact set is needed quickly, including at-scale remote collection.","https:\u002F\u002Fgithub.com\u002Fmukul975\u002FAnthropic-Cybersecurity-Skills\u002Fblob\u002Fmain\u002Fskills\u002Ftriaging-windows-with-kape\u002FSKILL.md",[201],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},[203,204,205,41,206,207,208,209,210,211,212,213,214,215,216,217,159,218,219,220],"windows","kape","triaging windows with kape","registry","browser","logs","windows-forensics","dfir","mft","mftecmd","data","prefetch","eric-zimmerman","digital-forensics","SET","collection","pecmd","artifact-collection",{"skillNo":222,"name":223,"nameZh":6,"description":224,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":225,"categories":226,"keywords":228,"publishedAt":44},"01M6AGD5PW5J4EVZM958WD74ZQ","triaging-vulnerabilities-with-ssvc-framework","Triages and prioritizes vulnerabilities with CISA's Stakeholder-Specific Vulnerability Categorization (SSVC) decision tree, weighing exploitation status (via the CISA KEV catalog and FIRST EPSS API), technical impact, automatability, and mission prevalence to output Track\u002FTrack*\u002FAttend\u002FAct decisions. Use when prioritizing vulnerability scan results (OpenVAS, Nessus, Qualys) for remediation planning beyond raw CVSS scores.","https:\u002F\u002Fgithub.com\u002Fmukul975\u002FAnthropic-Cybersecurity-Skills\u002Fblob\u002Fmain\u002Fskills\u002Ftriaging-vulnerabilities-with-ssvc-framework\u002FSKILL.md",[227],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},[229,230,231,41,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247],"vulnerabilities","framework","triaging vulnerabilities with ssvc framework","status","planning","CISA","vulnerability-management","risk-management","nessus","qualys","openvas","cvss","remediation","risk","vulnerability","api","prioritization","ssvc","decision-tree",{"skillNo":249,"name":250,"nameZh":6,"description":251,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":252,"categories":253,"keywords":255,"publishedAt":44},"01M6AGD24TTQQM4CXG69E3B9TJ","triaging-security-incident","Performs initial triage of security incidents using the NIST SP 800-61r3 and SANS PICERL frameworks, classifying incident type, assigning priority by business impact, and routing to the appropriate response team. Use when a SIEM\u002FEDR alert needs human classification, concurrent alerts must be prioritized, or a user report or threat-intel IOC match requires initial incident categorization.","https:\u002F\u002Fgithub.com\u002Fmukul975\u002FAnthropic-Cybersecurity-Skills\u002Fblob\u002Fmain\u002Fskills\u002Ftriaging-security-incident\u002FSKILL.md",[254],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},[28,256,41,257,258,259,260,261,262,263,264,35,265,191,26,266,267,268,269,270],"triaging security incident","siem","file","ioc","soc","NIST-800-61","NIST","severity","edr","execution","classification","severity-classification","incident-triage","SANS-PICERL","SOC-operations"]