diff --git a/rules/dnp3-events.rules b/rules/dnp3-events.rules index 50b2b95c50..983a5ae5f0 100644 --- a/rules/dnp3-events.rules +++ b/rules/dnp3-events.rules @@ -35,3 +35,8 @@ alert dnp3 any any -> any any (msg:"SURICATA DNP3 Too many objects"; \ app-layer-event:dnp3.too_many_objects; \ threshold:type backoff, track by_flow, count 1, multiplier 10; \ classtype:protocol-command-decode; sid:2270006; rev:1;) + +# Too long reassembly. +alert dnp3 any any -> any any (msg:"SURICATA DNP3 Too long reassembly"; \ + app-layer-event:dnp3.too_long_reassembly; \ + classtype:protocol-command-decode; sid:2270007; rev:1;) diff --git a/src/app-layer-dnp3.c b/src/app-layer-dnp3.c index d541fc5ff3..0bca648677 100644 --- a/src/app-layer-dnp3.c +++ b/src/app-layer-dnp3.c @@ -107,6 +107,7 @@ SCEnumCharMap dnp3_decoder_event_table[] = { { "UNKNOWN_OBJECT", DNP3_DECODER_EVENT_UNKNOWN_OBJECT }, { "TOO_MANY_POINTS", DNP3_DECODER_EVENT_TOO_MANY_POINTS }, { "TOO_MANY_OBJECTS", DNP3_DECODER_EVENT_TOO_MANY_OBJECTS }, + { "TOO_LONG_REASSEMBLY", DNP3_DECODER_EVENT_TOO_LONG_REASS }, { NULL, -1 }, }; @@ -941,6 +942,13 @@ static void DNP3HandleUserDataRequest( tx->done = 1; return; } + // a data link frame has its size on one byte, + // and transport layer has sequence in 0-63 + if (tx->buffer_len > 63 * 0xff) { + DNP3SetEvent(dnp3, DNP3_DECODER_EVENT_TOO_LONG_REASS); + tx->done = 1; + return; + } /* If this is not the final segment, just return. */ if (!DNP3_TH_FIN(th)) { diff --git a/src/app-layer-dnp3.h b/src/app-layer-dnp3.h index ffbd3bece0..cee658c7c5 100644 --- a/src/app-layer-dnp3.h +++ b/src/app-layer-dnp3.h @@ -112,6 +112,7 @@ enum { DNP3_DECODER_EVENT_UNKNOWN_OBJECT, DNP3_DECODER_EVENT_TOO_MANY_POINTS, DNP3_DECODER_EVENT_TOO_MANY_OBJECTS, + DNP3_DECODER_EVENT_TOO_LONG_REASS, }; /**