From ff784075a2ed8253135dd84092160cfcbb355f3b Mon Sep 17 00:00:00 2001 From: Eric Leblond Date: Mon, 2 Dec 2013 14:26:08 +0100 Subject: [PATCH] htp: randomization of htp inspection sizes This is an implementation of #940. It randomize libhtp request and response size if the same way this has been done for stream inspection. --- src/app-layer-htp.c | 34 ++++++++++++++++++++++++++++++++++ src/app-layer-htp.h | 5 +++++ suricata.yaml.in | 9 +++++++++ 3 files changed, 48 insertions(+) diff --git a/src/app-layer-htp.c b/src/app-layer-htp.c index 6580f4cc7e..808df46637 100644 --- a/src/app-layer-htp.c +++ b/src/app-layer-htp.c @@ -2112,6 +2112,8 @@ static void HTPConfigSetDefaultsPhase1(HTPCfgRec *cfg_prec) cfg_prec->request_inspect_window = HTP_CONFIG_DEFAULT_REQUEST_INSPECT_WINDOW; cfg_prec->response_inspect_min_size = HTP_CONFIG_DEFAULT_RESPONSE_INSPECT_MIN_SIZE; cfg_prec->response_inspect_window = HTP_CONFIG_DEFAULT_RESPONSE_INSPECT_WINDOW; + cfg_prec->randomize = HTP_CONFIG_DEFAULT_RANDOMIZE; + cfg_prec->randomize_range = HTP_CONFIG_DEFAULT_RANDOMIZE_RANGE; htp_config_register_request_header_data(cfg_prec->cfg, HTPCallbackRequestHeaderData); htp_config_register_request_trailer_data(cfg_prec->cfg, HTPCallbackRequestHeaderData); @@ -2150,6 +2152,25 @@ static void HTPConfigSetDefaultsPhase1(HTPCfgRec *cfg_prec) * the query and path. */ static void HTPConfigSetDefaultsPhase2(HTPCfgRec *cfg_prec) { + /* randomize inspection size if needed */ + if (cfg_prec->randomize) { + int rdrange = cfg_prec->randomize_range; + + cfg_prec->request_inspect_min_size += + (int) (cfg_prec->request_inspect_min_size * + (random() * 1.0 / RAND_MAX - 0.5) * rdrange / 100); + cfg_prec->request_inspect_window += + (int) (cfg_prec->request_inspect_window * + (random() * 1.0 / RAND_MAX - 0.5) * rdrange / 100); + + cfg_prec->response_inspect_min_size += + (int) (cfg_prec->response_inspect_min_size * + (random() * 1.0 / RAND_MAX - 0.5) * rdrange / 100); + cfg_prec->response_inspect_window += + (int) (cfg_prec->response_inspect_window * + (random() * 1.0 / RAND_MAX - 0.5) * rdrange / 100); + } + htp_config_register_request_line(cfg_prec->cfg, HTPCallbackRequestLine); return; @@ -2355,6 +2376,19 @@ static void HTPConfigParseParameters(HTPCfgRec *cfg_prec, ConfNode *s, htp_config_set_field_limits(cfg_prec->cfg, (size_t)HTP_CONFIG_DEFAULT_FIELD_LIMIT_SOFT, (size_t)limit); + } else if (strcasecmp("randomize-inspection-sizes", p->name) == 0) { + cfg_prec->randomize = ConfValIsTrue(p->val); + } else if (strcasecmp("randomize-inspection-range", p->name) == 0) { + uint32_t range = atoi(p->val); + if (range > 100) { + SCLogError(SC_ERR_SIZE_PARSE, "Invalid value for randomize" + " inspection range setting from conf file - %s." + " It should be inferior to 100." + " Killing engine", + p->val); + exit(EXIT_FAILURE); + } + cfg_prec->randomize_range = range; } else { SCLogWarning(SC_ERR_UNKNOWN_VALUE, "LIBHTP Ignoring unknown " "default config: %s", p->name); diff --git a/src/app-layer-htp.h b/src/app-layer-htp.h index eab5339d16..db7b56ae7f 100644 --- a/src/app-layer-htp.h +++ b/src/app-layer-htp.h @@ -48,6 +48,9 @@ #define HTP_CONFIG_DEFAULT_FIELD_LIMIT_SOFT 9000U #define HTP_CONFIG_DEFAULT_FIELD_LIMIT_HARD 18000U +#define HTP_CONFIG_DEFAULT_RANDOMIZE 1 +#define HTP_CONFIG_DEFAULT_RANDOMIZE_RANGE 10 + /** a boundary should be smaller in size */ #define HTP_BOUNDARY_MAX 200U @@ -147,6 +150,8 @@ typedef struct HTPCfgRec_ { uint32_t response_inspect_min_size; uint32_t response_inspect_window; + int randomize; + int randomize_range; } HTPCfgRec; /** Struct used to hold chunks of a body on a request */ diff --git a/suricata.yaml.in b/suricata.yaml.in index 4df61d493e..72ee6932bd 100644 --- a/suricata.yaml.in +++ b/suricata.yaml.in @@ -1123,6 +1123,15 @@ app-layer: request-body-inspect-window: 4kb response-body-minimal-inspect-size: 32kb response-body-inspect-window: 4kb + # Take a random value for inspection sizes around the specified value. + # This lower the risk of some evasion technics but could lead + # detection change between runs. It is set to 'yes' by default. + #randomize-inspection-sizes: yes + # If randomize-inspection-sizes is active, the value of various + # inspection size will be choosen in the [1 - range%, 1 + range%] + # range + # Default value of randomize-inspection-range is 10. + #randomize-inspection-range: 10 # decoding double-decode-path: no