daemon-sec-cheatsheet

The cheatsheet vault for operators: AD, enumeration, exploitation, priv-esc, web, DFIR
git clone https://git.daemon-sec.xyz/daemon-sec-cheatsheet.git
Log | Files | Refs | README | LICENSE

44818-ethernetip.md (7414B)


      1 ---
      2 title: "44818 Pentesting EtherNet/IP"
      3 section: "Network Services"
      4 sectionSlug: "network-services-pentesting"
      5 sourcePath: "src/network-services-pentesting/44818-ethernetip.md"
      6 sourceUrl: "https://github.com/HackTricks-wiki/hacktricks/blob/188de82beb54e70956b2952367a0af91d26758b8/src/network-services-pentesting/44818-ethernetip.md"
      7 sha: "188de82beb54e70956b2952367a0af91d26758b8"
      8 isIndex: false
      9 modified: true
     10 license: "CC-BY-NC-4.0"
     11 ---
     12 
     13 # 44818 Pentesting EtherNet/IP
     14 
     15 ## Protocol information
     16 
     17 EtherNet/IP carries the Common Industrial Protocol (CIP) over standard Ethernet and is maintained by ODVA. Its common object model and conformance framework are intended to let devices from different vendors interoperate. It is used across industrial automation environments such as manufacturing, utilities, and water or process-control systems. Its encapsulation protocol uses TCP and UDP port 44818 for explicit messaging and discovery. The `ListIdentity` command (`0x0063`) can be sent directly over TCP or UDP with a zero session handle; a UDP broadcast is commonly used to discover every EtherNet/IP device on the local network.<sup>[[1]](#references)</sup>
     18 
     19 **Default ports:**
     20 
     21 - **44818/TCP:** encapsulation sessions, discovery commands, and explicit CIP messaging.<sup>[[1]](#references)</sup>
     22 - **44818/UDP:** connectionless encapsulation discovery, especially `ListIdentity` broadcasts.<sup>[[1]](#references)</sup>
     23 - **2222/UDP:** time-critical implicit (Class 0/1) I/O after a connection is negotiated. This traffic can be cyclic or change-of-state, unicast or multicast, and is especially useful when mapping controller-to-adapter relationships.<sup>[[1]](#references)</sup>
     24 
     25 ```text
     26 PORT      STATE SERVICE
     27 44818/tcp open  EtherNet/IP
     28 ```
     29 
     30 ### Encapsulation and CIP request anatomy
     31 
     32 Recognizing the normal sequence makes captures and custom probes much easier:<sup>[[1]](#references)</sup>
     33 
     34 1. Discovery commands such as `ListIdentity`, `ListServices`, and `ListInterfaces` do not require a registered session.
     35 2. A TCP originator normally sends `RegisterSession` (`0x0065`) and receives a 32-bit session handle.
     36 3. `SendRRData` (`0x006f`) carries unconnected CIP requests. A `Forward_Open` request to the Connection Manager creates a connected explicit or I/O connection; connected explicit traffic is then normally carried by `SendUnitData` (`0x0070`).
     37 4. A CIP request selects a **service** and an encoded path. Object paths commonly identify class, instance, and attribute; Logix symbolic paths instead address controller/program tags. Read-only assessment usually starts with `Get_Attributes_All` (`0x01`) and `Get_Attribute_Single` (`0x0e`). Treat `Set_Attribute_Single` (`0x10`), `Reset` (`0x05`), vendor-specific services, and tag writes as state-changing operations.
     38 
     39 ## Enumeration
     40 
     41 Nmap's `enip-info` script sends a request-identity packet and can return the vendor ID, device type, product name, revision, serial number, and IP address.<sup>[[2]](#references)</sup>
     42 
     43 ```bash
     44 nmap -n -sV --script enip-info -p 44818 <IP>
     45 nmap -n -sU --script enip-info -p 44818 <IP>
     46 pip3 install cpppo
     47 python3 -m cpppo.server.enip.list_services [--udp] [--broadcast] --list-identity -a <IP>
     48 ```
     49 
     50 The complete unicast UDP `ListIdentity` request is only the 24-byte encapsulation header below. This is useful where NSE is unavailable and also confirms whether UDP discovery is filtered differently from TCP.<sup>[[1]](#references)</sup>
     51 
     52 ```bash
     53 IP=192.0.2.10
     54 printf '630000000000000000000000000000000000000000000000' | xxd -r -p | \
     55   timeout 3 socat -T2 - UDP-DATAGRAM:$IP:44818 | xxd
     56 ```
     57 
     58 For local-segment discovery and Rockwell/Allen-Bradley rack or tag inventory, `pycomm3` exposes both the encapsulation discovery calls and routed CIP operations. A route such as `<gateway-IP>/backplane/<slot>` reaches a controller behind an EtherNet/IP bridge. Opening `LogixDriver` uploads tag definitions by default, so do this slowly on production controllers; `external_access` immediately highlights tags exposed as `Read Only` or `Read/Write`.<sup>[[3]](#references)</sup>
     59 
     60 ```bash
     61 pip3 install pycomm3
     62 ```
     63 
     64 ```python
     65 from pycomm3 import CIPDriver, LogixDriver
     66 
     67 for identity in CIPDriver.discover():
     68     print(identity)
     69 
     70 target = "192.0.2.10/backplane/0"
     71 with LogixDriver(target, init_program_tags=False) as plc:
     72     print(plc.info)
     73     for name, meta in plc.tags.items():
     74         print(name, meta["data_type_name"], meta["external_access"])
     75     print(plc.read("KnownSafeTag"))
     76     # plc.write("AuthorizedTestTag", 1)  # physical/process impact possible
     77 ```
     78 
     79 ### Packet capture
     80 
     81 Capture both explicit and I/O planes. A connection setup on 44818/TCP followed by high-rate 2222/UDP flows is a quick way to associate an originator with adapters and multicast groups.<sup>[[1]](#references)</sup>
     82 
     83 ```bash
     84 sudo tcpdump -ni eth0 -s0 -w enip.pcap \
     85   'tcp port 44818 or udp port 44818 or udp port 2222'
     86 tshark -r enip.pcap -Y 'enip || cip' -T fields \
     87   -e frame.time -e ip.src -e ip.dst -e enip.command -e cip.service
     88 ```
     89 
     90 ## Attack primitives
     91 
     92 ### Exposed object and tag operations
     93 
     94 Do not equate a successful `ListIdentity` response with write access. After fingerprinting the product and revision, test progressively: standard Identity/TCP-IP object reads, rack-slot identity, tag metadata, individual tag reads, and only then an explicitly authorized sacrificial write. Whether a service is accepted depends on the target object, controller mode, tag `external_access`, vendor implementation, and whether CIP Security or another access-control layer is actually enforced.<sup>[[1]](#references)[[3]](#references)[[4]](#references)</sup>
     95 
     96 ### `Forward_Open` connection exhaustion
     97 
     98 Connected CIP requires the target and intermediate routing devices to reserve resources. Research presented at ACSAC 2024 showed that repeatedly issuing `Forward_Open` with changing originator serial values could allocate many distinct connections inside one TCP stream. On the tested ControlLogix 1756-EN4T setup, roughly 32–128 outstanding connections were enough to prevent legitimate connections; this threshold and recovery behavior are implementation-dependent. This is a disruptive availability test, not routine enumeration.<sup>[[4]](#references)</sup>
     99 
    100 Useful evidence during an authorized resilience test includes the number of accepted `Forward_Open` replies, unique originator/connection identifiers, `Forward_Close` balance, module resource/error counters, controller state, and the point at which a known-good client fails. Defensively, alert on bursts of connection opens, rapidly changing originator identities, or sustained opens without matching closes; restrict 44818/2222 reachability and validate that protected CIP transport and authentication are actually required rather than merely supported.<sup>[[4]](#references)</sup>
    101 
    102 ## Shodan
    103 
    104 `port:44818 "product name"`
    105 
    106 ## References
    107 
    108 - [1] [ODVA - EtherNet/IP Developers Guide](https://www.odva.org/wp-content/uploads/2020/05/PUB00213R0_EtherNetIP_Developers_Guide.pdf)
    109 - [2] [Nmap NSE documentation - `enip-info`](https://nmap.org/nsedoc/scripts/enip-info.html)
    110 - [3] [`pycomm3` documentation](https://pycomm3.readthedocs.io/en/latest/)
    111 - [4] [Gebhard and Perouli - Attacks on EtherNet/IP and Migrations through CIP Security (ACSAC 2024)](https://www.acsac.org/2024/workshops/icss/Alex-Gebhard-Attacks-on-EtherNetIP-and-Migrations-through-CIP-Security.pdf)