Vulnerability Description
OpENer suffers from an Incorrect Access Control vulnerability in its handling of encapsulation sessions. When the server processes critical encapsulation commands, it verifies whether the provided session_handle exists in the global session list, but it fails to verify whether that handle belongs to the specific TCP connection issuing the request. Because there is no strong binding between a session handle and its originating socket, any attacker on the network can use a valid session handle created by another legitimate client to bypass access controls. This access control failure leads to severe impacts, including Session Hijacking and Cross-Connection DoS.
Root Cause
The root cause lies in the encapsulation session authentication logic failing to enforce a "handle-to-socket" binding:
- Missing Socket Binding Validation: In
encap.c, the CheckRegisteredSessions() function only checks if the provided session_handle is active. It does not verify if the session is owned by the socket making the current request.
- Reused Authentication Flaw: This inadequate check is used across critical command paths (e.g.,
SendRRData, SendUnitData), allowing an attacker to pass the authentication flow using a victim's handle on an entirely different TCP connection.
- Cross-Connection Unregistration: The
UnregisterSession path closes the session resources based solely on the handle without verifying the request's origin socket. This enables an attacker to remotely terminate any active session.
- Predictable Handles: Session handles are generated as small, predictable integers (e.g.,
index + 1), significantly lowering the attack complexity for enumerating active sessions.
Trigger Conditions
- The target device is running OpENer and listening on the default ENIP TCP port (44818).
- A legitimate client establishes a TCP connection and registers a session (receiving a predictable
session_handle).
- The attacker establishes a separate TCP connection to the ENIP port.
- The attacker sends an encapsulation command (e.g.,
SendRRData or UnregisterSession) carrying the legitimate client's session_handle.
Reproduction (Validated)
PoC.zip
1) Build:
Compile the OpENer project on a POSIX environment (e.g., Ubuntu). Ensure -DOpENer_TRACES:BOOL=ON is enabled to observe the error logs.
cd bin/posix
./setup_posix.sh
make
2) Run target:
Start the OpENer service, listening on the loopback interface:
./src/ports/POSIX/OpENer lo
3) Run Legitimate Client Probe:
In a new terminal, start the normal client to register a session and continuously send ListIdentity keep-alive probes:
(The normal client will successfully connect, receive a session_handle such as 1).
4) Send attack traffic:
In another terminal, execute the attacker script to probe handles, bypass access control, and send a cross-connection UnregisterSession request:
python3 attacker_hijack.py
5) Observe Phenomena:
- Attacker Terminal: The attacker script successfully bypasses access control by enumerating and utilizing the valid
session_handle, and then sends the UnregisterSession command.
- Server Logs: The server processes the forged unregister request, destroying the session and forcefully closing the legitimate client's TCP socket.
- Legitimate Client Terminal: The
normal_client.py probe fails immediately, reporting DISCONNECTED: connection closed/no response because the underlying connection was unilaterally severed by the server.
Impact Assessment
This Incorrect Access Control vulnerability has a High severity impact on both integrity and availability.
- Session Hijacking (Integrity): In Industrial Control Systems, unauthorized access allows an attacker to inject malicious control commands or read sensitive operational data on behalf of a legitimate controller, breaking the integrity of the communication.
- Cross-Connection DoS (Availability): The ability to unilaterally terminate active sessions allows a network attacker to continuously disrupt critical communications between PLCs, HMIs, and the OpENer device, severely degrading operational availability.
Vulnerability Description
OpENer suffers from an Incorrect Access Control vulnerability in its handling of encapsulation sessions. When the server processes critical encapsulation commands, it verifies whether the provided
session_handleexists in the global session list, but it fails to verify whether that handle belongs to the specific TCP connection issuing the request. Because there is no strong binding between a session handle and its originating socket, any attacker on the network can use a valid session handle created by another legitimate client to bypass access controls. This access control failure leads to severe impacts, including Session Hijacking and Cross-Connection DoS.Root Cause
The root cause lies in the encapsulation session authentication logic failing to enforce a "handle-to-socket" binding:
encap.c, theCheckRegisteredSessions()function only checks if the providedsession_handleis active. It does not verify if the session is owned by the socket making the current request.SendRRData,SendUnitData), allowing an attacker to pass the authentication flow using a victim's handle on an entirely different TCP connection.UnregisterSessionpath closes the session resources based solely on the handle without verifying the request's origin socket. This enables an attacker to remotely terminate any active session.index + 1), significantly lowering the attack complexity for enumerating active sessions.Trigger Conditions
session_handle).SendRRDataorUnregisterSession) carrying the legitimate client'ssession_handle.Reproduction (Validated)
PoC.zip
1) Build:
Compile the OpENer project on a POSIX environment (e.g., Ubuntu). Ensure
-DOpENer_TRACES:BOOL=ONis enabled to observe the error logs.cd bin/posix ./setup_posix.sh make2) Run target:
Start the OpENer service, listening on the loopback interface:
3) Run Legitimate Client Probe:
In a new terminal, start the normal client to register a session and continuously send
ListIdentitykeep-alive probes:(The normal client will successfully connect, receive a
session_handlesuch as1).4) Send attack traffic:
In another terminal, execute the attacker script to probe handles, bypass access control, and send a cross-connection
UnregisterSessionrequest:5) Observe Phenomena:
session_handle, and then sends theUnregisterSessioncommand.normal_client.pyprobe fails immediately, reportingDISCONNECTED: connection closed/no responsebecause the underlying connection was unilaterally severed by the server.Impact Assessment
This Incorrect Access Control vulnerability has a High severity impact on both integrity and availability.