From 2e697ed446a9cca530fc7da392fc0521224cf07f Mon Sep 17 00:00:00 2001 From: "Tom Peters (thopeter)" Date: Mon, 11 Sep 2017 13:15:10 -0400 Subject: [PATCH] Merge pull request #1009 in SNORT/snort3 from nhttp88 to master Squashed commit of the following: commit ff9037908b697cda3c847d25a91427526a7305d6 Author: Tom Peters Date: Fri Sep 8 15:35:46 2017 -0400 http_inspect: added http_raw_buffer rule option --- doc/http_inspect.txt | 13 +++++- .../http_inspect/http_api.cc | 3 ++ .../http_inspect/http_enum.h | 2 +- .../http_inspect/http_msg_body.cc | 2 + .../http_inspect/http_msg_section.cc | 5 +++ .../http_inspect/ips_http.cc | 42 +++++++++++++++++++ .../http_inspect/ips_http.h | 2 +- 7 files changed, 65 insertions(+), 4 deletions(-) diff --git a/doc/http_inspect.txt b/doc/http_inspect.txt index 275470064..6b93a9dfa 100644 --- a/doc/http_inspect.txt +++ b/doc/http_inspect.txt @@ -409,6 +409,15 @@ This is the body of a request message such as POST or PUT. Normalization for http_client_body is the same URI-like normalization applied to http_header when no specific header is specified. +===== http_raw_body + +This is the body of a request or response message. It will be dechunked +and unzipped if applicable but will not be normalized in any other way. +The difference between http_raw_body and packet data is a rule that uses +packet data will search and may match an HTTP header, but http_raw_body +is limited to the message body. Thus the latter is more efficient and +more accurate for most uses. + ===== http_method The method field of a request message. Common values are "GET", "POST", @@ -447,8 +456,8 @@ file_data contains the normalized message body. This is the normalization described above under gzip, normalize_utf, decompress_pdf, decompress_swf, and normalize_javascript. -The unnormalized message body is available in the packet data. If gzip is -configured the packet data will be unzipped. +The unnormalized message content is available in the packet data. If gzip +is configured the packet data will be unzipped. ==== Timing issues and combining rule options diff --git a/src/service_inspectors/http_inspect/http_api.cc b/src/service_inspectors/http_inspect/http_api.cc index b73297c91..138d28555 100644 --- a/src/service_inspectors/http_inspect/http_api.cc +++ b/src/service_inspectors/http_inspect/http_api.cc @@ -51,6 +51,7 @@ const char* HttpApi::classic_buffer_names[] = "http_raw_trailer", "http_raw_request", "http_raw_status", + "http_raw_body", nullptr }; @@ -97,6 +98,7 @@ extern const BaseApi* ips_http_trailer; extern const BaseApi* ips_http_raw_trailer; extern const BaseApi* ips_http_raw_request; extern const BaseApi* ips_http_raw_status; +extern const BaseApi* ips_http_raw_body; #ifdef BUILDING_SO SO_PUBLIC const BaseApi* snort_plugins[] = @@ -120,6 +122,7 @@ const BaseApi* sin_http[] = ips_http_raw_trailer, ips_http_raw_request, ips_http_raw_status, + ips_http_raw_body, nullptr }; diff --git a/src/service_inspectors/http_inspect/http_enum.h b/src/service_inspectors/http_inspect/http_enum.h index e1967a099..7d9a74121 100644 --- a/src/service_inspectors/http_inspect/http_enum.h +++ b/src/service_inspectors/http_inspect/http_enum.h @@ -57,7 +57,7 @@ enum HTTP_BUFFER { HTTP_BUFFER_CLIENT_BODY = 1, HTTP_BUFFER_COOKIE, HTTP_BUFFER_ HTTP_BUFFER_METHOD, HTTP_BUFFER_RAW_COOKIE, HTTP_BUFFER_RAW_HEADER, HTTP_BUFFER_RAW_URI, HTTP_BUFFER_STAT_CODE, HTTP_BUFFER_STAT_MSG, HTTP_BUFFER_URI, HTTP_BUFFER_VERSION, HTTP_BUFFER_TRAILER, HTTP_BUFFER_RAW_TRAILER, HTTP_BUFFER_RAW_REQUEST, - HTTP_BUFFER_RAW_STATUS, HTTP_BUFFER_MAX }; + HTTP_BUFFER_RAW_STATUS, HTTP_BUFFER_RAW_BODY, HTTP_BUFFER_MAX }; // Peg counts // This enum must remain synchronized with HttpModule::peg_names[] in http_tables.cc diff --git a/src/service_inspectors/http_inspect/http_msg_body.cc b/src/service_inspectors/http_inspect/http_msg_body.cc index facdb7762..26f191527 100644 --- a/src/service_inspectors/http_inspect/http_msg_body.cc +++ b/src/service_inspectors/http_inspect/http_msg_body.cc @@ -282,6 +282,8 @@ void HttpMsgBody::print_body_section(FILE* output) detect_data.print(output, "Detect data"); get_classic_buffer(HTTP_BUFFER_CLIENT_BODY, 0, 0).print(output, HttpApi::classic_buffer_names[HTTP_BUFFER_CLIENT_BODY-1]); + get_classic_buffer(HTTP_BUFFER_RAW_BODY, 0, 0).print(output, + HttpApi::classic_buffer_names[HTTP_BUFFER_RAW_BODY-1]); HttpMsgSection::print_section_wrapup(output); } diff --git a/src/service_inspectors/http_inspect/http_msg_section.cc b/src/service_inspectors/http_inspect/http_msg_section.cc index 7a552292f..17c656e61 100644 --- a/src/service_inspectors/http_inspect/http_msg_section.cc +++ b/src/service_inspectors/http_inspect/http_msg_section.cc @@ -218,6 +218,11 @@ const Field& HttpMsgSection::get_classic_buffer(unsigned id, uint64_t sub_id, ui HttpMsgTrailer* trailer = transaction->get_trailer(buffer_side); return (trailer != nullptr) ? trailer->get_classic_raw_header() : Field::FIELD_NULL; } + case HTTP_BUFFER_RAW_BODY: + { + HttpMsgBody* body = transaction->get_body(); + return (body != nullptr) ? body->msg_text : Field::FIELD_NULL; + } default: assert(false); return Field::FIELD_NULL; diff --git a/src/service_inspectors/http_inspect/ips_http.cc b/src/service_inspectors/http_inspect/ips_http.cc index a97d7216b..86cd7d600 100644 --- a/src/service_inspectors/http_inspect/ips_http.cc +++ b/src/service_inspectors/http_inspect/ips_http.cc @@ -59,6 +59,7 @@ bool HttpCursorModule::begin(const char*, int, SnortConfig*) inspect_section = IS_DETECTION; break; case HTTP_BUFFER_CLIENT_BODY: + case HTTP_BUFFER_RAW_BODY: inspect_section = IS_BODY; break; case HTTP_BUFFER_TRAILER: @@ -1002,6 +1003,46 @@ static const IpsApi raw_status_api = nullptr }; +//------------------------------------------------------------------------- +// http_raw_body +//------------------------------------------------------------------------- + +#undef IPS_OPT +#define IPS_OPT "http_raw_body" +#undef IPS_HELP +#define IPS_HELP "rule option to set the detection cursor to the unnormalized message body" + +static Module* raw_body_mod_ctor() +{ + return new HttpCursorModule(IPS_OPT, IPS_HELP, HTTP_BUFFER_RAW_BODY, CAT_SET_OTHER, + PSI_RAW_BODY); +} + +static const IpsApi raw_body_api = +{ + { + PT_IPS_OPTION, + sizeof(IpsApi), + IPSAPI_VERSION, + 1, + API_RESERVED, + API_OPTIONS, + IPS_OPT, + IPS_HELP, + raw_body_mod_ctor, + HttpCursorModule::mod_dtor + }, + OPT_TYPE_DETECTION, + 0, PROTO_BIT__TCP, + nullptr, + nullptr, + nullptr, + nullptr, + HttpIpsOption::opt_ctor, + HttpIpsOption::opt_dtor, + nullptr +}; + //------------------------------------------------------------------------- // plugins //------------------------------------------------------------------------- @@ -1021,4 +1062,5 @@ const BaseApi* ips_http_trailer = &trailer_api.base; const BaseApi* ips_http_raw_trailer = &raw_trailer_api.base; const BaseApi* ips_http_raw_request = &raw_request_api.base; const BaseApi* ips_http_raw_status = &raw_status_api.base; +const BaseApi* ips_http_raw_body = &raw_body_api.base; diff --git a/src/service_inspectors/http_inspect/ips_http.h b/src/service_inspectors/http_inspect/ips_http.h index 4aedd7783..270835f30 100644 --- a/src/service_inspectors/http_inspect/ips_http.h +++ b/src/service_inspectors/http_inspect/ips_http.h @@ -30,7 +30,7 @@ enum PsIdx { PSI_URI, PSI_CLIENT_BODY, PSI_METHOD, PSI_COOKIE, PSI_STAT_CODE, PSI_STAT_MSG, PSI_RAW_URI, PSI_RAW_HEADER, PSI_RAW_COOKIE, PSI_HEADER, PSI_VERSION, PSI_TRAILER, - PSI_RAW_TRAILER, PSI_RAW_REQUEST, PSI_RAW_STATUS, PSI_MAX }; + PSI_RAW_TRAILER, PSI_RAW_REQUEST, PSI_RAW_STATUS, PSI_RAW_BODY, PSI_MAX }; class HttpCursorModule : public Module { -- 2.47.3