Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Packet Correlation ID #30

Merged
merged 4 commits into from
Sep 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 21 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,23 +96,24 @@ This log captures Ethernet/IP header information for every Ethernet/IP packet an

#### Fields Captured

| Field | Type | Description |
| ----------------- |-----------|-------------------------------------------------------------- |
| ts | time | Timestamp |
| uid | string | Unique ID for this connection |
| id | conn_id | Default Zeek connection info (IP addresses, ports) |
| is_orig | bool | True if the packet is sent from the originator |
| source_h | address | Source IP address (see *Source and Destination Fields*) |
| source_p | port | Source port (see *Source and Destination Fields*) |
| destination_h | address | Destination IP address (see *Source and Destination Fields*) |
| destination_p | port | Destination port (see *Source and Destination Fields*) |
| enip_command_code | string | Ethernet/IP command code |
| enip_command | string | Ethernet/IP command name |
| length | count | Length of ENIP data following header |
| session_handle | string | Session identifier |
| enip_status | string | Ethernet/IP status code |
| sender_context | string | Sender context |
| options | string | Options flags |
| Field | Type | Description |
| ----------------------|-----------|-------------------------------------------------------------- |
| ts | time | Timestamp |
| uid | string | Unique ID for this connection |
| id | conn_id | Default Zeek connection info (IP addresses, ports) |
| is_orig | bool | True if the packet is sent from the originator |
| source_h | address | Source IP address (see *Source and Destination Fields*) |
| source_p | port | Source port (see *Source and Destination Fields*) |
| destination_h | address | Destination IP address (see *Source and Destination Fields*) |
| destination_p | port | Destination port (see *Source and Destination Fields*) |
| packet_correlation_id | string | Ties ENIP headers to associated CIP packets |
| enip_command_code | string | Ethernet/IP command code |
| enip_command | string | Ethernet/IP command name |
| length | count | Length of ENIP data following header |
| session_handle | string | Session identifier |
| enip_status | string | Ethernet/IP status code |
| sender_context | string | Sender context |
| options | string | Options flags |

### CIP Header Log (cip.log)

