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 #include "detect-engine-build.h"
25 
26 #include "util-unittest.h"
27 
28 static int DetectBase64DataSetup(DetectEngineCtx *, Signature *, const char *);
29 #ifdef UNITTESTS
30 static void DetectBase64DataRegisterTests(void);
31 #endif
32 
34 {
35  sigmatch_table[DETECT_BASE64_DATA].name = "base64_data";
37  "Content match base64 decoded data.";
39  "/rules/base64-keywords.html#base64-data";
40  sigmatch_table[DETECT_BASE64_DATA].Setup = DetectBase64DataSetup;
41 #ifdef UNITTESTS
43  DetectBase64DataRegisterTests;
44 #endif
46 }
47 
48 static int DetectBase64DataSetup(DetectEngineCtx *de_ctx, Signature *s,
49  const char *str)
50 {
51  SigMatch *pm = NULL;
52 
53  /* Check for a preceding base64_decode. */
55  if (pm == NULL) {
56  SCLogError("\"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 static int g_file_data_buffer_id = 0;
80 
81 static int DetectBase64DataSetupTest01(void)
82 {
83  DetectEngineCtx *de_ctx = NULL;
84  SigMatch *sm;
85  int retval = 0;
86 
88  if (de_ctx == NULL) {
89  goto end;
90  }
91 
92  de_ctx->flags |= DE_QUIET;
94  "alert smtp any any -> any any (msg:\"DetectBase64DataSetupTest\"; "
95  "base64_decode; base64_data; content:\"content\"; sid:1; rev:1;)");
96  if (de_ctx->sig_list == NULL) {
97  printf("SigInit failed: ");
98  goto end;
99  }
100 
101  sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH];
102  if (sm == NULL) {
103  printf("DETECT_SM_LIST_PMATCH should not be NULL: ");
104  goto end;
105  }
106  if (sm->type != DETECT_BASE64_DECODE) {
107  printf("sm->type should be DETECT_BASE64_DECODE: ");
108  goto end;
109  }
110 
111  if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_BASE64_DATA] == NULL) {
112  printf("DETECT_SM_LIST_BASE64_DATA should not be NULL: ");
113  goto end;
114  }
115 
116  retval = 1;
117 end:
118  if (de_ctx != NULL) {
122  }
123  return retval;
124 }
125 
126 static int DetectBase64DataSetupTest02(void)
127 {
128  DetectEngineCtx *de_ctx = NULL;
129  SigMatch *sm;
130  int retval = 0;
131 
133  if (de_ctx == NULL) {
134  goto end;
135  }
136 
137  de_ctx->flags |= DE_QUIET;
139  "alert smtp any any -> any any ( "
140  "msg:\"DetectBase64DataSetupTest\"; "
141  "file_data; "
142  "content:\"SGV\"; "
143  "base64_decode: bytes 16; "
144  "base64_data; "
145  "content:\"content\"; "
146  "sid:1; rev:1;)");
147  if (de_ctx->sig_list == NULL) {
148  printf("SigInit failed: ");
149  goto end;
150  }
151 
152  sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH];
153  if (sm != NULL) {
154  printf("DETECT_SM_LIST_PMATCH is not NULL: ");
155  goto end;
156  }
157 
158  sm = de_ctx->sig_list->sm_lists[g_file_data_buffer_id];
159  if (sm == NULL) {
160  printf("DETECT_SM_LIST_FILEDATA is NULL: ");
161  goto end;
162  }
163 
164  sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_BASE64_DATA];
165  if (sm == NULL) {
166  printf("DETECT_SM_LIST_BASE64_DATA is NULL: ");
167  goto end;
168  }
169 
170  retval = 1;
171 end:
172  if (de_ctx != NULL) {
176  }
177  return retval;
178 }
179 
180 /**
181  * \test Test that the rule fails to load if the detection list is
182  * changed after base64_data.
183  */
184 static int DetectBase64DataSetupTest03(void)
185 {
186  DetectEngineCtx *de_ctx = NULL;
187  int retval = 0;
188 
190  if (de_ctx == NULL) {
191  goto end;
192  }
193 
194  de_ctx->flags |= DE_QUIET;
196  "alert smtp any any -> any any ( "
197  "msg:\"DetectBase64DataSetupTest\"; "
198  "base64_decode: bytes 16; "
199  "base64_data; "
200  "content:\"content\"; "
201  "file_data; "
202  "content:\"SGV\"; "
203  "sid:1; rev:1;)");
204  if (de_ctx->sig_list != NULL) {
205  printf("SigInit should have failed: ");
206  goto end;
207  }
208 
209  retval = 1;
210 end:
211  if (de_ctx != NULL) {
215  }
216  return retval;
217 }
218 
219 /**
220  * \test Test that the list can be changed to post-detection lists
221  * after the base64 keyword.
222  */
223 static int DetectBase64DataSetupTest04(void)
224 {
225  DetectEngineCtx *de_ctx = NULL;
226  int retval = 0;
227 
229  if (de_ctx == NULL) {
230  goto end;
231  }
232 
233  de_ctx->flags |= DE_QUIET;
235  "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;)");
236  if (de_ctx->sig_list == NULL) {
237  printf("SigInit failed: ");
238  goto end;
239  }
240 
241  retval = 1;
242 end:
243  if (de_ctx != NULL) {
247  }
248  return retval;
249 }
250 
251 static void DetectBase64DataRegisterTests(void)
252 {
253  g_file_data_buffer_id = DetectBufferTypeGetByName("file_data");
254 
255  UtRegisterTest("DetectBase64DataSetupTest01", DetectBase64DataSetupTest01);
256  UtRegisterTest("DetectBase64DataSetupTest02", DetectBase64DataSetupTest02);
257  UtRegisterTest("DetectBase64DataSetupTest03", DetectBase64DataSetupTest03);
258  UtRegisterTest("DetectBase64DataSetupTest04", DetectBase64DataSetupTest04);
259 }
260 #endif /* UNITTESTS */
SigTableElmt_::url
const char * url
Definition: detect.h:1241
detect-engine.h
DETECT_SM_LIST_PMATCH
@ DETECT_SM_LIST_PMATCH
Definition: detect.h:79
SigTableElmt_::desc
const char * desc
Definition: detect.h:1240
DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE
@ DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE
Definition: detect-engine-content-inspection.h:36
SigTableElmt_::name
const char * name
Definition: detect.h:1238
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:103
Flow_
Flow data structure.
Definition: flow.h:357
SigTableElmt_::flags
uint16_t flags
Definition: detect.h:1232
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:785
DetectEngineCtxFree
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
Definition: detect-engine.c:2442
DE_QUIET
#define DE_QUIET
Definition: detect.h:287
DETECT_BASE64_DATA
@ DETECT_BASE64_DATA
Definition: detect-engine-register.h:251
Signature_::sm_arrays
SigMatchData * sm_arrays[DETECT_SM_LIST_MAX]
Definition: detect.h:595
SigCleanSignatures
void SigCleanSignatures(DetectEngineCtx *de_ctx)
Definition: detect-engine-build.c:46
SigTableElmt_::Setup
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1223
util-unittest.h
DetectBufferTypeGetByName
int DetectBufferTypeGetByName(const char *name)
Definition: detect-engine.c:1079
detect-base64-data.h
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:17
DetectEngineThreadCtx_
Definition: detect.h:1025
DETECT_SM_LIST_BASE64_DATA
@ DETECT_SM_LIST_BASE64_DATA
Definition: detect.h:84
SignatureInitData_::list
int list
Definition: detect.h:517
detect.h
DetectBase64DataDoMatch
int DetectBase64DataDoMatch(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, const Signature *s, Flow *f)
Definition: detect-base64-data.c:64
SigInit
Signature * SigInit(DetectEngineCtx *de_ctx, const char *sigstr)
Parses a signature and adds it to the Detection Engine Context.
Definition: detect-parse.c:2129
DetectEngineThreadCtx_::base64_decoded_len
int base64_decoded_len
Definition: detect.h:1168
SigGroupCleanup
int SigGroupCleanup(DetectEngineCtx *de_ctx)
Definition: detect-engine-build.c:2019
detect-engine-build.h
Signature_::init_data
SignatureInitData * init_data
Definition: detect.h:611
detect-engine-content-inspection.h
DetectEngineContentInspection
uint8_t 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:106
DETECT_CI_FLAGS_SINGLE
#define DETECT_CI_FLAGS_SINGLE
Definition: detect-engine-content-inspection.h:47
DetectBase64DataRegister
void DetectBase64DataRegister(void)
Definition: detect-base64-data.c:33
suricata-common.h
SigMatch_::type
uint16_t type
Definition: detect.h:314
sigmatch_table
SigTableElmt sigmatch_table[DETECT_TBLSIZE]
Definition: detect-parse.c:76
DetectEngineCtx_::sig_list
Signature * sig_list
Definition: detect.h:791
str
#define str(s)
Definition: suricata-common.h:280
SCLogError
#define SCLogError(...)
Macro used to log ERROR messages.
Definition: util-debug.h:261
detect-parse.h
Signature_
Signature container.
Definition: detect.h:540
SigMatch_
a single match condition for a signature
Definition: detect.h:313
DetectEngineCtxInit
DetectEngineCtx * DetectEngineCtxInit(void)
Definition: detect-engine.c:2403
DetectEngineThreadCtx_::base64_decoded
uint8_t * base64_decoded
Definition: detect.h:1167
DETECT_BASE64_DECODE
@ DETECT_BASE64_DECODE
Definition: detect-engine-register.h:250
SIGMATCH_NOOPT
#define SIGMATCH_NOOPT
Definition: detect.h:1423
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:474
DetectEngineCtx_::flags
uint8_t flags
Definition: detect.h:786
SigTableElmt_::RegisterTests
void(* RegisterTests)(void)
Definition: detect.h:1230