From: Mike Stepanek (mstepane) Date: Thu, 30 Jan 2020 14:04:41 +0000 (+0000) Subject: Merge pull request #1966 in SNORT/snort3 from ~MDAGON/snort3:h2i to master X-Git-Tag: 3.0.0-268~35 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e230c6d6b28a92d006f2dacd8d1b2a8358c40a87;p=thirdparty%2Fsnort3.git Merge pull request #1966 in SNORT/snort3 from ~MDAGON/snort3:h2i to master Squashed commit of the following: commit bbe358a1e38a2c5256f20792b9ad5c3120f9a942 Author: mdagon Date: Fri Jan 17 09:50:41 2020 -0500 http2_inspect: data frame http inspection walking skeleton first phase --- diff --git a/src/service_inspectors/http2_inspect/http2_enum.h b/src/service_inspectors/http2_inspect/http2_enum.h index c305228bf..b63b5f1b3 100644 --- a/src/service_inspectors/http2_inspect/http2_enum.h +++ b/src/service_inspectors/http2_inspect/http2_enum.h @@ -61,6 +61,7 @@ enum EventSid EVENT_INVALID_HEADER = 10, EVENT_SETTINGS_FRAME_ERROR = 11, EVENT_SETTINGS_FRAME_UNKN_PARAM = 12, + EVENT_FRAME_SEQUENCE = 13, EVENT__MAX_VALUE }; @@ -88,6 +89,7 @@ enum Infraction INF_HPACK_INDEX_OUT_OF_BOUNDS = 17, INF_INVALID_SETTINGS_FRAME = 18, INF_SETTINGS_FRAME_UNKN_PARAM = 19, + INF_FRAME_SEQUENCE = 20, INF__MAX_VALUE }; diff --git a/src/service_inspectors/http2_inspect/http2_flow_data.h b/src/service_inspectors/http2_inspect/http2_flow_data.h index 9a239ba79..acb4550b9 100644 --- a/src/service_inspectors/http2_inspect/http2_flow_data.h +++ b/src/service_inspectors/http2_inspect/http2_flow_data.h @@ -151,9 +151,9 @@ protected: #endif private: - class Http2Stream* find_stream(uint32_t key) const; class Http2Stream* get_stream(uint32_t key); class Http2Stream* get_hi_stream() const; + class Http2Stream* find_stream(uint32_t key) const; }; #endif diff --git a/src/service_inspectors/http2_inspect/http2_inspect.cc b/src/service_inspectors/http2_inspect/http2_inspect.cc index 9b5b0b06d..0fa6646e1 100644 --- a/src/service_inspectors/http2_inspect/http2_inspect.cc +++ b/src/service_inspectors/http2_inspect/http2_inspect.cc @@ -115,6 +115,9 @@ void Http2Inspect::eval(Packet* p) Http2FlowData* const session_data = (Http2FlowData*)p->flow->get_flow_data(Http2FlowData::inspector_id); + if (!session_data) + return; + // FIXIT-H Workaround for unexpected eval() calls // Avoid eval if scan/reassemble aborts if (session_data->frame_type[source_id] == FT__NONE) diff --git a/src/service_inspectors/http2_inspect/http2_stream_splitter.cc b/src/service_inspectors/http2_inspect/http2_stream_splitter.cc index 5a150cc43..c9de163fd 100644 --- a/src/service_inspectors/http2_inspect/http2_stream_splitter.cc +++ b/src/service_inspectors/http2_inspect/http2_stream_splitter.cc @@ -53,6 +53,8 @@ StreamSplitter::Status Http2StreamSplitter::scan(Packet* pkt, const uint8_t* dat { AssistantGadgetEvent event(pkt, "http"); DataBus::publish(FLOW_ASSISTANT_GADGET_EVENT, event); + if (pkt->flow->assistant_gadget == nullptr) + return HttpStreamSplitter::status_value(StreamSplitter::ABORT, true); pkt->flow->set_flow_data(session_data = new Http2FlowData(pkt->flow)); Http2Module::increment_peg_counts(PEG_FLOW); } diff --git a/src/service_inspectors/http2_inspect/http2_stream_splitter_impl.cc b/src/service_inspectors/http2_inspect/http2_stream_splitter_impl.cc index 9e42fa0b4..39e2a69b6 100644 --- a/src/service_inspectors/http2_inspect/http2_stream_splitter_impl.cc +++ b/src/service_inspectors/http2_inspect/http2_stream_splitter_impl.cc @@ -26,6 +26,7 @@ #include #include "service_inspectors/http_inspect/http_common.h" +#include "service_inspectors/http_inspect/http_flow_data.h" #include "service_inspectors/http_inspect/http_test_input.h" #include "service_inspectors/http_inspect/http_test_manager.h" @@ -168,6 +169,22 @@ StreamSplitter::Status implement_scan(Http2FlowData* session_data, const uint8_t session_data->current_stream[source_id] = get_stream_id(session_data->scan_frame_header[source_id]); + if (type == FT_DATA) + { + Http2Stream* const stream = session_data->find_stream(session_data->current_stream[source_id]); + HttpFlowData* http_flow = nullptr; + if (stream) + http_flow = (HttpFlowData*)stream->get_hi_flow_data(); + + if (!stream || !http_flow || + (http_flow->get_type_expected(source_id) != HttpEnums::SEC_BODY_CHUNK)) + { + *session_data->infractions[source_id] += INF_FRAME_SEQUENCE; + session_data->events[source_id]->create_event(EVENT_FRAME_SEQUENCE); + status = StreamSplitter::ABORT; + } + } + // Compute frame section length once per frame if (session_data->scan_remaining_frame_octets[source_id] == 0) { diff --git a/src/service_inspectors/http2_inspect/http2_tables.cc b/src/service_inspectors/http2_inspect/http2_tables.cc index bf270adb9..b0ebc2df6 100644 --- a/src/service_inspectors/http2_inspect/http2_tables.cc +++ b/src/service_inspectors/http2_inspect/http2_tables.cc @@ -43,6 +43,7 @@ const RuleMap Http2Module::http2_events[] = { EVENT_INVALID_HEADER, "invalid HTTP/2 header field" }, { EVENT_SETTINGS_FRAME_ERROR, "error in HTTP/2 settings frame" }, { EVENT_SETTINGS_FRAME_UNKN_PARAM, "unknown parameter in HTTP/2 settings frame" }, + { EVENT_FRAME_SEQUENCE, "invalid HTTP/2 frame sequence" }, { 0, nullptr } }; diff --git a/src/service_inspectors/http_inspect/http_flow_data.h b/src/service_inspectors/http_inspect/http_flow_data.h index 9440455b1..bbf397dcc 100644 --- a/src/service_inspectors/http_inspect/http_flow_data.h +++ b/src/service_inspectors/http_inspect/http_flow_data.h @@ -65,6 +65,9 @@ public: friend class HttpUnitTestSetup; #endif + HttpEnums::SectionType get_type_expected(HttpCommon::SourceId source_id) + { return type_expected[source_id]; } + private: bool for_http2 = false;