Expand All @@ -132,6 +133,7 @@ This log captures CIP header information for every CIP packet and logs it to **c
| source_p | port | Source port (see *Source and Destination Fields*) |
| destination_h | address | Destination IP address (see *Source and Destination Fields*) |
| destination_p | port | Destination port (see *Source and Destination Fields*) |
| packet_correlation_id | string | Ties ENIP headers to associated CIP packets |
| cip_sequence_count | count | CIP sequence number |
| direction | string | Request or response |
| cip_service_code | string | CIP service code |
Expand Down Expand Up @@ -163,6 +165,7 @@ This log captures CIP I/O (input-output) data for every CIP IO packet and logs i
| source_p | port | Source port (see *Source and Destination Fields*) |
| destination_h | address | Destination IP address (see *Source and Destination Fields*) |
| destination_p | port | Destination port (see *Source and Destination Fields*) |
| packet_correlation_id | string | Ties ENIP headers to associated CIP packets |
| connection_id | string | Connection identifier |
| sequence_number | count | Sequence number within connection |
| data_length | count | Length of data in io_data field |
Expand All @@ -186,6 +189,7 @@ This log captures important variables for CIP_Identity objects and logs them to
| source_p | port | Source Port (see *Source and Destination Fields*) |
| destination_h | address | Destination IP address (see *Source and Destination Fields*) |
| destination_p | port | Destination Port (see *Source and Destination Fields*) |
| packet_correlation_id | string | Ties ENIP headers to associated CIP packets |
| encapsulation_version | count | Encapsulation protocol version supported |
| socket_address | addr | Socket address IP address |
| socket_port | count | Socket address port number |
Expand Down
13 changes: 13 additions & 0 deletions scripts/icsnpp/enip/main.zeek
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export{
source_p : port &log; # Source Port
destination_h : addr &log; # Destination IP Address
destination_p : port &log; # Destination Port
packet_correlation_id : string &log; # A correlation ID that ties ENIP headers to associated CIP packets (packet rather than connection based)
enip_command_code : string &log; # Ethernet/IP Command Code (in hex)
enip_command : string &log; # Ethernet/IP Command Name (see enip_commands)
length : count &log; # Length of ENIP data following header
Expand All @@ -51,6 +52,7 @@ export{
source_p : port &log; # Source Port
destination_h : addr &log; # Destination IP Address
destination_p : port &log; # Destination Port
packet_correlation_id : string &log; # A correlation ID that ties ENIP headers to associated CIP packets (packet rather than connection based)
cip_sequence_count : count &log; # CIP sequence number for transport
direction : string &log; # Request or Response
cip_service_code : string &log; # CIP service code (in hex)
Expand Down Expand Up @@ -79,6 +81,7 @@ export{
source_p : port &log; # Source Port
destination_h : addr &log; # Destination IP Address
destination_p : port &log; # Destination Port
packet_correlation_id : string &log; # A correlation ID that ties ENIP headers to associated CIP packets (packet rather than connection based)
connection_id : string &log; # CIP Connection Identifier
sequence_number : count &log; # CIP Sequence Number with Connection
data_length : count &log; # Length of io_data field
Expand All @@ -99,6 +102,7 @@ export{
source_p : port &log; # Source Port
destination_h : addr &log; # Destination IP Address
destination_p : port &log; # Destination Port
packet_correlation_id : string &log; # A correlation ID that ties ENIP headers to associated CIP packets (packet rather than connection based)
encapsulation_version : count &log; # Encapsulation protocol version supported
socket_address : addr &log; # Socket address IP address
socket_port : count &log; # Socket address port number
Expand Down Expand Up @@ -183,6 +187,7 @@ function set_service(c: connection, service: string) {
###################################################################################################
event enip_header(c: connection,
is_orig: bool,
packet_correlation_id: string,
command: count,
length: count,
session_handle: count,
Expand Down Expand Up @@ -211,6 +216,7 @@ event enip_header(c: connection,
enip_item$destination_p = c$id$orig_p;
}

enip_item$packet_correlation_id = packet_correlation_id;
enip_item$enip_command_code = fmt("0x%02x",command);
enip_item$enip_command = enip_commands[command];
enip_item$length = length;
Expand All @@ -227,6 +233,7 @@ event enip_header(c: connection,
###################################################################################################
event cip_header(c: connection,
is_orig: bool,
packet_correlation_id: string,
cip_sequence_count: count,
service: count,
response: bool,
Expand Down Expand Up @@ -260,6 +267,7 @@ event cip_header(c: connection,
if (cip_sequence_count != 0)
cip_header_item$cip_sequence_count = cip_sequence_count;

cip_header_item$packet_correlation_id = packet_correlation_id;
cip_header_item$cip_service_code = fmt("0x%02x",service);
cip_header_item$cip_service = cip_services[service];

Expand Down Expand Up @@ -302,6 +310,7 @@ event cip_header(c: connection,
###################################################################################################
event cip_io(c: connection,
is_orig: bool,
packet_correlation_id: string,
connection_identifier: count,
sequence_number: count,
data_length: count,
Expand All @@ -328,6 +337,7 @@ event cip_io(c: connection,
cip_io_item$destination_p = c$id$orig_p;
}

cip_io_item$packet_correlation_id = packet_correlation_id;
cip_io_item$connection_id = fmt("0x%08x", connection_identifier);;
cip_io_item$sequence_number = sequence_number;
cip_io_item$data_length = data_length;
Expand All @@ -341,6 +351,7 @@ event cip_io(c: connection,
###################################################################################################
event cip_identity(c: connection,
is_orig: bool,
packet_correlation_id: string,
encapsulation_version: count,
socket_address: count,
socket_port: count,
Expand Down Expand Up @@ -375,6 +386,8 @@ event cip_identity(c: connection,
cip_identity_item$destination_p = c$id$orig_p;
}

cip_identity_item$packet_correlation_id = packet_correlation_id;

cip_identity_item$encapsulation_version = encapsulation_version;
cip_identity_item$socket_address = count_to_v4_addr(socket_address);
cip_identity_item$socket_port = socket_port;
Expand Down
13 changes: 12 additions & 1 deletion src/enip-analyzer.pac
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
##
## Copyright (c) 2023 Battelle Energy Alliance, LLC. All rights reserved.

%extern{
#include <sstream>
#include <random>
%}
%header{

typedef struct CIP_Request_Path {
Expand All @@ -25,7 +29,6 @@
uint32 get_number(uint8 size, uint8 x, const_bytestring data);
CIP_Request_Path parse_request_path(const_bytestring data);
CIP_Request_Path parse_request_multiple_service_packet(const_bytestring data, uint16 starting_location);

%}

%code{
Expand Down Expand Up @@ -157,6 +160,7 @@ refine flow ENIP_Flow += {
zeek::BifEvent::enqueue_enip_header(connection()->zeek_analyzer(),
connection()->zeek_analyzer()->Conn(),
${enip_header.is_originator},
zeek::make_intrusive<zeek::StringVal>(${enip_header.packet_correlation_id}),
${enip_header.command},
${enip_header.length},
${enip_header.session_handle},
Expand Down Expand Up @@ -196,6 +200,7 @@ refine flow ENIP_Flow += {
zeek::BifEvent::enqueue_cip_header(connection()->zeek_analyzer(),
connection()->zeek_analyzer()->Conn(),
${cip_header.is_originator},
zeek::make_intrusive<zeek::StringVal>(${cip_header.packet_correlation_id}),
${cip_header.cip_sequence_count},
${cip_header.service_code},
(${cip_header.request_or_response} == 1),
Expand All @@ -218,6 +223,7 @@ refine flow ENIP_Flow += {
zeek::BifEvent::enqueue_cip_io(connection()->zeek_analyzer(),
connection()->zeek_analyzer()->Conn(),
${cip_io_item.is_originator},
zeek::make_intrusive<zeek::StringVal>(${cip_io_item.packet_correlation_id}),
${cip_io_item.sequenced_address_item.connection_identifier},
${cip_io_item.sequenced_address_item.encap_sequence_number},
${cip_io_item.connected_data_length},
Expand All @@ -236,6 +242,7 @@ refine flow ENIP_Flow += {
zeek::BifEvent::enqueue_cip_identity(connection()->zeek_analyzer(),
connection()->zeek_analyzer()->Conn(),
${identity_item.is_originator},
zeek::make_intrusive<zeek::StringVal>(${identity_item.packet_correlation_id}),
${identity_item.encapsulation_version},
${identity_item.socket_address.sin_addr},
${identity_item.socket_address.sin_port},
Expand Down Expand Up @@ -498,6 +505,7 @@ refine flow ENIP_Flow += {
zeek::BifEvent::enqueue_cip_header(connection()->zeek_analyzer(),
connection()->zeek_analyzer()->Conn(),
${data.is_originator},
zeek::make_intrusive<zeek::StringVal>(${data.packet_correlation_id}),
${data.cip_sequence_count},
MULTIPLE_SERVICE,
false,
Expand All @@ -516,6 +524,7 @@ refine flow ENIP_Flow += {
zeek::BifEvent::enqueue_cip_header(connection()->zeek_analyzer(),
connection()->zeek_analyzer()->Conn(),
${data.is_originator},
zeek::make_intrusive<zeek::StringVal>(${data.packet_correlation_id}),
cip_sequence_count,
${data.services[service_packet_location]} & 0x7f,
false,
Expand Down Expand Up @@ -547,6 +556,7 @@ refine flow ENIP_Flow += {
zeek::BifEvent::enqueue_cip_header(connection()->zeek_analyzer(),
connection()->zeek_analyzer()->Conn(),
${data.is_originator},
zeek::make_intrusive<zeek::StringVal>(${data.packet_correlation_id}),
${data.cip_sequence_count},
MULTIPLE_SERVICE,
true,
Expand All @@ -564,6 +574,7 @@ refine flow ENIP_Flow += {
zeek::BifEvent::enqueue_cip_header(connection()->zeek_analyzer(),
connection()->zeek_analyzer()->Conn(),
${data.is_originator},
zeek::make_intrusive<zeek::StringVal>(${data.packet_correlation_id}),
cip_sequence_count,
${data.services[service_packet_location]} & 0x7f,
true,
Expand Down
Loading