mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 06:38:20 +00:00
Modbus: Add support for Encapsulation Interface Transport (FC=2B) requests and responses
This commit is contained in:
parent
f14be0de29
commit
406a406813
14 changed files with 143 additions and 21 deletions
|
@ -315,3 +315,25 @@ event modbus_diagnostics_request%(c: connection, headers: ModbusHeaders, subfunc
|
|||
##
|
||||
## data: The data passed in the diagnostics response.
|
||||
event modbus_diagnostics_response%(c: connection, headers: ModbusHeaders, subfunction: count, data: string%);
|
||||
|
||||
## Generated for a Modbus Encapsulated Interface Transport request.
|
||||
##
|
||||
## c: The connection.
|
||||
##
|
||||
## headers: The headers for the modbus function.
|
||||
##
|
||||
## mei_type: The MEI type for the request.
|
||||
##
|
||||
## data: The MEI type specific data passed in the request.
|
||||
event modbus_encap_interface_transport_request%(c: connection, headers: ModbusHeaders, mei_type: count, data: string%);
|
||||
|
||||
## Generated for a Modbus Encapsulated Interface Transport response.
|
||||
##
|
||||
## c: The connection.
|
||||
##
|
||||
## headers: The headers for the modbus function.
|
||||
##
|
||||
## mei_type: The MEI type for the response.
|
||||
##
|
||||
## data: The MEI type specific data passed in the response.
|
||||
event modbus_encap_interface_transport_response%(c: connection, headers: ModbusHeaders, mei_type: count, data: string%);
|
||||
|
|
|
@ -761,4 +761,31 @@ refine flow ModbusTCP_Flow += {
|
|||
|
||||
return true;
|
||||
%}
|
||||
|
||||
# REQUEST FC=2B
|
||||
function deliver_EncapInterfaceTransportRequest(header: ModbusTCP_TransportHeader, message: EncapInterfaceTransportRequest): bool
|
||||
%{
|
||||
if ( ::modbus_encap_interface_transport_request )
|
||||
{
|
||||
zeek::BifEvent::enqueue_modbus_encap_interface_transport_request(
|
||||
connection()->zeek_analyzer(), connection()->zeek_analyzer()->Conn(),
|
||||
HeaderToVal(header), ${message.mei_type}, to_stringval(${message.data}));
|
||||
}
|
||||
|
||||
return true;
|
||||
%}
|
||||
|
||||
# RESPONSE FC=2B
|
||||
function deliver_EncapInterfaceTransportResponse(header: ModbusTCP_TransportHeader, message: EncapInterfaceTransportResponse): bool
|
||||
%{
|
||||
if ( ::modbus_encap_interface_transport_response )
|
||||
{
|
||||
zeek::BifEvent::enqueue_modbus_encap_interface_transport_response(
|
||||
connection()->zeek_analyzer(), connection()->zeek_analyzer()->Conn(),
|
||||
HeaderToVal(header), ${message.mei_type}, to_stringval(${message.data}));
|
||||
}
|
||||
|
||||
return true;
|
||||
%}
|
||||
|
||||
};
|
||||
|
|
|
@ -56,6 +56,7 @@ enum function_codes {
|
|||
MASK_WRITE_REGISTER_EXCEPTION = 0x96,
|
||||
READ_WRITE_MULTIPLE_REGISTERS_EXCEPTION = 0x97,
|
||||
READ_FIFO_QUEUE_EXCEPTION = 0x98,
|
||||
ENCAP_INTERFACE_TRANSPORT_EXCEPTION = 0xAB,
|
||||
};
|
||||
|
||||
enum diagnostic_subfunctions {
|
||||
|
@ -116,7 +117,7 @@ type ModbusTCP_Request(header: ModbusTCP_TransportHeader) = case header.fc of {
|
|||
MASK_WRITE_REGISTER -> maskWriteRegister: MaskWriteRegisterRequest(header);
|
||||
READ_WRITE_MULTIPLE_REGISTERS -> readWriteMultipleRegisters: ReadWriteMultipleRegistersRequest(header);
|
||||
READ_FIFO_QUEUE -> readFIFOQueue: ReadFIFOQueueRequest(header);
|
||||
#ENCAP_INTERFACE_TRANSPORT
|
||||
ENCAP_INTERFACE_TRANSPORT -> encapInterfaceException: EncapInterfaceTransportRequest(header);
|
||||
|
||||
# All the rest
|
||||
default -> unknown: bytestring &restofdata;
|
||||
|
@ -143,23 +144,25 @@ type ModbusTCP_Response(header: ModbusTCP_TransportHeader) = case header.fc of {
|
|||
MASK_WRITE_REGISTER -> maskWriteRegister: MaskWriteRegisterResponse(header);
|
||||
READ_WRITE_MULTIPLE_REGISTERS -> readWriteMultipleRegisters: ReadWriteMultipleRegistersResponse(header);
|
||||
READ_FIFO_QUEUE -> readFIFOQueue: ReadFIFOQueueResponse(header);
|
||||
ENCAP_INTERFACE_TRANSPORT -> encapInterfaceException: EncapInterfaceTransportResponse(header);
|
||||
|
||||
# Exceptions
|
||||
READ_HOLDING_REGISTERS_EXCEPTION -> readHoldingRegistersException: Exception(header);
|
||||
WRITE_MULTIPLE_REGISTERS_EXCEPTION -> writeMultRegistersException: Exception(header);
|
||||
READ_COILS_EXCEPTION -> readCoilsException: Exception(header);
|
||||
READ_DISCRETE_INPUTS_EXCEPTION -> readDiscreteInputsException: Exception(header);
|
||||
READ_INPUT_REGISTERS_EXCEPTION -> readInputRegistersException: Exception(header);
|
||||
WRITE_SINGLE_COIL_EXCEPTION -> writeCoilException: Exception(header);
|
||||
WRITE_SINGLE_REGISTER_EXCEPTION -> writeSingleRegisterException: Exception(header);
|
||||
READ_EXCEPTION_STATUS_EXCEPTION -> readExceptionStatusException: Exception(header);
|
||||
DIAGNOSTICS_EXCEPTION -> diagnosticsException: Exception(header);
|
||||
WRITE_MULTIPLE_COILS_EXCEPTION -> forceMultipleCoilsException: Exception(header);
|
||||
READ_FILE_RECORD_EXCEPTION -> readGeneralReferenceException: Exception(header);
|
||||
WRITE_FILE_RECORD_EXCEPTION -> writeGeneralReferenceException: Exception(header);
|
||||
MASK_WRITE_REGISTER_EXCEPTION -> maskWriteRegisterException: Exception(header);
|
||||
READ_WRITE_MULTIPLE_REGISTERS_EXCEPTION -> readWriteRegistersException: Exception(header);
|
||||
READ_FIFO_QUEUE_EXCEPTION -> readFIFOQueueException: Exception(header);
|
||||
READ_HOLDING_REGISTERS_EXCEPTION -> readHoldingRegistersException: Exception(header);
|
||||
WRITE_MULTIPLE_REGISTERS_EXCEPTION -> writeMultRegistersException: Exception(header);
|
||||
READ_COILS_EXCEPTION -> readCoilsException: Exception(header);
|
||||
READ_DISCRETE_INPUTS_EXCEPTION -> readDiscreteInputsException: Exception(header);
|
||||
READ_INPUT_REGISTERS_EXCEPTION -> readInputRegistersException: Exception(header);
|
||||
WRITE_SINGLE_COIL_EXCEPTION -> writeCoilException: Exception(header);
|
||||
WRITE_SINGLE_REGISTER_EXCEPTION -> writeSingleRegisterException: Exception(header);
|
||||
READ_EXCEPTION_STATUS_EXCEPTION -> readExceptionStatusException: Exception(header);
|
||||
DIAGNOSTICS_EXCEPTION -> diagnosticsException: Exception(header);
|
||||
WRITE_MULTIPLE_COILS_EXCEPTION -> forceMultipleCoilsException: Exception(header);
|
||||
READ_FILE_RECORD_EXCEPTION -> readGeneralReferenceException: Exception(header);
|
||||
WRITE_FILE_RECORD_EXCEPTION -> writeGeneralReferenceException: Exception(header);
|
||||
MASK_WRITE_REGISTER_EXCEPTION -> maskWriteRegisterException: Exception(header);
|
||||
READ_WRITE_MULTIPLE_REGISTERS_EXCEPTION -> readWriteRegistersException: Exception(header);
|
||||
READ_FIFO_QUEUE_EXCEPTION -> readFIFOQueueException: Exception(header);
|
||||
ENCAP_INTERFACE_TRANSPORT_EXCEPTION -> encapInterfaceTransportException: Exception(header);
|
||||
|
||||
# All the rest
|
||||
default -> unknown: bytestring &restofdata;
|
||||
|
@ -430,3 +433,19 @@ type ReadFIFOQueueResponse(header: ModbusTCP_TransportHeader) = record {
|
|||
} &let {
|
||||
deliver: bool = $context.flow.deliver_ReadFIFOQueueResponse(header, this);
|
||||
} &byteorder=bigendian;
|
||||
|
||||
# REQUEST FC=2B
|
||||
type EncapInterfaceTransportRequest(header: ModbusTCP_TransportHeader) = record {
|
||||
mei_type: uint8;
|
||||
data: bytestring &restofdata;
|
||||
} &let {
|
||||
deliver: bool = $context.flow.deliver_EncapInterfaceTransportRequest(header, this);
|
||||
} &byteorder=bigendian;
|
||||
|
||||
# RESPONSE FC=2B
|
||||
type EncapInterfaceTransportResponse(header: ModbusTCP_TransportHeader) = record {
|
||||
mei_type: uint8;
|
||||
data: bytestring &restofdata;
|
||||
} &let {
|
||||
deliver: bool = $context.flow.deliver_EncapInterfaceTransportResponse(header, this);
|
||||
} &byteorder=bigendian;
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
|
||||
5 of 30 events triggered by trace
|
||||
5 of 32 events triggered by trace
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
|
||||
5 of 30 events triggered by trace
|
||||
5 of 32 events triggered by trace
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
|
||||
#separator \x09
|
||||
#set_separator ,
|
||||
#empty_field (empty)
|
||||
#unset_field -
|
||||
#path conn
|
||||
#open XXXX-XX-XX-XX-XX-XX
|
||||
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig local_resp missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes tunnel_parents
|
||||
#types time string addr port addr port enum string interval count count string bool bool count string count count count count set[string]
|
||||
XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.2.42 54297 192.168.88.100 502 tcp modbus 0.022532 11 18 OTH T T 0 Dd 1 51 1 58 -
|
||||
XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h 192.168.2.42 54298 192.168.88.100 502 tcp modbus 3.019519 11 9 OTH T T 0 Dd 1 51 1 49 -
|
||||
#close XXXX-XX-XX-XX-XX-XX
|
|
@ -1,2 +1,2 @@
|
|||
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
|
||||
20 of 30 events triggered by trace
|
||||
22 of 32 events triggered by trace
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
2 modbus_diagnostics_response, [orig_h=10.0.0.57, orig_p=2578/tcp, resp_h=10.0.0.3, resp_p=502/tcp], [tid=0, pid=0, uid=10, function_code=8], 1, \x00\x00
|
||||
2 modbus_diagnostics_response, [orig_h=10.0.0.57, orig_p=2578/tcp, resp_h=10.0.0.3, resp_p=502/tcp], [tid=0, pid=0, uid=10, function_code=8], 10, \x00\x00
|
||||
1 modbus_diagnostics_response, [orig_h=192.168.66.235, orig_p=2582/tcp, resp_h=166.161.16.230, resp_p=502/tcp], [tid=0, pid=0, uid=1, function_code=8], 0, \x00\x00
|
||||
2 modbus_encap_interface_transport_request, [orig_h=10.0.0.57, orig_p=2579/tcp, resp_h=10.0.0.8, resp_p=502/tcp], [tid=1, pid=0, uid=10, function_code=43], 14, \x03\x01\x00
|
||||
1 modbus_encap_interface_transport_request, [orig_h=192.168.66.235, orig_p=2582/tcp, resp_h=166.161.16.230, resp_p=502/tcp], [tid=0, pid=0, uid=1, function_code=43], 0, \x00\x00\x00
|
||||
4 modbus_exception, [orig_h=10.0.0.57, orig_p=2578/tcp, resp_h=10.0.0.3, resp_p=502/tcp], [tid=0, pid=0, uid=10, function_code=136], 11
|
||||
8 modbus_exception, [orig_h=192.168.66.235, orig_p=2582/tcp, resp_h=166.161.16.230, resp_p=502/tcp], [tid=0, pid=0, uid=1, function_code=129], 2
|
||||
1 modbus_exception, [orig_h=192.168.66.235, orig_p=2582/tcp, resp_h=166.161.16.230, resp_p=502/tcp], [tid=0, pid=0, uid=1, function_code=129], 3
|
||||
|
@ -20,6 +22,7 @@
|
|||
1 modbus_exception, [orig_h=192.168.66.235, orig_p=2582/tcp, resp_h=166.161.16.230, resp_p=502/tcp], [tid=0, pid=0, uid=1, function_code=150], 3
|
||||
1 modbus_exception, [orig_h=192.168.66.235, orig_p=2582/tcp, resp_h=166.161.16.230, resp_p=502/tcp], [tid=0, pid=0, uid=1, function_code=151], 3
|
||||
1 modbus_exception, [orig_h=192.168.66.235, orig_p=2582/tcp, resp_h=166.161.16.230, resp_p=502/tcp], [tid=0, pid=0, uid=1, function_code=152], 3
|
||||
1 modbus_exception, [orig_h=192.168.66.235, orig_p=2582/tcp, resp_h=166.161.16.230, resp_p=502/tcp], [tid=0, pid=0, uid=1, function_code=171], 1
|
||||
4 modbus_message, [orig_h=10.0.0.57, orig_p=2578/tcp, resp_h=10.0.0.3, resp_p=502/tcp], [tid=0, pid=0, uid=10, function_code=136], F
|
||||
2 modbus_message, [orig_h=10.0.0.57, orig_p=2578/tcp, resp_h=10.0.0.3, resp_p=502/tcp], [tid=0, pid=0, uid=10, function_code=17], F
|
||||
2 modbus_message, [orig_h=10.0.0.57, orig_p=2578/tcp, resp_h=10.0.0.3, resp_p=502/tcp], [tid=0, pid=0, uid=10, function_code=17], T
|
||||
|
@ -79643,3 +79646,11 @@
|
|||
1 modbus_write_single_register_response, [orig_h=10.1.1.234, orig_p=51411/tcp, resp_h=10.10.5.85, resp_p=502/tcp], [tid=9776, pid=0, uid=255, function_code=6], 102, 1
|
||||
1 modbus_write_single_register_response, [orig_h=10.1.1.234, orig_p=51411/tcp, resp_h=10.10.5.85, resp_p=502/tcp], [tid=9777, pid=0, uid=255, function_code=6], 500, 80
|
||||
1 modbus_write_single_register_response, [orig_h=10.1.1.234, orig_p=51411/tcp, resp_h=10.10.5.85, resp_p=502/tcp], [tid=9778, pid=0, uid=255, function_code=6], 502, 60
|
||||
1 modbus_encap_interface_transport_request, [orig_h=192.168.2.42, orig_p=54297/tcp, resp_h=192.168.88.100, resp_p=502/tcp], [tid=0, pid=0, uid=0, function_code=43], 14, \x01\x00
|
||||
1 modbus_encap_interface_transport_request, [orig_h=192.168.2.42, orig_p=54298/tcp, resp_h=192.168.88.100, resp_p=502/tcp], [tid=0, pid=0, uid=255, function_code=43], 14, \x01\x00
|
||||
1 modbus_encap_interface_transport_response, [orig_h=192.168.2.42, orig_p=54297/tcp, resp_h=192.168.88.100, resp_p=502/tcp], [tid=0, pid=0, uid=0, function_code=43], 14, \x01\x00M\xb7\x00\x00\x00\x00\x00
|
||||
1 modbus_exception, [orig_h=192.168.2.42, orig_p=54298/tcp, resp_h=192.168.88.100, resp_p=502/tcp], [tid=0, pid=0, uid=255, function_code=171], 4
|
||||
1 modbus_message, [orig_h=192.168.2.42, orig_p=54297/tcp, resp_h=192.168.88.100, resp_p=502/tcp], [tid=0, pid=0, uid=0, function_code=43], F
|
||||
1 modbus_message, [orig_h=192.168.2.42, orig_p=54297/tcp, resp_h=192.168.88.100, resp_p=502/tcp], [tid=0, pid=0, uid=0, function_code=43], T
|
||||
1 modbus_message, [orig_h=192.168.2.42, orig_p=54298/tcp, resp_h=192.168.88.100, resp_p=502/tcp], [tid=0, pid=0, uid=255, function_code=171], F
|
||||
1 modbus_message, [orig_h=192.168.2.42, orig_p=54298/tcp, resp_h=192.168.88.100, resp_p=502/tcp], [tid=0, pid=0, uid=255, function_code=43], T
|
||||
|
|
|
@ -9,3 +9,13 @@
|
|||
#types time string addr port addr port string string bool string string
|
||||
XXXXXXXXXX.XXXXXX - - - - - modbus_diag_unknown_request_subfunction 0 F zeek -
|
||||
#close XXXX-XX-XX-XX-XX-XX
|
||||
#separator \x09
|
||||
#set_separator ,
|
||||
#empty_field (empty)
|
||||
#unset_field -
|
||||
#path weird
|
||||
#open XXXX-XX-XX-XX-XX-XX
|
||||
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p name addl notice peer source
|
||||
#types time string addr port addr port string string bool string string
|
||||
XXXXXXXXXX.XXXXXX - - - - - modbus_diag_unknown_request_subfunction 0 F zeek -
|
||||
#close XXXX-XX-XX-XX-XX-XX
|
|
@ -123,6 +123,7 @@ XXXXXXXXXX.XXXXXX C37jN32gN3y3AZzyf6 192.168.66.235 2582 166.161.16.230 502 0 1
|
|||
XXXXXXXXXX.XXXXXX C37jN32gN3y3AZzyf6 192.168.66.235 2582 166.161.16.230 502 0 1 unknown-42 RESP -
|
||||
XXXXXXXXXX.XXXXXX C37jN32gN3y3AZzyf6 192.168.66.235 2582 166.161.16.230 502 0 1 ENCAP_INTERFACE_TRANSPORT REQ -
|
||||
XXXXXXXXXX.XXXXXX C37jN32gN3y3AZzyf6 192.168.66.235 2582 166.161.16.230 502 0 1 unknown-171 RESP -
|
||||
XXXXXXXXXX.XXXXXX C37jN32gN3y3AZzyf6 192.168.66.235 2582 166.161.16.230 502 0 1 unknown-171 RESP ILLEGAL_FUNCTION
|
||||
XXXXXXXXXX.XXXXXX C37jN32gN3y3AZzyf6 192.168.66.235 2582 166.161.16.230 502 0 1 unknown-44 REQ -
|
||||
XXXXXXXXXX.XXXXXX C37jN32gN3y3AZzyf6 192.168.66.235 2582 166.161.16.230 502 0 1 unknown-172 RESP -
|
||||
XXXXXXXXXX.XXXXXX C37jN32gN3y3AZzyf6 192.168.66.235 2582 166.161.16.230 502 0 1 unknown-45 REQ -
|
||||
|
|
|
@ -3,3 +3,7 @@ These are the trace files that are used by the Zeek test suite.
|
|||
Note to maintainers: please take care when modifying/removing files from here.
|
||||
We install these traces with the Zeek distribution and external packages might
|
||||
depend on them for tests.
|
||||
|
||||
Trace Index/Sources:
|
||||
|
||||
- modbus/modbus-eit.trace: Sourced from https://www.netresec.com/?page=PCAP4SICS, credit to https://cs3sthlm.se/. The packets in this trace were pulled from the 4SICS-GeekLounge-151021.pcap file.
|
BIN
testing/btest/Traces/modbus/modbus-eit.pcap
Normal file
BIN
testing/btest/Traces/modbus/modbus-eit.pcap
Normal file
Binary file not shown.
|
@ -1,12 +1,18 @@
|
|||
#
|
||||
# @TEST-EXEC: zeek -b -r $TRACES/modbus/modbus.trace %INPUT | sort | uniq -c | sed 's/^ *//g' >output
|
||||
# @TEST-EXEC: mv conn.log conn-first.log
|
||||
# @TEST-EXEC: cat weird.log >> weird-combined.log
|
||||
# @TEST-EXEC: zeek -b -r $TRACES/modbus/modbus-eit.pcap %INPUT | sort | uniq -c | sed 's/^ *//g' >>output
|
||||
# @TEST-EXEC: mv conn.log conn-second.log
|
||||
# @TEST-EXEC: cat weird.log >> weird-combined.log
|
||||
# @TEST-EXEC: btest-diff output
|
||||
# @TEST-EXEC: cat output | awk '{print $2}' | grep "^modbus_" | sort | uniq | wc -l >covered
|
||||
# @TEST-EXEC: cat ${DIST}/src/analyzer/protocol/modbus/events.bif | grep "^event modbus_" | wc -l >total
|
||||
# @TEST-EXEC: echo `cat covered` of `cat total` events triggered by trace >coverage
|
||||
# @TEST-EXEC: btest-diff coverage
|
||||
# @TEST-EXEC: btest-diff conn.log
|
||||
# @TEST-EXEC: btest-diff weird.log
|
||||
# @TEST-EXEC: btest-diff conn-first.log
|
||||
# @TEST-EXEC: btest-diff conn-second.log
|
||||
# @TEST-EXEC: btest-diff weird-combined.log
|
||||
|
||||
@load base/protocols/modbus
|
||||
@load base/protocols/conn
|
||||
|
@ -163,3 +169,13 @@ event modbus_diagnostics_response(c: connection, headers: ModbusHeaders, subfunc
|
|||
{
|
||||
print "modbus_diagnostics_response", c$id, headers, subfunction, data;
|
||||
}
|
||||
|
||||
event modbus_encap_interface_transport_request(c: connection, headers: ModbusHeaders, mei_type: count, data: string)
|
||||
{
|
||||
print "modbus_encap_interface_transport_request", c$id, headers, mei_type, data;
|
||||
}
|
||||
|
||||
event modbus_encap_interface_transport_response(c: connection, headers: ModbusHeaders, mei_type: count, data: string)
|
||||
{
|
||||
print "modbus_encap_interface_transport_response", c$id, headers, mei_type, data;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue