]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #2692 in SNORT/snort3 from ~MDAGON/snort3:nhi_alert to master
authorMike Stepanek (mstepane) <mstepane@cisco.com>
Mon, 11 Jan 2021 13:38:56 +0000 (13:38 +0000)
committerMike Stepanek (mstepane) <mstepane@cisco.com>
Mon, 11 Jan 2021 13:38:56 +0000 (13:38 +0000)
Squashed commit of the following:

commit 45db5f4a4e9eadc2ddb6565824ed3407063b4307
Author: mdagon <mdagon@cisco.com>
Date:   Tue Dec 22 15:44:07 2020 -0500

    http_inspect: alert on truncated chunked and content-length message bodies

src/service_inspectors/http_inspect/http_enum.h
src/service_inspectors/http_inspect/http_stream_splitter_finish.cc
src/service_inspectors/http_inspect/http_tables.cc

index 7be0f0f7a49f701466d9b6e2b334416629a4aa7e..cae4b20c72c4d6a8d6f9645a8d6b7ea8225d4565 100755 (executable)
@@ -244,6 +244,8 @@ enum Infraction
     INF_EARLY_CONNECT_RESPONSE,
     INF_MALFORMED_CD_FILENAME,
     INF_HTTP2_IN_HI,
+    INF_TRUNCATED_MSG_BODY_CL,
+    INF_TRUNCATED_MSG_BODY_CHUNK,
     INF__MAX_VALUE
 };
 
@@ -372,6 +374,8 @@ enum EventSid
     EVENT_100_CONNECT_RESP,
     EVENT_EARLY_CONNECT_RESPONSE,          // 258
     EVENT_MALFORMED_CD_FILENAME,
+    EVENT_TRUNCATED_MSG_BODY_CL,
+    EVENT_TRUNCATED_MSG_BODY_CHUNK,
     EVENT__MAX_VALUE
 };
 
index 0cd6adff997af90c11322f88070bcfe2f6f5bfe2..a67bfcd350ef696b5ede17a5251ba771bb27af41 100644 (file)
@@ -42,7 +42,7 @@ bool HttpStreamSplitter::finish(Flow* flow)
     Profile profile(HttpModule::get_profile_stats());
 
     HttpFlowData* session_data = HttpInspect::http_get_flow_data(flow);
-    if(!session_data)
+    if (!session_data)
         return false;
 
 #ifdef REG_TEST
@@ -69,14 +69,26 @@ bool HttpStreamSplitter::finish(Flow* flow)
     }
 
     session_data->tcp_close[source_id] = true;
+    if (session_data->section_type[source_id] != SEC__NOT_COMPUTE)
+        return true;
+
+    if (session_data->type_expected[source_id] == SEC_BODY_CL)
+    {
+        *session_data->get_infractions(source_id) += INF_TRUNCATED_MSG_BODY_CL;
+        session_data->events[source_id]->create_event(EVENT_TRUNCATED_MSG_BODY_CL);
+    }
+    else if (session_data->type_expected[source_id] == SEC_BODY_CHUNK)
+    {
+        *session_data->get_infractions(source_id) += INF_TRUNCATED_MSG_BODY_CHUNK;
+        session_data->events[source_id]->create_event(EVENT_TRUNCATED_MSG_BODY_CHUNK);
+    }
 
     // If there is leftover data for which we returned PAF_SEARCH and never flushed, we need to set
     // up to process because it is about to go to reassemble(). But we don't support partial start
     // lines.
-    if ((session_data->section_type[source_id] == SEC__NOT_COMPUTE) &&
-        (session_data->cutter[source_id] != nullptr)                &&
+    if ((session_data->cutter[source_id] != nullptr) &&
         (session_data->cutter[source_id]->get_octets_seen() >
-            session_data->partial_raw_bytes[source_id]))
+        session_data->partial_raw_bytes[source_id]))
     {
         if ((session_data->type_expected[source_id] == SEC_REQUEST) ||
             (session_data->type_expected[source_id] == SEC_STATUS))
@@ -104,8 +116,7 @@ bool HttpStreamSplitter::finish(Flow* flow)
     // process an empty header section to provide an inspection section. Otherwise the start line
     // won't go through detection.
     if ((session_data->type_expected[source_id] == SEC_HEADER)      &&
-        (session_data->cutter[source_id] == nullptr)                &&
-        (session_data->section_type[source_id] == SEC__NOT_COMPUTE))
+        (session_data->cutter[source_id] == nullptr))
     {
         // Set up to process empty header section
         uint32_t not_used;
@@ -114,8 +125,7 @@ bool HttpStreamSplitter::finish(Flow* flow)
     }
 
     // If there is no more data to process we need to wrap up file processing right now
-    if ((session_data->section_type[source_id] == SEC__NOT_COMPUTE) &&
-        (session_data->file_depth_remaining[source_id] > 0)        &&
+    if ((session_data->file_depth_remaining[source_id] > 0)        &&
         (session_data->cutter[source_id] != nullptr)               &&
         (session_data->cutter[source_id]->get_octets_seen() ==
             session_data->partial_raw_bytes[source_id]))
@@ -165,7 +175,7 @@ bool HttpStreamSplitter::finish(Flow* flow)
         return false;
     }
 
-    return session_data->section_type[source_id] != SEC__NOT_COMPUTE;
+    return false;
 }
 
 bool HttpStreamSplitter::init_partial_flush(Flow* flow, uint32_t num_flush)
@@ -178,9 +188,9 @@ bool HttpStreamSplitter::init_partial_flush(Flow* flow, uint32_t num_flush)
     assert(session_data->for_http2 || source_id == SRC_SERVER);
 
     assert((session_data->type_expected[source_id] == SEC_BODY_CL)      ||
-           (session_data->type_expected[source_id] == SEC_BODY_OLD)     ||
-           (session_data->type_expected[source_id] == SEC_BODY_CHUNK)   ||
-           (session_data->type_expected[source_id] == SEC_BODY_H2));
+        (session_data->type_expected[source_id] == SEC_BODY_OLD)     ||
+        (session_data->type_expected[source_id] == SEC_BODY_CHUNK)   ||
+        (session_data->type_expected[source_id] == SEC_BODY_H2));
 
 #ifdef REG_TEST
     if (HttpTestManager::use_test_output(HttpTestManager::IN_HTTP) &&
index 4e45865fbcb0f0a62b11fe6285daedc93e540700..16207e0d6fe56d3943df391437e0b67715fc85cc 100755 (executable)
@@ -404,6 +404,8 @@ const RuleMap HttpModule::http_events[] =
     { EVENT_100_CONNECT_RESP,           "HTTP CONNECT response with 1XX status code" },
     { EVENT_EARLY_CONNECT_RESPONSE,     "HTTP CONNECT response before request message completed" },
     { EVENT_MALFORMED_CD_FILENAME,      "malformed HTTP Content-Disposition filename parameter" },
+    { EVENT_TRUNCATED_MSG_BODY_CL,      "HTTP Content-Length message body was truncated" },
+    { EVENT_TRUNCATED_MSG_BODY_CHUNK,   "HTTP chunked message body was truncated" },
     { 0, nullptr }
 };