suricata
detect-transform-xor.c
Go to the documentation of this file.
1 /* Copyright (C) 2021 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 Philippe Antoine <contact@catenacyber.fr>
22  *
23  * Implements the xor transform keyword with option support
24  */
25 
26 #include "suricata-common.h"
27 #include "detect.h"
28 #include "detect-engine.h"
29 #include "detect-parse.h"
30 #include "detect-transform-xor.h"
31 
32 typedef struct DetectTransformXorData {
33  uint8_t *key;
34  // limit the key length
35  uint8_t length;
37 
38 static int DetectTransformXorSetup(DetectEngineCtx *, Signature *, const char *);
39 static void DetectTransformXorFree(DetectEngineCtx *, void *);
40 static void DetectTransformXor(InspectionBuffer *buffer, void *options);
41 #ifdef UNITTESTS
43 #endif
44 
46 {
48  sigmatch_table[DETECT_TRANSFORM_XOR].desc = "modify buffer via XOR decoding before inspection";
49  sigmatch_table[DETECT_TRANSFORM_XOR].url = "/rules/transforms.html#xor";
50  sigmatch_table[DETECT_TRANSFORM_XOR].Transform = DetectTransformXor;
51  sigmatch_table[DETECT_TRANSFORM_XOR].Free = DetectTransformXorFree;
52  sigmatch_table[DETECT_TRANSFORM_XOR].Setup = DetectTransformXorSetup;
53 #ifdef UNITTESTS
55 #endif
57 }
58 
59 static void DetectTransformXorFree(DetectEngineCtx *de_ctx, void *ptr)
60 {
61  if (ptr != NULL) {
63  SCFree(pxd->key);
64  SCFree(pxd);
65  }
66 }
67 
68 /**
69  * \internal
70  * \brief Apply the xor keyword to the last pattern match
71  * \param det_ctx detection engine ctx
72  * \param s signature
73  * \param optstr options string
74  * \retval 0 ok
75  * \retval -1 failure
76  */
77 static int DetectTransformXorSetup(DetectEngineCtx *de_ctx, Signature *s, const char *optstr)
78 {
79  SCEnter();
80 
81  // Create pxd from optstr
82  DetectTransformXorData *pxd = SCCalloc(1, sizeof(*pxd));
83  if (pxd == NULL) {
84  SCLogError(SC_ERR_MEM_ALLOC, "memory allocation failed");
85  SCReturnInt(-1);
86  }
87 
88  size_t keylen = strlen(optstr);
89  if (keylen % 2 == 1) {
90  SCLogError(SC_ERR_INVALID_SIGNATURE, "XOR transform key's length must be an even number");
91  DetectTransformXorFree(de_ctx, pxd);
92  SCReturnInt(-1);
93  }
94  if (keylen / 2 > UINT8_MAX) {
95  SCLogError(SC_ERR_INVALID_SIGNATURE, "Key length too big for XOR transform");
96  DetectTransformXorFree(de_ctx, pxd);
97  SCReturnInt(-1);
98  }
99  pxd->length = (uint8_t)(keylen / 2);
100  pxd->key = SCMalloc(keylen / 2);
101  if (pxd->key == NULL) {
102  SCLogError(SC_ERR_MEM_ALLOC, "memory allocation failed");
103  DetectTransformXorFree(de_ctx, pxd);
104  SCReturnInt(-1);
105  }
106  for (size_t i = 0; i < keylen / 2; i++) {
107  if ((isxdigit(optstr[2 * i])) && (isxdigit(optstr[2 * i + 1]))) {
108  pxd->key[i] = (uint8_t)((optstr[2 * i] >= 'A' ? ((optstr[2 * i] & 0xdf) - 'A') + 10
109  : (optstr[2 * i] - '0'))
110  << 4);
111  pxd->key[i] |= (optstr[2 * i + 1] >= 'A' ? ((optstr[2 * i + 1] & 0xdf) - 'A') + 10
112  : (optstr[2 * i + 1] - '0'));
113  } else {
115  "XOR transform key must be hexadecimal characters only");
116  DetectTransformXorFree(de_ctx, pxd);
117  SCReturnInt(-1);
118  }
119  }
120 
122  if (r != 0) {
123  DetectTransformXorFree(de_ctx, pxd);
124  }
125 
126  SCReturnInt(r);
127 }
128 
129 static void DetectTransformXor(InspectionBuffer *buffer, void *options)
130 {
131  const uint8_t *input = buffer->inspect;
132  const uint32_t input_len = buffer->inspect_len;
133  DetectTransformXorData *pxd = options;
134  if (input_len == 0) {
135  return;
136  }
137  uint8_t output[input_len];
138 
139  for (uint32_t i = 0; i < input_len; i++) {
140  output[i] = input[i] ^ pxd->key[i % pxd->length];
141  }
142  InspectionBufferCopy(buffer, output, input_len);
143 }
144 
145 #ifdef UNITTESTS
147 #endif
SigTableElmt_::url
const char * url
Definition: detect.h:1248
detect-transform-xor.h
detect-engine.h
SigTableElmt_::desc
const char * desc
Definition: detect.h:1247
SigTableElmt_::Free
void(* Free)(DetectEngineCtx *, void *)
Definition: detect.h:1235
SigTableElmt_::name
const char * name
Definition: detect.h:1245
InspectionBuffer
Definition: detect.h:338
SigTableElmt_::flags
uint16_t flags
Definition: detect.h:1239
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:785
SC_ERR_INVALID_SIGNATURE
@ SC_ERR_INVALID_SIGNATURE
Definition: util-error.h:69
DetectTransformXorData
struct DetectTransformXorData DetectTransformXorData
DetectTransformXorRegisterTests
void DetectTransformXorRegisterTests(void)
this function registers unit tests for DetectTransformXor
Definition: detect-transform-xor.c:63
DETECT_TRANSFORM_XOR
@ DETECT_TRANSFORM_XOR
Definition: detect-engine-register.h:319
SigTableElmt_::Setup
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1230
SIGMATCH_QUOTES_MANDATORY
#define SIGMATCH_QUOTES_MANDATORY
Definition: detect.h:1447
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:17
SCEnter
#define SCEnter(...)
Definition: util-debug.h:298
detect.h
DetectTransformXorData::key
uint8_t * key
Definition: detect-transform-xor.c:33
InspectionBufferCopy
void InspectionBufferCopy(InspectionBuffer *buffer, uint8_t *buf, uint32_t buf_len)
Definition: detect-engine.c:1497
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:1226
SCLogError
#define SCLogError(err_code,...)
Macro used to log ERROR messages.
Definition: util-debug.h:255
SCMalloc
#define SCMalloc(sz)
Definition: util-mem.h:47
InspectionBuffer::inspect_len
uint32_t inspect_len
Definition: detect.h:341
InspectionBuffer::inspect
const uint8_t * inspect
Definition: detect.h:339
SCFree
#define SCFree(p)
Definition: util-mem.h:61
detect-parse.h
Signature_
Signature container.
Definition: detect.h:540
DetectSignatureAddTransform
int DetectSignatureAddTransform(Signature *s, int transform, void *options)
Definition: detect-parse.c:1465
DetectTransformXorData
Definition: detect-transform-xor.c:32
SC_ERR_MEM_ALLOC
@ SC_ERR_MEM_ALLOC
Definition: util-error.h:31
detect-transform-xor.c
DetectTransformXorData::length
uint8_t length
Definition: detect-transform-xor.c:35
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
SCReturnInt
#define SCReturnInt(x)
Definition: util-debug.h:302
SigTableElmt_::RegisterTests
void(* RegisterTests)(void)
Definition: detect.h:1237
DetectTransformXorRegister
void DetectTransformXorRegister(void)
Definition: detect-transform-xor.c:45