From 8a339e73d3d4377b7bca6f548b8858995974905b Mon Sep 17 00:00:00 2001 From: Philippe Antoine Date: Fri, 17 May 2019 13:16:27 +0200 Subject: [PATCH] http: adds an event for double encoded uri --- rules/http-events.rules | 4 +++- src/app-layer-htp.c | 38 ++++++++++++++++++++++++++++++-------- src/app-layer-htp.h | 1 + 3 files changed, 34 insertions(+), 9 deletions(-) diff --git a/rules/http-events.rules b/rules/http-events.rules index 165979f026..e0235180d0 100644 --- a/rules/http-events.rules +++ b/rules/http-events.rules @@ -69,5 +69,7 @@ alert http any any -> any any (msg:"SURICATA HTTP Response invalid status"; flow alert http any any -> any any (msg:"SURICATA HTTP Request line incomplete"; flow:established,to_server; app-layer-event:http.request_line_incomplete; flowint:http.anomaly.count,+,1; classtype:protocol-command-decode; sid:2221042; rev:1;) -# next sid 2221043 +alert http any any -> any any (msg:"SURICATA HTTP Request double encoded URI"; flow:established,to_server; app-layer-event:http.double_encoded_uri; flowint:http.anomaly.count,+,1; classtype:protocol-command-decode; sid:2221043; rev:1;) + +# next sid 2221044 diff --git a/src/app-layer-htp.c b/src/app-layer-htp.c index 564cfca38d..be367a8677 100644 --- a/src/app-layer-htp.c +++ b/src/app-layer-htp.c @@ -150,6 +150,8 @@ SCEnumCharMap http_decoder_event_table[ ] = { HTTP_DECODER_EVENT_REQUEST_HEADER_REPETITION}, { "RESPONSE_HEADER_REPETITION", HTTP_DECODER_EVENT_RESPONSE_HEADER_REPETITION}, + { "DOUBLE_ENCODED_URI", + HTTP_DECODER_EVENT_DOUBLE_ENCODED_URI}, { "URI_DELIM_NON_COMPLIANT", HTTP_DECODER_EVENT_URI_DELIM_NON_COMPLIANT}, { "METHOD_DELIM_NON_COMPLIANT", @@ -2158,26 +2160,46 @@ static int HTPCallbackRequestLine(htp_tx_t *tx) return HTP_OK; } -static int HTPCallbackDoubleDecodeQuery(htp_tx_t *tx) +static int HTPCallbackDoubleDecodeUriPart(htp_tx_t *tx, bstr *part) { - if (tx->parsed_uri == NULL || tx->parsed_uri->query == NULL) + if (part == NULL) return HTP_OK; uint64_t flags = 0; - htp_urldecode_inplace(tx->cfg, HTP_DECODER_URLENCODED, tx->parsed_uri->query, &flags); + size_t prevlen = bstr_len(part); + htp_status_t res = htp_urldecode_inplace(tx->cfg, HTP_DECODER_URLENCODED, part, &flags); + // shorter string means that uri was encoded + if (res == HTP_OK && prevlen > bstr_len(part)) { + HtpTxUserData *htud = (HtpTxUserData *) htp_tx_get_user_data(tx); + if (likely(htud == NULL)) { + htud = HTPCalloc(1, sizeof(*htud)); + if (unlikely(htud == NULL)) + return HTP_OK; + htp_tx_set_user_data(tx, htud); + } + HtpState *s = htp_connp_get_user_data(tx->connp); + if (s == NULL) + return HTP_OK; + HTPSetEvent(s, htud, HTTP_DECODER_EVENT_DOUBLE_ENCODED_URI); + } return HTP_OK; } -static int HTPCallbackDoubleDecodePath(htp_tx_t *tx) +static int HTPCallbackDoubleDecodeQuery(htp_tx_t *tx) { - if (tx->parsed_uri == NULL || tx->parsed_uri->path == NULL) + if (tx->parsed_uri == NULL) return HTP_OK; - uint64_t flags = 0; - htp_urldecode_inplace(tx->cfg, HTP_DECODER_URL_PATH, tx->parsed_uri->path, &flags); + return HTPCallbackDoubleDecodeUriPart(tx, tx->parsed_uri->query); +} - return HTP_OK; +static int HTPCallbackDoubleDecodePath(htp_tx_t *tx) +{ + if (tx->parsed_uri == NULL) + return HTP_OK; + + return HTPCallbackDoubleDecodeUriPart(tx, tx->parsed_uri->path); } static int HTPCallbackRequestHeaderData(htp_tx_data_t *tx_data) diff --git a/src/app-layer-htp.h b/src/app-layer-htp.h index c5e798103e..ca439f0335 100644 --- a/src/app-layer-htp.h +++ b/src/app-layer-htp.h @@ -115,6 +115,7 @@ enum { HTTP_DECODER_EVENT_RESPONSE_INVALID_PROTOCOL, HTTP_DECODER_EVENT_RESPONSE_INVALID_STATUS, HTTP_DECODER_EVENT_REQUEST_LINE_INCOMPLETE, + HTTP_DECODER_EVENT_DOUBLE_ENCODED_URI, /* suricata errors/warnings */ HTTP_DECODER_EVENT_MULTIPART_GENERIC_ERROR,