From a36718525e08ad0f2a809363001bf105efc5fe1c Mon Sep 17 00:00:00 2001 From: Pavel Odintsov Date: Fri, 13 Dec 2024 15:08:14 +0300 Subject: [PATCH] DoS: explicitly blocked zero length data templates for Netflow v9 as they have no sense DoS: explicitly blocked zero length options templates for Netflow v9 as they have no sense DoS: Added fix for FPE / division by zero in Netflow v9 logic when length of template is zero Reported by Evgeny Shtanov aka Klavishnik --- src/netflow_plugin/netflow_v9_collector.cpp | 30 ++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/src/netflow_plugin/netflow_v9_collector.cpp b/src/netflow_plugin/netflow_v9_collector.cpp index b8bef137..b9833fd5 100644 --- a/src/netflow_plugin/netflow_v9_collector.cpp +++ b/src/netflow_plugin/netflow_v9_collector.cpp @@ -64,7 +64,9 @@ bool process_netflow_v9_options_template(const uint8_t* pkt, size_t flowset_leng std::vector template_records_map; uint32_t total_size = 0; - for (; offset < fast_ntoh(options_nested_header->option_length);) { + uint32_t option_length = fast_ntoh(options_nested_header->option_length); + + for (; offset < option_length;) { records_number++; const netflow9_template_flowset_record_t* tmplr = (const netflow9_template_flowset_record_t*)(zone_address_without_skopes + offset); @@ -92,6 +94,15 @@ bool process_netflow_v9_options_template(const uint8_t* pkt, size_t flowset_leng field_template.type = netflow_template_type_t::Options; field_template.option_scope_length = scopes_total_size; + // Templates with total length which is zero do not make any sense and have to be ignored + // We need templates to decode data blob and decoding zero length value is meaningless + if (field_template.total_length == 0) { + logger << log4cpp::Priority::ERROR + << "Received zero length malformed options Netfow v9 template " << template_id + << " from " << client_addres_in_string_format; + return false; + } + // We need to know when we received it field_template.timestamp = current_inaccurate_time; @@ -183,6 +194,15 @@ bool process_netflow_v9_template(const uint8_t* pkt, // TODO: introduce netflow9_check_rec_len } + // Templates with total length which is zero do not make any sense and have to be ignored + // We need templates to decode data blob and decoding zero length value is meaningless + if (total_size == 0) { + logger << log4cpp::Priority::ERROR + << "Received zero length malformed data Netflow v9 template " << template_id + << " from " << client_addres_in_string_format; + return false; + } + template_t field_template{}; field_template.template_id = template_id; @@ -1473,6 +1493,14 @@ bool process_netflow_v9_data(const uint8_t* pkt, return false; } + // Check that template total length is not zero as we're going to divide by it + if (field_template->total_length == 0) { + logger << log4cpp::Priority::ERROR + << "Zero template length is not valid " + << "client " << client_addres_in_string_format << " source_id: " << source_id; + return false; + } + uint32_t offset = sizeof(*dath); uint32_t num_flowsets = (flowset_length - offset) / field_template->total_length;