From 2a86df53f295ba865d9bbf276aba706624eb202e Mon Sep 17 00:00:00 2001 From: Philippe Antoine Date: Tue, 12 Dec 2023 09:34:04 +0100 Subject: [PATCH] detect: strip_pseudo_headers transform Ticket: 6546 (cherry picked from commit adf5e6da7bdf81d65ccfeb115e6bc50e7031a0ca) --- doc/userguide/rules/transforms.rst | 14 +++ src/Makefile.am | 2 + src/detect-engine-register.c | 2 + src/detect-engine-register.h | 1 + src/detect-transform-strip-pseudo-headers.c | 100 ++++++++++++++++++++ src/detect-transform-strip-pseudo-headers.h | 30 ++++++ 6 files changed, 149 insertions(+) create mode 100644 src/detect-transform-strip-pseudo-headers.c create mode 100644 src/detect-transform-strip-pseudo-headers.h diff --git a/doc/userguide/rules/transforms.rst b/doc/userguide/rules/transforms.rst index 0067ace1de8b..f730f0d2dc71 100644 --- a/doc/userguide/rules/transforms.rst +++ b/doc/userguide/rules/transforms.rst @@ -174,3 +174,17 @@ Example:: alert http any any -> any any (msg:"HTTP authorization"; http.header_names; \ header_lowercase; content:"authorization:"; sid:1;) + +strip_pseudo_headers +-------------------- + +This transform is meant for HTTP/1 HTTP/2 header names normalization. +It strips HTTP2 pseudo-headers (names and values). + +The implementation just strips every line beginning by ``:``. + +This example alerts for both HTTP/1 and HTTP/2 with only a user agent +Example:: + + alert http any any -> any any (msg:"HTTP ua only"; http.header_names; \ + bsize:16; content:"|0d 0a|User-Agent|0d 0a 0d 0a|"; nocase; sid:1;) diff --git a/src/Makefile.am b/src/Makefile.am index 18adccc8ba39..c863cf67f423 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -345,6 +345,7 @@ noinst_HEADERS = \ detect-transform-pcrexform.h \ detect-transform-sha1.h \ detect-transform-sha256.h \ + detect-transform-strip-pseudo-headers.h \ detect-transform-strip-whitespace.h \ detect-transform-urldecode.h \ detect-transform-xor.h \ @@ -956,6 +957,7 @@ libsuricata_c_a_SOURCES = \ detect-transform-pcrexform.c \ detect-transform-sha1.c \ detect-transform-sha256.c \ + detect-transform-strip-pseudo-headers.c \ detect-transform-strip-whitespace.c \ detect-transform-urldecode.c \ detect-transform-xor.c \ diff --git a/src/detect-engine-register.c b/src/detect-engine-register.c index bd90fb03a9ab..41038a23cf1d 100644 --- a/src/detect-engine-register.c +++ b/src/detect-engine-register.c @@ -237,6 +237,7 @@ #include "detect-transform-compress-whitespace.h" #include "detect-transform-strip-whitespace.h" +#include "detect-transform-strip-pseudo-headers.h" #include "detect-transform-md5.h" #include "detect-transform-sha1.h" #include "detect-transform-sha256.h" @@ -691,6 +692,7 @@ void SigTableSetup(void) DetectTransformCompressWhitespaceRegister(); DetectTransformStripWhitespaceRegister(); + DetectTransformStripPseudoHeadersRegister(); DetectTransformMd5Register(); DetectTransformSha1Register(); DetectTransformSha256Register(); diff --git a/src/detect-engine-register.h b/src/detect-engine-register.h index 8dc4bda2b8a7..7cc694af83d3 100644 --- a/src/detect-engine-register.h +++ b/src/detect-engine-register.h @@ -314,6 +314,7 @@ enum DetectKeywordId { DETECT_TRANSFORM_COMPRESS_WHITESPACE, DETECT_TRANSFORM_STRIP_WHITESPACE, + DETECT_TRANSFORM_STRIP_PSEUDO_HEADERS, DETECT_TRANSFORM_MD5, DETECT_TRANSFORM_SHA1, DETECT_TRANSFORM_SHA256, diff --git a/src/detect-transform-strip-pseudo-headers.c b/src/detect-transform-strip-pseudo-headers.c new file mode 100644 index 000000000000..450900d46037 --- /dev/null +++ b/src/detect-transform-strip-pseudo-headers.c @@ -0,0 +1,100 @@ +/* Copyright (C) 2023 Open Information Security Foundation + * + * You can copy, redistribute or modify this Program under the terms of + * the GNU General Public License version 2 as published by the Free + * Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * version 2 along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +/** + * \file + * + * \author Philippe Antoine + * + * Implements the strip_pseudo_headers transform keyword with option support + */ + +#include "suricata-common.h" +#include "detect.h" +#include "detect-engine.h" +#include "detect-parse.h" +#include "detect-transform-strip-pseudo-headers.h" + +/** + * \internal + * \brief Apply the strip_pseudo_headers keyword to the last pattern match + * \param det_ctx detection engine ctx + * \param s signature + * \param optstr options string + * \retval 0 ok + * \retval -1 failure + */ +static int DetectTransformStripPseudoHeadersSetup( + DetectEngineCtx *de_ctx, Signature *s, const char *optstr) +{ + SCEnter(); + int r = DetectSignatureAddTransform(s, DETECT_TRANSFORM_STRIP_PSEUDO_HEADERS, NULL); + SCReturnInt(r); +} + +static void DetectTransformStripPseudoHeaders(InspectionBuffer *buffer, void *options) +{ + const uint8_t *input = buffer->inspect; + const uint32_t input_len = buffer->inspect_len; + if (input_len == 0) { + return; + } + uint8_t output[input_len]; + + bool new_line = true; + bool pseudo = false; + uint32_t j = 0; + for (uint32_t i = 0; i < input_len; i++) { + if (new_line) { + if (input[i] == ':') { + pseudo = true; + } + if (input[i] != '\r' && input[i] != '\n') { + new_line = false; + } + } else { + if (input[i] == '\n') { + new_line = true; + if (!pseudo) { + output[j] = input[i]; + j++; + } + pseudo = false; + continue; + } + } + if (!pseudo) { + output[j] = input[i]; + j++; + } + } + InspectionBufferCopy(buffer, output, j); +} + +void DetectTransformStripPseudoHeadersRegister(void) +{ + sigmatch_table[DETECT_TRANSFORM_STRIP_PSEUDO_HEADERS].name = "strip_pseudo_headers"; + sigmatch_table[DETECT_TRANSFORM_STRIP_PSEUDO_HEADERS].desc = + "modify buffer via stripping pseudo headers"; + sigmatch_table[DETECT_TRANSFORM_STRIP_PSEUDO_HEADERS].url = + "/rules/transforms.html#strip_pseudo_headers"; + sigmatch_table[DETECT_TRANSFORM_STRIP_PSEUDO_HEADERS].Transform = + DetectTransformStripPseudoHeaders; + sigmatch_table[DETECT_TRANSFORM_STRIP_PSEUDO_HEADERS].Setup = + DetectTransformStripPseudoHeadersSetup; + sigmatch_table[DETECT_TRANSFORM_STRIP_PSEUDO_HEADERS].flags |= SIGMATCH_NOOPT; +} diff --git a/src/detect-transform-strip-pseudo-headers.h b/src/detect-transform-strip-pseudo-headers.h new file mode 100644 index 000000000000..c2016d438f04 --- /dev/null +++ b/src/detect-transform-strip-pseudo-headers.h @@ -0,0 +1,30 @@ +/* Copyright (C) 2023 Open Information Security Foundation + * + * You can copy, redistribute or modify this Program under the terms of + * the GNU General Public License version 2 as published by the Free + * Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * version 2 along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +/** + * \file + * + * \author Philippe Antoine + */ + +#ifndef __DETECT_TRANSFORM_STRIP_PSEUDOHEADERS_H__ +#define __DETECT_TRANSFORM_STRIP_PSEUDOHEADERS_H__ + +/* prototypes */ +void DetectTransformStripPseudoHeadersRegister(void); + +#endif /* __DETECT_TRANSFORM_STRIP_PSEUDOHEADERS_H__ */