suricata
detect-transform-pcrexform.c
Go to the documentation of this file.
1 /* Copyright (C) 2020 Open Information Security Foundation
2  *
3  * You can copy, redistribute or modify this Program under the terms of
4  * the GNU General Public License version 2 as published by the Free
5  * Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * version 2 along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15  * 02110-1301, USA.
16  */
17 
18 /**
19  * \file
20  *
21  * \author Jeff Lucovsky <jeff@lucovsky.org>
22  *
23  * Implements the pcrexform transform keyword with option support
24  */
25 
26 #include "suricata-common.h"
27 
28 #include "detect.h"
29 #include "detect-engine.h"
30 #include "detect-parse.h"
32 
34  pcre2_code *regex;
36 
37 static int DetectTransformPcrexformSetup (DetectEngineCtx *, Signature *, const char *);
38 static void DetectTransformPcrexformFree(DetectEngineCtx *, void *);
39 static void DetectTransformPcrexform(InspectionBuffer *buffer, void *options);
40 #ifdef UNITTESTS
42 #endif
43 
45 {
48  "modify buffer via PCRE before inspection";
49  sigmatch_table[DETECT_TRANSFORM_PCREXFORM].url = "/rules/transforms.html#pcre-xform";
51  DetectTransformPcrexform;
53  DetectTransformPcrexformFree;
55  DetectTransformPcrexformSetup;
56 #ifdef UNITTESTS
58 #endif
60 }
61 
62 static void DetectTransformPcrexformFree(DetectEngineCtx *de_ctx, void *ptr)
63 {
64  if (ptr != NULL) {
66  pcre2_code_free(pxd->regex);
67  SCFree(pxd);
68  }
69 }
70 
71 /**
72  * \internal
73  * \brief Apply the pcrexform keyword to the last pattern match
74  * \param det_ctx detection engine ctx
75  * \param s signature
76  * \param regexstr options string
77  * \retval 0 ok
78  * \retval -1 failure
79  */
80 static int DetectTransformPcrexformSetup (DetectEngineCtx *de_ctx, Signature *s, const char *regexstr)
81 {
82  SCEnter();
83 
84  // Create pxd from regexstr
85  DetectTransformPcrexformData *pxd = SCCalloc(1, sizeof(*pxd));
86  if (pxd == NULL) {
87  SCLogDebug("pxd allocation failed");
88  SCReturnInt(-1);
89  }
90 
91  int en;
92  PCRE2_SIZE eo;
93  pxd->regex = pcre2_compile((PCRE2_SPTR8)regexstr, PCRE2_ZERO_TERMINATED, 0, &en, &eo, NULL);
94  if (pxd->regex == NULL) {
95  PCRE2_UCHAR buffer[256];
96  pcre2_get_error_message(en, buffer, sizeof(buffer));
98  "pcre2 compile of \"%s\" failed at "
99  "offset %d: %s",
100  regexstr, (int)eo, buffer);
101  SCFree(pxd);
102  SCReturnInt(-1);
103  }
104  // check pcd->regex has exactly one capture expression
105  uint32_t nb;
106  if (pcre2_pattern_info(pxd->regex, PCRE2_INFO_CAPTURECOUNT, &nb) < 0) {
107  SCLogError(SC_ERR_INVALID_SIGNATURE, "pcrexform failed getting info about capturecount");
108  DetectTransformPcrexformFree(de_ctx, pxd);
109  SCReturnInt(-1);
110  }
111  if (nb != 1) {
113  "pcrexform needs exactly one substring capture, found %" PRIu32, nb);
114  DetectTransformPcrexformFree(de_ctx, pxd);
115  SCReturnInt(-1);
116  }
117 
119  if (r != 0) {
120  DetectTransformPcrexformFree(de_ctx, pxd);
121  }
122 
123  SCReturnInt(r);
124 }
125 
126 static void DetectTransformPcrexform(InspectionBuffer *buffer, void *options)
127 {
128  const char *input = (const char *)buffer->inspect;
129  const uint32_t input_len = buffer->inspect_len;
130  DetectTransformPcrexformData *pxd = options;
131 
132  pcre2_match_data *match = pcre2_match_data_create_from_pattern(pxd->regex, NULL);
133  int ret = pcre2_match(pxd->regex, (PCRE2_SPTR8)input, input_len, 0, 0, match, NULL);
134 
135  if (ret > 0) {
136  const char *str;
137  PCRE2_SIZE caplen;
138  ret = pcre2_substring_get_bynumber(match, 1, (PCRE2_UCHAR8 **)&str, &caplen);
139 
140  if (ret >= 0) {
141  InspectionBufferCopy(buffer, (uint8_t *)str, (uint32_t)caplen);
142  pcre2_substring_free((PCRE2_UCHAR8 *)str);
143  }
144  }
145  pcre2_match_data_free(match);
146 }
147 
148 #ifdef UNITTESTS
150 #endif
SigTableElmt_::url
const char * url
Definition: detect.h:1204
SC_ERR_PCRE_COMPILE
@ SC_ERR_PCRE_COMPILE
Definition: util-error.h:35
detect-engine.h
SigTableElmt_::desc
const char * desc
Definition: detect.h:1203
SigTableElmt_::Free
void(* Free)(DetectEngineCtx *, void *)
Definition: detect.h:1191
SigTableElmt_::name
const char * name
Definition: detect.h:1201
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:298
InspectionBuffer
Definition: detect.h:344
SigTableElmt_::flags
uint16_t flags
Definition: detect.h:1195
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:758
SC_ERR_INVALID_SIGNATURE
@ SC_ERR_INVALID_SIGNATURE
Definition: util-error.h:69
DetectTransformPcrexformData
struct DetectTransformPcrexformData DetectTransformPcrexformData
SigTableElmt_::Setup
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1186
SIGMATCH_QUOTES_MANDATORY
#define SIGMATCH_QUOTES_MANDATORY
Definition: detect.h:1389
detect-transform-pcrexform.h
DetectTransformPcrexformData::regex
pcre2_code * regex
Definition: detect-transform-pcrexform.c:34
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:17
DETECT_TRANSFORM_PCREXFORM
@ DETECT_TRANSFORM_PCREXFORM
Definition: detect-engine-register.h:299
SCEnter
#define SCEnter(...)
Definition: util-debug.h:300
detect.h
DetectTransformPcrexformData
Definition: detect-transform-pcrexform.c:33
DetectTransformPcrexformRegister
void DetectTransformPcrexformRegister(void)
Definition: detect-transform-pcrexform.c:44
DetectTransformPcrexformRegisterTests
void DetectTransformPcrexformRegisterTests(void)
this function registers unit tests for DetectTransformPcrexform
Definition: detect-transform-pcrexform.c:81
InspectionBufferCopy
void InspectionBufferCopy(InspectionBuffer *buffer, uint8_t *buf, uint32_t buf_len)
Definition: detect-engine.c:1138
detect-transform-pcrexform.c
suricata-common.h
sigmatch_table
SigTableElmt sigmatch_table[DETECT_TBLSIZE]
Definition: detect-parse.c:73
SigTableElmt_::Transform
void(* Transform)(InspectionBuffer *, void *context)
Definition: detect.h:1182
SCLogError
#define SCLogError(err_code,...)
Macro used to log ERROR messages.
Definition: util-debug.h:257
InspectionBuffer::inspect_len
uint32_t inspect_len
Definition: detect.h:347
InspectionBuffer::inspect
const uint8_t * inspect
Definition: detect.h:345
str
#define str(s)
Definition: suricata-common.h:272
SCFree
#define SCFree(p)
Definition: util-mem.h:61
detect-parse.h
Signature_
Signature container.
Definition: detect.h:517
DetectSignatureAddTransform
int DetectSignatureAddTransform(Signature *s, int transform, void *options)
Definition: detect-parse.c:1464
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
SCReturnInt
#define SCReturnInt(x)
Definition: util-debug.h:304
SigTableElmt_::RegisterTests
void(* RegisterTests)(void)
Definition: detect.h:1193