From: Tom Peters (thopeter) Date: Fri, 14 Jul 2017 15:51:35 +0000 (-0400) Subject: Merge pull request #956 in SNORT/snort3 from nhttp81 to master X-Git-Tag: 3.0.0-239~16 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=de98bedebba3736959da30c25189cd36802a9758;p=thirdparty%2Fsnort3.git Merge pull request #956 in SNORT/snort3 from nhttp81 to master Squashed commit of the following: commit 70455188e2954b95107457eefe85937439c271b5 Author: Tom Peters Date: Mon Jul 10 12:26:42 2017 -0400 http_inspect: specific alert added 119:95 for Content-Encoding chunked. http_inspect: alert 119:96 added for unsolicited 206 response. file_api: memory leak fixed --- diff --git a/src/file_api/file_policy.cc b/src/file_api/file_policy.cc index fe98106f1..42f54fde9 100644 --- a/src/file_api/file_policy.cc +++ b/src/file_api/file_policy.cc @@ -188,6 +188,8 @@ FileVerdict FilePolicy::signature_lookup(Flow* flow, FileContext* file) if (file->reserve_file(captured) == FILE_CAPTURE_SUCCESS) captured->store_file_async(); + else + delete captured; } return (signature_lookup(flow, (FileInfo*)file)); diff --git a/src/service_inspectors/http_inspect/http_enum.h b/src/service_inspectors/http_inspect/http_enum.h index 4424fc066..31cd6bbdc 100644 --- a/src/service_inspectors/http_inspect/http_enum.h +++ b/src/service_inspectors/http_inspect/http_enum.h @@ -208,7 +208,7 @@ enum Infraction INF_JS_OBFUSCATION_EXCD, INF_JS_EXCESS_WS, INF_MIXED_ENCODINGS, - INF_RSP_WO_REQ, + INF_RESPONSE_WO_REQUEST, INF_SWF_ZLIB_FAILURE, INF_SWF_LZMA_FAILURE, INF_PDF_DEFL_FAILURE, @@ -228,6 +228,8 @@ enum Infraction INF_CTE_HEADER, INF_ILLEGAL_TRAILER, INF_REPEATED_HEADER, + INF_CONTENT_ENCODING_CHUNKED, + INF_206_WITHOUT_RANGE, INF__MAX_VALUE }; @@ -237,7 +239,7 @@ enum CharAction { CHAR_NORMAL=2, CHAR_PERCENT, CHAR_PATH, CHAR_EIGHTBIT, CHAR_SU // Content codings enum Contentcoding { CONTENTCODE__OTHER=1, CONTENTCODE_GZIP, CONTENTCODE_DEFLATE, CONTENTCODE_COMPRESS, CONTENTCODE_EXI, CONTENTCODE_PACK200_GZIP, CONTENTCODE_X_GZIP, - CONTENTCODE_X_COMPRESS, CONTENTCODE_IDENTITY }; + CONTENTCODE_X_COMPRESS, CONTENTCODE_IDENTITY, CONTENTCODE_CHUNKED }; enum EventSid { @@ -336,6 +338,8 @@ enum EventSid EVENT_CTE_HEADER, EVENT_ILLEGAL_TRAILER, EVENT_REPEATED_HEADER, + EVENT_CONTENT_ENCODING_CHUNKED, + EVENT_206_WITHOUT_RANGE, EVENT__MAX_VALUE }; diff --git a/src/service_inspectors/http_inspect/http_msg_header.cc b/src/service_inspectors/http_inspect/http_msg_header.cc index 50b779c8c..5657b8020 100644 --- a/src/service_inspectors/http_inspect/http_msg_header.cc +++ b/src/service_inspectors/http_inspect/http_msg_header.cc @@ -337,6 +337,10 @@ void HttpMsgHeader::setup_encoding_decompression() break; case CONTENTCODE_IDENTITY: break; + case CONTENTCODE_CHUNKED: + add_infraction(INF_CONTENT_ENCODING_CHUNKED); + create_event(EVENT_CONTENT_ENCODING_CHUNKED); + break; case CONTENTCODE__OTHER: add_infraction(INF_UNKNOWN_ENCODING); create_event(EVENT_UNKNOWN_ENCODING); diff --git a/src/service_inspectors/http_inspect/http_msg_status.cc b/src/service_inspectors/http_inspect/http_msg_status.cc index 19b3470db..d5680b75f 100644 --- a/src/service_inspectors/http_inspect/http_msg_status.cc +++ b/src/service_inspectors/http_inspect/http_msg_status.cc @@ -153,10 +153,22 @@ void HttpMsgStatus::gen_events() if (flow->is_pdu_inorder(SSN_DIR_FROM_SERVER)) { // HTTP response without a request. Possible ssh tunneling - add_infraction(INF_RSP_WO_REQ); + add_infraction(INF_RESPONSE_WO_REQUEST); create_event(EVENT_RESPONSE_WO_REQUEST); } } + + if (status_code_num == 206) + { + // Verify that 206 Partial Content is in response to a Range request. Unsolicited 206 + // responses indicate content is being fragmented for no good reason. + HttpMsgHeader* const req_header = transaction->get_header(SRC_CLIENT); + if ((req_header != nullptr) && (req_header->get_header_count(HEAD_RANGE) == 0)) + { + add_infraction(INF_206_WITHOUT_RANGE); + create_event(EVENT_206_WITHOUT_RANGE); + } + } } void HttpMsgStatus::update_flow() diff --git a/src/service_inspectors/http_inspect/http_tables.cc b/src/service_inspectors/http_inspect/http_tables.cc index 9c5bde32c..ab1f2ec75 100644 --- a/src/service_inspectors/http_inspect/http_tables.cc +++ b/src/service_inspectors/http_inspect/http_tables.cc @@ -148,6 +148,7 @@ const StrCode HttpMsgHeadShared::content_code_list[] = { CONTENTCODE_X_GZIP, "x-gzip" }, { CONTENTCODE_X_COMPRESS, "x-compress" }, { CONTENTCODE_IDENTITY, "identity" }, + { CONTENTCODE_CHUNKED, "chunked" }, { 0, nullptr } }; @@ -374,6 +375,8 @@ const RuleMap HttpModule::http_events[] = { EVENT_ILLEGAL_TRAILER, "illegal field in chunked message trailers" }, { EVENT_REPEATED_HEADER, "header field inappropriately appears twice or has two " "values" }, + { EVENT_CONTENT_ENCODING_CHUNKED, "invalid value chunked in Content-Encoding header" }, + { EVENT_206_WITHOUT_RANGE, "206 response sent to a request without a Range header" }, { 0, nullptr } }; diff --git a/src/service_inspectors/http_inspect/http_test_input.cc b/src/service_inspectors/http_inspect/http_test_input.cc index 7390d308e..ee6873b22 100644 --- a/src/service_inspectors/http_inspect/http_test_input.cc +++ b/src/service_inspectors/http_inspect/http_test_input.cc @@ -254,10 +254,9 @@ void HttpTestInput::scan(uint8_t*& data, uint32_t& length, SourceId source_id, u const unsigned amount = convert_num_octets(command_value + strlen("fileread"), command_length - strlen("fileread")); assert((amount > 0) && (amount <= MAX_OCTETS)); - int new_octet; for (unsigned k=0; k < amount; k++) { - new_octet = getc(include_file); + const int new_octet = getc(include_file); assert(new_octet != EOF); msg_buf[end_offset++] = new_octet; } diff --git a/src/service_inspectors/http_inspect/http_uri.cc b/src/service_inspectors/http_inspect/http_uri.cc index 4b427a25b..df5f5690e 100644 --- a/src/service_inspectors/http_inspect/http_uri.cc +++ b/src/service_inspectors/http_inspect/http_uri.cc @@ -144,7 +144,7 @@ void HttpUri::parse_abs_path() } } -void HttpUri::check_oversize_dir(Field uri_field) +void HttpUri::check_oversize_dir(Field& uri_field) { int32_t total_length = 0; const uint8_t* last_dir = nullptr; diff --git a/src/service_inspectors/http_inspect/http_uri.h b/src/service_inspectors/http_inspect/http_uri.h index 327e3e490..d61421e65 100644 --- a/src/service_inspectors/http_inspect/http_uri.h +++ b/src/service_inspectors/http_inspect/http_uri.h @@ -87,7 +87,7 @@ private: void parse_authority(); void parse_abs_path(); - void check_oversize_dir(Field); + void check_oversize_dir(Field&); }; #endif diff --git a/src/service_inspectors/http_inspect/test/http_normalizers_test.cc b/src/service_inspectors/http_inspect/test/http_normalizers_test.cc index 4c100c84a..e0910ce14 100644 --- a/src/service_inspectors/http_inspect/test/http_normalizers_test.cc +++ b/src/service_inspectors/http_inspect/test/http_normalizers_test.cc @@ -49,7 +49,6 @@ TEST(norm_decimal_integer_test, examples) CHECK(norm_decimal_integer(Field(2, (const uint8_t*)"-27")) == STAT_PROBLEMATIC); CHECK(norm_decimal_integer(Field(6, (const uint8_t*)"27,382")) == 27); CHECK(norm_decimal_integer(Field(3, (const uint8_t*)",27")) == STAT_PROBLEMATIC); - CHECK(norm_decimal_integer(Field(3, (const uint8_t*)",27")) == STAT_PROBLEMATIC); CHECK(norm_decimal_integer(Field(6, (const uint8_t*)"00000=")) == STAT_PROBLEMATIC); CHECK(norm_decimal_integer(Field(6, (const uint8_t*)"32.578")) == STAT_PROBLEMATIC); CHECK(norm_decimal_integer(Field(18, (const uint8_t*)"123456789012345678")) ==