]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #1779 in SNORT/snort3 from ~DERAMADA/snort3:h2i_validate_connectio...
authorMike Stepanek (mstepane) <mstepane@cisco.com>
Fri, 4 Oct 2019 18:09:44 +0000 (14:09 -0400)
committerMike Stepanek (mstepane) <mstepane@cisco.com>
Fri, 4 Oct 2019 18:09:44 +0000 (14:09 -0400)
Squashed commit of the following:

commit 7391aa89fb2f7b2c274ec8966c63fa22b2f86b27
Author: deramada <deramada@cisco.com>
Date:   Wed Oct 2 15:29:09 2019 -0400

    http2_inspect: validate connection preface

src/service_inspectors/http2_inspect/http2_enum.h
src/service_inspectors/http2_inspect/http2_inspect.cc
src/service_inspectors/http2_inspect/http2_stream_splitter.h
src/service_inspectors/http2_inspect/http2_stream_splitter_impl.cc
src/service_inspectors/http2_inspect/http2_tables.cc

index 55590f8329fdb1f4cd9f9d1c51d5f4e3ea5f697a..cf02cbe1759caf8b0dd0d9ab789d6042ecc4e84f 100644 (file)
@@ -52,6 +52,7 @@ enum EventSid
     EVENT_STRING_DECODE_FAILURE = 3,
     EVENT_MISSING_CONTINUATION = 4,
     EVENT_UNEXPECTED_CONTINUATION = 5,
+    EVENT_PREFACE_MATCH_FAILURE = 7,
     EVENT__MAX_VALUE
 };
 
index e8b84060e3082196b7766a4d58452ebd08ef1842..e893ff56ebac591dd32f1f059e5a177b33f3ef09 100644 (file)
@@ -113,6 +113,11 @@ void Http2Inspect::eval(Packet* p)
             (int) session_data->frame_data_size[source_id] : HttpCommon::STAT_NOT_PRESENT,
             session_data->frame_data[source_id]).print(HttpTestManager::get_output_file(),
             "Frame Data");
+               if (HttpTestManager::use_test_input(HttpTestManager::IN_HTTP2))
+        {
+            printf("Finished processing section from test %" PRIi64 "\n",
+                HttpTestManager::get_test_number());
+        }
     }
 #endif
 }
index 12bcb137737716ea6c1a76fecd1ae556642d87da..167353e615261721aa9e3076ac826ac5039b276c 100644 (file)
@@ -54,5 +54,10 @@ const snort::StreamBuffer implement_reassemble(Http2FlowData* session_data, unsi
     unsigned offset, const uint8_t* data, unsigned len, uint32_t flags,
     HttpCommon::SourceId source_id);
 
+enum ValidationResult { V_GOOD, V_BAD, V_TBD };
+
+ValidationResult validate_preface(const uint8_t* data, const uint32_t length,
+    const uint32_t octets_seen);
+
 #endif
 
index 91d5efe5d4c9ea64db64a407cd1871dfc135c996..9c31c68b73f2014ae3ae46d70693072430bd2f62 100644 (file)
@@ -45,14 +45,22 @@ StreamSplitter::Status implement_scan(Http2FlowData* session_data, const uint8_t
     if (session_data->preface[source_id])
     {
         // 24-byte preface, not a real frame, no frame header
-        const uint32_t preface_length = 24;
-        if (session_data->octets_seen[source_id] + length < preface_length)
+        // Verify preface is correct, else generate loss of sync event and abort
+        switch (validate_preface(data, length, session_data->octets_seen[source_id]))
         {
-            session_data->octets_seen[source_id] += length;
-            return status = StreamSplitter::SEARCH;
+            case V_GOOD:
+                break;
+            case V_BAD:
+                session_data->events[source_id]->create_event(EVENT_PREFACE_MATCH_FAILURE);
+                // FIXIT-H: Workaround till abort is implemented
+                if((session_data->octets_seen[source_id] + length) >= 24)
+                    break;
+                // Falls through
+            case V_TBD:
+                session_data->octets_seen[source_id] += length;
+                return StreamSplitter::SEARCH;
         }
 
-        //FIXIT-M verify preface is correct, else generate loss of sync event and abort
         *flush_offset = 24 - session_data->octets_seen[source_id];
         session_data->header_coming[source_id] = false;
         session_data->preface[source_id] = false;
@@ -324,3 +332,24 @@ const StreamBuffer implement_reassemble(Http2FlowData* session_data, unsigned to
     return frame_buf;
 }
 
+ValidationResult validate_preface(const uint8_t* data, const uint32_t length, 
+    const uint32_t octets_seen)
+{
+    const uint32_t preface_length = 24;
+
+    static const uint8_t connection_prefix[] = {'P', 'R', 'I', ' ', '*', ' ',
+      'H', 'T', 'T', 'P', '/', '2', '.', '0', '\r', '\n', '\r', '\n', 'S', 'M', 
+      '\r', '\n', '\r', '\n'};
+
+    assert(octets_seen < preface_length);
+
+    const uint32_t count = (octets_seen + length) < preface_length ? length : (preface_length - octets_seen); 
+
+    if (memcmp(data, connection_prefix + octets_seen, count))
+        return V_BAD;
+
+    if ((octets_seen + length) < preface_length)
+        return V_TBD;
+    
+    return V_GOOD;
+}
index bf1686e8a1deefb7d2cd076d9c0f2d44a470ede1..8620f5f6e4f5192d06407a9a77e516bef1b530c5 100644 (file)
@@ -35,6 +35,7 @@ const snort::RuleMap Http2Module::http2_events[] =
     { EVENT_STRING_DECODE_FAILURE, "error in HPACK string value" },
     { EVENT_MISSING_CONTINUATION, "missing continuation frame"},
     { EVENT_UNEXPECTED_CONTINUATION, "unexpected continuation frame"},
+    { EVENT_PREFACE_MATCH_FAILURE, "HTTP/2 connection preface does not match"},
     { 0, nullptr }
 };