Remove byte count parameter from modbus events carrying register arrays

Instead of these events being generated for invalid byte count values
(they should always be even, not odd), a protocol_violation is raised.

    modbus_read_holding_registers_response
    modbus_read_input_registers_response
    modbus_write_multiple_registers_request
    modbus_read_write_multiple_registers_request
    modbus_read_write_multiple_registers_response
    modbus_read_fifo_queue_respons
This commit is contained in:
Jon Siwek 2012-11-13 12:09:14 -06:00
parent c911d03c30
commit fd5eb23fa6
6 changed files with 64 additions and 38 deletions

View file

@ -60,7 +60,7 @@ event modbus_read_holding_registers_request(c: connection, headers: ModbusHeader
c$modbus$track_address = start_address+1;
}
event modbus_read_holding_registers_response(c: connection, headers: ModbusHeaders, byte_count: count, registers: ModbusRegisters)
event modbus_read_holding_registers_response(c: connection, headers: ModbusHeaders, registers: ModbusRegisters)
{
local slave = c$id$resp_h;

View file

@ -6623,10 +6623,8 @@ event modbus_read_holding_registers_request%(c: connection, headers: ModbusHeade
##
## headers: The headers for the modbus function.
##
## byte_count: The number of bytes in the message that comprise register values.
##
## registers: The register values returned from the device.
event modbus_read_holding_registers_response%(c: connection, headers: ModbusHeaders, byte_count: count, registers: ModbusRegisters%);
event modbus_read_holding_registers_response%(c: connection, headers: ModbusHeaders, registers: ModbusRegisters%);
## Generated for a Modbus read input registers request.
##
@ -6645,10 +6643,8 @@ event modbus_read_input_registers_request%(c: connection, headers: ModbusHeaders
##
## headers: The headers for the modbus function.
##
## byte_count: The number of bytes in the message that comprise register values.
##
## registers: The register values returned from the device.
event modbus_read_input_registers_response%(c: connection, headers: ModbusHeaders, byte_count: count, registers: ModbusRegisters%);
event modbus_read_input_registers_response%(c: connection, headers: ModbusHeaders, registers: ModbusRegisters%);
## Generated for a Modbus write single coil request.
##
@ -6724,10 +6720,8 @@ event modbus_write_multiple_coils_response%(c: connection, headers: ModbusHeader
##
## start_address: The memory address of the first register to be written.
##
## byte_count: The number of bytes in the message that comprise register values.
##
## registers: The values to be written to the registers.
event modbus_write_multiple_registers_request%(c: connection, headers: ModbusHeaders, start_address: count, byte_count: count, registers: ModbusRegisters%);
event modbus_write_multiple_registers_request%(c: connection, headers: ModbusHeaders, start_address: count, registers: ModbusRegisters%);
## Generated for a Modbus write multiple registers response.
##
@ -6818,10 +6812,8 @@ event modbus_mask_write_register_response%(c: connection, headers: ModbusHeaders
##
## write_start_address: The memory address of the first register to be written.
##
## write_byte_count: Number of bytes in message that comprise register values.
##
## write_registers: The values to be written to the registers.
event modbus_read_write_multiple_registers_request%(c: connection, headers: ModbusHeaders, read_start_address: count, read_quantity: count, write_start_address: count, write_byte_count: count, write_registers: ModbusRegisters%);
event modbus_read_write_multiple_registers_request%(c: connection, headers: ModbusHeaders, read_start_address: count, read_quantity: count, write_start_address: count, write_registers: ModbusRegisters%);
## Generated for a Modbus read/write multiple registers response.
##
@ -6829,10 +6821,8 @@ event modbus_read_write_multiple_registers_request%(c: connection, headers: Modb
##
## headers: The headers for the modbus function.
##
## byte_count: The number of bytes in the message that comprise register values.
##
## written_registers: The register values read from the registers specified in the request.
event modbus_read_write_multiple_registers_response%(c: connection, headers: ModbusHeaders, byte_count: count, written_registers: ModbusRegisters%);
event modbus_read_write_multiple_registers_response%(c: connection, headers: ModbusHeaders, written_registers: ModbusRegisters%);
## Generated for a Modbus read FIFO queue request.
##
@ -6849,10 +6839,8 @@ event modbus_read_fifo_queue_request%(c: connection, headers: ModbusHeaders, sta
##
## headers: The headers for the modbus function.
##
## byte_count: The number of bytes in the message that comprise register values.
##
## fifos: The register values read from the FIFO queue on the device.
event modbus_read_fifo_queue_response%(c: connection, headers: ModbusHeaders, byte_count: count, fifos: ModbusRegisters%);
event modbus_read_fifo_queue_response%(c: connection, headers: ModbusHeaders, fifos: ModbusRegisters%);
## Raised for informational messages reported via Bro's reporter framework. Such
## messages may be generated internally by the event engine and also by other

View file

@ -135,8 +135,16 @@ refine flow ModbusTCP_Flow += {
# RESPONSE FC=3
function deliver_ReadHoldingRegistersResponse(header: ModbusTCP_TransportHeader, message: ReadHoldingRegistersResponse): bool
%{
if ( ${message.byte_count} % 2 != 0 )
{
connection()->bro_analyzer()->ProtocolViolation(
fmt("invalid value for modbus read holding register response byte count %d", ${message.byte_count}));
return false;
}
if ( ::modbus_read_holding_registers_response )
{
VectorVal* t = new VectorVal(BifType::Vector::ModbusRegisters);
for ( unsigned int i=0; i < ${message.registers}->size(); ++i )
{
@ -147,7 +155,6 @@ refine flow ModbusTCP_Flow += {
BifEvent::generate_modbus_read_holding_registers_response(connection()->bro_analyzer(),
connection()->bro_analyzer()->Conn(),
HeaderToBro(header),
${message.byte_count},
t);
}
@ -172,6 +179,13 @@ refine flow ModbusTCP_Flow += {
# RESPONSE FC=4
function deliver_ReadInputRegistersResponse(header: ModbusTCP_TransportHeader, message: ReadInputRegistersResponse): bool
%{
if ( ${message.byte_count} % 2 != 0 )
{
connection()->bro_analyzer()->ProtocolViolation(
fmt("invalid value for modbus read input register response byte count %d", ${message.byte_count}));
return false;
}
if ( ::modbus_read_input_registers_response )
{
VectorVal* t = new VectorVal(BifType::Vector::ModbusRegisters);
@ -184,7 +198,6 @@ refine flow ModbusTCP_Flow += {
BifEvent::generate_modbus_read_input_registers_response(connection()->bro_analyzer(),
connection()->bro_analyzer()->Conn(),
HeaderToBro(header),
${message.byte_count},
t);
}
@ -309,6 +322,13 @@ refine flow ModbusTCP_Flow += {
# REQUEST FC=16
function deliver_WriteMultipleRegistersRequest(header: ModbusTCP_TransportHeader, message: WriteMultipleRegistersRequest): bool
%{
if ( ${message.byte_count} % 2 != 0 )
{
connection()->bro_analyzer()->ProtocolViolation(
fmt("invalid value for modbus write multiple registers request byte count %d", ${message.byte_count}));
return false;
}
if ( ::modbus_write_multiple_registers_request )
{
VectorVal * t = new VectorVal(BifType::Vector::ModbusRegisters);
@ -321,7 +341,7 @@ refine flow ModbusTCP_Flow += {
BifEvent::generate_modbus_write_multiple_registers_request(connection()->bro_analyzer(),
connection()->bro_analyzer()->Conn(),
HeaderToBro(header),
${message.start_address}, ${message.byte_count}, t);
${message.start_address}, t);
}
return true;
@ -486,6 +506,13 @@ refine flow ModbusTCP_Flow += {
# REQUEST FC=23
function deliver_ReadWriteMultipleRegistersRequest(header: ModbusTCP_TransportHeader, message: ReadWriteMultipleRegistersRequest): bool
%{
if ( ${message.write_byte_count} % 2 != 0 )
{
connection()->bro_analyzer()->ProtocolViolation(
fmt("invalid value for modbus read write multiple registers request write byte count %d", ${message.write_byte_count}));
return false;
}
if ( ::modbus_read_write_multiple_registers_request )
{
VectorVal* t = new VectorVal(BifType::Vector::ModbusRegisters);
@ -501,7 +528,6 @@ refine flow ModbusTCP_Flow += {
${message.read_start_address},
${message.read_quantity},
${message.write_start_address},
${message.write_byte_count},
t);
}
@ -511,6 +537,13 @@ refine flow ModbusTCP_Flow += {
# RESPONSE FC=23
function deliver_ReadWriteMultipleRegistersResponse(header: ModbusTCP_TransportHeader, message: ReadWriteMultipleRegistersResponse): bool
%{
if ( ${message.byte_count} % 2 != 0 )
{
connection()->bro_analyzer()->ProtocolViolation(
fmt("invalid value for modbus read write multiple registers response byte count %d", ${message.byte_count}));
return false;
}
if ( ::modbus_read_write_multiple_registers_response )
{
VectorVal* t = new VectorVal(BifType::Vector::ModbusRegisters);
@ -523,7 +556,6 @@ refine flow ModbusTCP_Flow += {
BifEvent::generate_modbus_read_write_multiple_registers_response(connection()->bro_analyzer(),
connection()->bro_analyzer()->Conn(),
HeaderToBro(header),
${message.byte_count},
t);
}
@ -548,6 +580,13 @@ refine flow ModbusTCP_Flow += {
# RESPONSE FC=24
function deliver_ReadFIFOQueueResponse(header: ModbusTCP_TransportHeader, message: ReadFIFOQueueResponse): bool
%{
if ( ${message.byte_count} % 2 != 0 )
{
connection()->bro_analyzer()->ProtocolViolation(
fmt("invalid value for modbus read FIFO queue response byte count %d", ${message.byte_count}));
return false;
}
if ( ::modbus_read_fifo_queue_response )
{
VectorVal* t = new VectorVal(new VectorType(base_type(TYPE_COUNT)));
@ -560,7 +599,6 @@ refine flow ModbusTCP_Flow += {
BifEvent::generate_modbus_read_fifo_queue_response(connection()->bro_analyzer(),
connection()->bro_analyzer()->Conn(),
HeaderToBro(header),
${message.byte_count},
t);
}

View file

@ -1,5 +1,4 @@
modbus_read_input_registers_request, [orig_h=10.1.1.234, orig_p=51411/tcp, resp_h=10.10.5.104, resp_p=502/tcp], [tid=1119, pid=0, uid=255, function_code=4], 900, 147
modbus_read_input_registers_response, [orig_h=10.1.1.234, orig_p=51411/tcp, resp_h=10.10.5.104, resp_p=502/tcp], [tid=2606, pid=0, uid=255, function_code=4], [0, 0, 0, 0, 0, 0, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690], 100, 200
modbus_read_input_registers_response, [orig_h=10.1.1.234, orig_p=51411/tcp, resp_h=10.10.5.104, resp_p=502/tcp], [tid=6714, pid=0, uid=255, function_code=4], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3840, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 64, 129
modbus_read_input_registers_response, [orig_h=10.1.1.234, orig_p=51411/tcp, resp_h=10.10.5.104, resp_p=502/tcp], [tid=2606, pid=0, uid=255, function_code=4], [0, 0, 0, 0, 0, 0, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690], 100
modbus_read_input_registers_request, [orig_h=10.1.1.234, orig_p=51411/tcp, resp_h=10.10.5.104, resp_p=502/tcp], [tid=12993, pid=0, uid=255, function_code=4], 400, 100
modbus_read_input_registers_response, [orig_h=10.1.1.234, orig_p=51411/tcp, resp_h=10.10.5.104, resp_p=502/tcp], [tid=17667, pid=0, uid=255, function_code=4], [49, 18012, 51, 42, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 49, 50, 51, 54324, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 69, 63, 64, 65, 66, 67, 68, 49, 189, 51, 52, 53, 54, 4151, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 136, 49, 50, 51, 212, 53, 54, 170, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690], 100, 200
modbus_read_input_registers_response, [orig_h=10.1.1.234, orig_p=51411/tcp, resp_h=10.10.5.104, resp_p=502/tcp], [tid=17667, pid=0, uid=255, function_code=4], [49, 18012, 51, 42, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 49, 50, 51, 54324, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 69, 63, 64, 65, 66, 67, 68, 49, 189, 51, 52, 53, 54, 4151, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 136, 49, 50, 51, 212, 53, 54, 170, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690, 43690], 100

View file

@ -41,7 +41,7 @@ event modbus_read_holding_registers_request(c: connection, headers: ModbusHeader
print "modbus_read_holding_registers_request", c, headers, start_address, quantity;
}
event modbus_read_holding_registers_response(c: connection, headers: ModbusHeaders, byte_count: count, registers: ModbusRegisters)
event modbus_read_holding_registers_response(c: connection, headers: ModbusHeaders, registers: ModbusRegisters)
{
print "modbus_read_holding_registers_response", c, headers, registers;
}
@ -51,7 +51,7 @@ event modbus_read_input_registers_request(c: connection, headers: ModbusHeaders,
print "modbus_read_input_registers_request", c, headers, start_address, quantity;
}
event modbus_read_input_registers_response(c: connection, headers: ModbusHeaders, byte_count: count, registers: ModbusRegisters)
event modbus_read_input_registers_response(c: connection, headers: ModbusHeaders, registers: ModbusRegisters)
{
print "modbus_read_input_registers_response", c, headers, registers;
}
@ -86,7 +86,7 @@ event modbus_write_multiple_coils_response(c: connection, headers: ModbusHeaders
print "modbus_write_multiple_coils_response", c, headers, start_address, quantity;
}
event modbus_write_multiple_registers_request(c: connection, headers: ModbusHeaders, start_address: count, byte_count: count, registers: ModbusRegisters)
event modbus_write_multiple_registers_request(c: connection, headers: ModbusHeaders, start_address: count, registers: ModbusRegisters)
{
print "modbus_write_multiple_registers_request", c, headers, start_address, registers;
}
@ -126,12 +126,12 @@ event modbus_mask_write_register_response(c: connection, headers: ModbusHeaders,
print "modbus_mask_write_register_response", c, headers, address, and_mask, or_mask;
}
event modbus_read_write_multiple_registers_request(c: connection, headers: ModbusHeaders, read_start_address: count, read_quantity: count, write_start_address: count, write_byte_count: count, write_registers: ModbusRegisters)
event modbus_read_write_multiple_registers_request(c: connection, headers: ModbusHeaders, read_start_address: count, read_quantity: count, write_start_address: count, write_registers: ModbusRegisters)
{
print "modbus_read_write_multiple_registers_request", c, headers, read_start_address, read_quantity, write_start_address, write_registers;
}
event modbus_read_write_multiple_registers_response(c: connection, headers: ModbusHeaders, byte_count: count, written_registers: ModbusRegisters)
event modbus_read_write_multiple_registers_response(c: connection, headers: ModbusHeaders, written_registers: ModbusRegisters)
{
print "modbus_read_write_multiple_registers_response", c, headers, written_registers;
}
@ -141,7 +141,7 @@ event modbus_read_fifo_queue_request(c: connection, headers: ModbusHeaders, star
print "modbus_read_fifo_queue_request", c, headers, start_address;
}
event modbus_read_fifo_queue_response(c: connection, headers: ModbusHeaders, byte_count: count, fifos: ModbusRegisters)
event modbus_read_fifo_queue_response(c: connection, headers: ModbusHeaders, fifos: ModbusRegisters)
{
print "modbus_read_fifo_queue_response", c, headers, fifos;
}

View file

@ -6,15 +6,16 @@
# of register values, with the quantity being derived from a byte count value
# that is also sent. If the byte count value is invalid (e.g. an odd value
# might not be valid since registers must be 2-byte values), then the parser
# should not trigger any asserts, but the resulting event could indicate
# the strangeness (i.e. byte_count != 2*|registers|).
# should not trigger any asserts, but generate a protocol_violation (in this
# case TCP_ApplicationAnalyzer::ProtocolViolation asserts its behavior for
# incomplete connections).
event modbus_read_input_registers_request(c: connection, headers: ModbusHeaders, start_address: count, quantity: count)
{
print "modbus_read_input_registers_request", c$id, headers, start_address, quantity;
}
event modbus_read_input_registers_response(c: connection, headers: ModbusHeaders, byte_count: count, registers: ModbusRegisters)
event modbus_read_input_registers_response(c: connection, headers: ModbusHeaders, registers: ModbusRegisters)
{
print "modbus_read_input_registers_response", c$id, headers, registers, |registers|, byte_count;
print "modbus_read_input_registers_response", c$id, headers, registers, |registers|;
}