suricata
detect-base64-data.c
Go to the documentation of this file.
1 /* Copyright (C) 2015 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 #include "suricata-common.h"
19 #include "detect.h"
20 #include "detect-engine.h"
22 #include "detect-parse.h"
23 #include "detect-base64-data.h"
24 
25 #include "util-unittest.h"
26 
27 static int DetectBase64DataSetup(DetectEngineCtx *, Signature *, const char *);
28 #ifdef UNITTESTS
29 static void DetectBase64DataRegisterTests(void);
30 #endif
31 
33 {
34  sigmatch_table[DETECT_BASE64_DATA].name = "base64_data";
36  "Content match base64 decoded data.";
38  "/rules/base64-keywords.html#base64-data";
39  sigmatch_table[DETECT_BASE64_DATA].Setup = DetectBase64DataSetup;
40 #ifdef UNITTESTS
42  DetectBase64DataRegisterTests;
43 #endif
45 }
46 
47 static int DetectBase64DataSetup(DetectEngineCtx *de_ctx, Signature *s,
48  const char *str)
49 {
50  SigMatch *pm = NULL;
51 
52  /* Check for a preceding base64_decode. */
54  if (pm == NULL) {
56  "\"base64_data\" keyword seen without preceding base64_decode.");
57  return -1;
58  }
59 
61  return 0;
62 }
63 
65  DetectEngineThreadCtx *det_ctx, const Signature *s, Flow *f)
66 {
67  if (det_ctx->base64_decoded_len) {
68  return DetectEngineContentInspection(de_ctx, det_ctx, s,
72  }
73 
74  return 0;
75 }
76 
77 #ifdef UNITTESTS
78 
79 #include "detect-engine.h"
80 
81 static int g_file_data_buffer_id = 0;
82 
83 static int DetectBase64DataSetupTest01(void)
84 {
85  DetectEngineCtx *de_ctx = NULL;
86  SigMatch *sm;
87  int retval = 0;
88 
90  if (de_ctx == NULL) {
91  goto end;
92  }
93 
94  de_ctx->flags |= DE_QUIET;
96  "alert smtp any any -> any any (msg:\"DetectBase64DataSetupTest\"; "
97  "base64_decode; base64_data; content:\"content\"; sid:1; rev:1;)");
98  if (de_ctx->sig_list == NULL) {
99  printf("SigInit failed: ");
100  goto end;
101  }
102 
103  sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH];
104  if (sm == NULL) {
105  printf("DETECT_SM_LIST_PMATCH should not be NULL: ");
106  goto end;
107  }
108  if (sm->type != DETECT_BASE64_DECODE) {
109  printf("sm->type should be DETECT_BASE64_DECODE: ");
110  goto end;
111  }
112 
113  if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_BASE64_DATA] == NULL) {
114  printf("DETECT_SM_LIST_BASE64_DATA should not be NULL: ");
115  goto end;
116  }
117 
118  retval = 1;
119 end:
120  if (de_ctx != NULL) {
124  }
125  return retval;
126 }
127 
128 static int DetectBase64DataSetupTest02(void)
129 {
130  DetectEngineCtx *de_ctx = NULL;
131  SigMatch *sm;
132  int retval = 0;
133 
135  if (de_ctx == NULL) {
136  goto end;
137  }
138 
139  de_ctx->flags |= DE_QUIET;
141  "alert smtp any any -> any any ( "
142  "msg:\"DetectBase64DataSetupTest\"; "
143  "file_data; "
144  "content:\"SGV\"; "
145  "base64_decode: bytes 16; "
146  "base64_data; "
147  "content:\"content\"; "
148  "sid:1; rev:1;)");
149  if (de_ctx->sig_list == NULL) {
150  printf("SigInit failed: ");
151  goto end;
152  }
153 
154  sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH];
155  if (sm != NULL) {
156  printf("DETECT_SM_LIST_PMATCH is not NULL: ");
157  goto end;
158  }
159 
160  sm = de_ctx->sig_list->sm_lists[g_file_data_buffer_id];
161  if (sm == NULL) {
162  printf("DETECT_SM_LIST_FILEDATA is NULL: ");
163  goto end;
164  }
165 
166  sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_BASE64_DATA];
167  if (sm == NULL) {
168  printf("DETECT_SM_LIST_BASE64_DATA is NULL: ");
169  goto end;
170  }
171 
172  retval = 1;
173 end:
174  if (de_ctx != NULL) {
178  }
179  return retval;
180 }
181 
182 /**
183  * \test Test that the rule fails to load if the detection list is
184  * changed after base64_data.
185  */
186 static int DetectBase64DataSetupTest03(void)
187 {
188  DetectEngineCtx *de_ctx = NULL;
189  int retval = 0;
190 
192  if (de_ctx == NULL) {
193  goto end;
194  }
195 
196  de_ctx->flags |= DE_QUIET;
198  "alert smtp any any -> any any ( "
199  "msg:\"DetectBase64DataSetupTest\"; "
200  "base64_decode: bytes 16; "
201  "base64_data; "
202  "content:\"content\"; "
203  "file_data; "
204  "content:\"SGV\"; "
205  "sid:1; rev:1;)");
206  if (de_ctx->sig_list != NULL) {
207  printf("SigInit should have failed: ");
208  goto end;
209  }
210 
211  retval = 1;
212 end:
213  if (de_ctx != NULL) {
217  }
218  return retval;
219 }
220 
221 /**
222  * \test Test that the list can be changed to post-detection lists
223  * after the base64 keyword.
224  */
225 static int DetectBase64DataSetupTest04(void)
226 {
227  DetectEngineCtx *de_ctx = NULL;
228  int retval = 0;
229 
231  if (de_ctx == NULL) {
232  goto end;
233  }
234 
235  de_ctx->flags |= DE_QUIET;
237  "alert tcp any any -> any any (msg:\"some b64thing\"; flow:established,from_server; file_data; content:\"sometext\"; fast_pattern; base64_decode:relative; base64_data; content:\"foobar\"; nocase; tag:session,120,seconds; sid:1111111; rev:1;)");
238  if (de_ctx->sig_list == NULL) {
239  printf("SigInit failed: ");
240  goto end;
241  }
242 
243  retval = 1;
244 end:
245  if (de_ctx != NULL) {
249  }
250  return retval;
251 }
252 
253 static void DetectBase64DataRegisterTests(void)
254 {
255  g_file_data_buffer_id = DetectBufferTypeGetByName("file_data");
256 
257  UtRegisterTest("DetectBase64DataSetupTest01", DetectBase64DataSetupTest01);
258  UtRegisterTest("DetectBase64DataSetupTest02", DetectBase64DataSetupTest02);
259  UtRegisterTest("DetectBase64DataSetupTest03", DetectBase64DataSetupTest03);
260  UtRegisterTest("DetectBase64DataSetupTest04", DetectBase64DataSetupTest04);
261 }
262 #endif /* UNITTESTS */
SigTableElmt_::url
const char * url
Definition: detect.h:1213
detect-engine.h
DETECT_SM_LIST_PMATCH
@ DETECT_SM_LIST_PMATCH
Definition: detect.h:90
SigTableElmt_::desc
const char * desc
Definition: detect.h:1212
SigTableElmt_::name
const char * name
Definition: detect.h:1210
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:103
Flow_
Flow data structure.
Definition: flow.h:347
SigInit
Signature * SigInit(DetectEngineCtx *, const char *)
Parses a signature and adds it to the Detection Engine Context.
Definition: detect-parse.c:2039
SigTableElmt_::flags
uint16_t flags
Definition: detect.h:1204
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:766
SC_ERR_INVALID_SIGNATURE
@ SC_ERR_INVALID_SIGNATURE
Definition: util-error.h:69
DetectEngineCtxFree
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
Definition: detect-engine.c:2093
DE_QUIET
#define DE_QUIET
Definition: detect.h:293
DETECT_BASE64_DATA
@ DETECT_BASE64_DATA
Definition: detect-engine-register.h:238
Signature_::sm_arrays
SigMatchData * sm_arrays[DETECT_SM_LIST_MAX]
Definition: detect.h:580
SigCleanSignatures
void SigCleanSignatures(DetectEngineCtx *de_ctx)
Definition: detect-engine-build.c:39
DetectEngineContentInspection
int DetectEngineContentInspection(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, const Signature *s, const SigMatchData *smd, Packet *p, Flow *f, const uint8_t *buffer, uint32_t buffer_len, uint32_t stream_start_offset, uint8_t flags, uint8_t inspection_mode)
Run the actual payload match functions.
Definition: detect-engine-content-inspection.c:104
SigTableElmt_::Setup
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1195
util-unittest.h
DetectBufferTypeGetByName
int DetectBufferTypeGetByName(const char *name)
Definition: detect-engine.c:880
detect-base64-data.h
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:17
DetectEngineThreadCtx_
Definition: detect.h:1009
DETECT_SM_LIST_BASE64_DATA
@ DETECT_SM_LIST_BASE64_DATA
Definition: detect.h:95
SignatureInitData_::list
int list
Definition: detect.h:504
detect.h
DetectBase64DataDoMatch
int DetectBase64DataDoMatch(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, const Signature *s, Flow *f)
Definition: detect-base64-data.c:64
DetectEngineThreadCtx_::base64_decoded_len
int base64_decoded_len
Definition: detect.h:1144
SigGroupCleanup
int SigGroupCleanup(DetectEngineCtx *de_ctx)
Definition: detect-engine-build.c:1943
Signature_::init_data
SignatureInitData * init_data
Definition: detect.h:596
SigMatch_::type
uint8_t type
Definition: detect.h:320
detect-engine-content-inspection.h
DETECT_CI_FLAGS_SINGLE
#define DETECT_CI_FLAGS_SINGLE
Definition: detect-engine-content-inspection.h:46
DetectBase64DataRegister
void DetectBase64DataRegister(void)
Definition: detect-base64-data.c:32
suricata-common.h
sigmatch_table
SigTableElmt sigmatch_table[DETECT_TBLSIZE]
Definition: detect-parse.c:73
SCLogError
#define SCLogError(err_code,...)
Macro used to log ERROR messages.
Definition: util-debug.h:257
DetectEngineCtx_::sig_list
Signature * sig_list
Definition: detect.h:772
str
#define str(s)
Definition: suricata-common.h:273
detect-parse.h
Signature_
Signature container.
Definition: detect.h:527
SigMatch_
a single match condition for a signature
Definition: detect.h:319
DetectEngineCtxInit
DetectEngineCtx * DetectEngineCtxInit(void)
Definition: detect-engine.c:2048
DetectEngineThreadCtx_::base64_decoded
uint8_t * base64_decoded
Definition: detect.h:1143
DETECT_BASE64_DECODE
@ DETECT_BASE64_DECODE
Definition: detect-engine-register.h:237
SIGMATCH_NOOPT
#define SIGMATCH_NOOPT
Definition: detect.h:1379
DetectGetLastSMFromLists
SigMatch * DetectGetLastSMFromLists(const Signature *s,...)
Returns the sm with the largest index (added latest) from the lists passed to us.
Definition: detect-parse.c:468
DetectEngineCtx_::flags
uint8_t flags
Definition: detect.h:767
DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE
@ DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE
Definition: detect-engine-content-inspection.h:35
SigTableElmt_::RegisterTests
void(* RegisterTests)(void)
Definition: detect.h:1202