suricata
detect-dce-iface.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-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 Anoop Saldanha <anoopsaldanha@gmail.com>
22  *
23  * Implements dce_iface keyword.
24  */
25 
26 #include "suricata-common.h"
27 
28 #include "detect.h"
29 #include "detect-parse.h"
30 
31 #include "detect-engine.h"
32 #include "detect-engine-mpm.h"
33 #include "detect-engine-state.h"
34 #include "detect-dce-iface.h"
35 
36 #include "flow.h"
37 #include "flow-var.h"
38 #include "flow-util.h"
39 
40 #include "app-layer.h"
41 #include "app-layer-dcerpc.h"
42 #include "queue.h"
43 #include "stream-tcp-reassemble.h"
44 
45 #include "util-debug.h"
46 #include "util-unittest.h"
47 #include "util-unittest-helper.h"
48 #include "stream-tcp.h"
49 
50 #include "rust.h"
51 
52 #define PARSE_REGEX "^\\s*([0-9a-zA-Z]{8}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{12})(?:\\s*,\\s*(<|>|=|!)([0-9]{1,5}))?(?:\\s*,\\s*(any_frag))?\\s*$"
53 
54 static DetectParseRegex parse_regex;
55 
56 static int DetectDceIfaceMatchRust(DetectEngineThreadCtx *det_ctx,
57  Flow *f, uint8_t flags, void *state, void *txv,
58  const Signature *s, const SigMatchCtx *m);
59 static int DetectDceIfaceSetup(DetectEngineCtx *, Signature *, const char *);
60 static void DetectDceIfaceFree(DetectEngineCtx *, void *);
61 #ifdef UNITTESTS
62 static void DetectDceIfaceRegisterTests(void);
63 #endif
64 static int g_dce_generic_list_id = 0;
65 
66 static int InspectDceGeneric(ThreadVars *tv,
68  const Signature *s, const SigMatchData *smd,
69  Flow *f, uint8_t flags, void *alstate,
70  void *txv, uint64_t tx_id);
71 
72 /**
73  * \brief Registers the keyword handlers for the "dce_iface" keyword.
74  */
76 {
77  sigmatch_table[DETECT_DCE_IFACE].name = "dcerpc.iface";
78  sigmatch_table[DETECT_DCE_IFACE].alias = "dce_iface";
79  sigmatch_table[DETECT_DCE_IFACE].AppLayerTxMatch = DetectDceIfaceMatchRust;
80  sigmatch_table[DETECT_DCE_IFACE].Setup = DetectDceIfaceSetup;
81  sigmatch_table[DETECT_DCE_IFACE].Free = DetectDceIfaceFree;
82 #ifdef UNITTESTS
83  sigmatch_table[DETECT_DCE_IFACE].RegisterTests = DetectDceIfaceRegisterTests;
84 #endif
85  DetectSetupParseRegexes(PARSE_REGEX, &parse_regex);
86 
87  g_dce_generic_list_id = DetectBufferTypeRegister("dce_generic");
88 
90  ALPROTO_DCERPC, SIG_FLAG_TOSERVER, 0, InspectDceGeneric);
92  ALPROTO_SMB, SIG_FLAG_TOSERVER, 0, InspectDceGeneric);
93 
95  ALPROTO_DCERPC, SIG_FLAG_TOCLIENT, 0, InspectDceGeneric);
97  ALPROTO_SMB, SIG_FLAG_TOCLIENT, 0, InspectDceGeneric);
98 }
99 
100 static int InspectDceGeneric(ThreadVars *tv,
102  const Signature *s, const SigMatchData *smd,
103  Flow *f, uint8_t flags, void *alstate,
104  void *txv, uint64_t tx_id)
105 {
106  return DetectEngineInspectGenericList(tv, de_ctx, det_ctx, s, smd,
107  f, flags, alstate, txv, tx_id);
108 }
109 
110 /**
111  * \brief App layer match function for the "dce_iface" keyword.
112  *
113  * \param t Pointer to the ThreadVars instance.
114  * \param det_ctx Pointer to the DetectEngineThreadCtx.
115  * \param f Pointer to the flow.
116  * \param flags Pointer to the flags indicating the flow direction.
117  * \param state Pointer to the app layer state data.
118  * \param s Pointer to the Signature instance.
119  * \param m Pointer to the SigMatch.
120  *
121  * \retval 1 On Match.
122  * \retval 0 On no match.
123  */
124 static int DetectDceIfaceMatchRust(DetectEngineThreadCtx *det_ctx,
125  Flow *f, uint8_t flags, void *state, void *txv,
126  const Signature *s, const SigMatchCtx *m)
127 {
128  SCEnter();
129 
130  if (f->alproto == ALPROTO_DCERPC) {
131  // TODO check if state is NULL
132  return rs_dcerpc_iface_match(txv, state, (void *)m);
133  }
134 
135  int ret = 0;
136 
137  if (rs_smb_tx_get_dce_iface(f->alstate, txv, (void *)m) != 1) {
138  SCLogDebug("rs_smb_tx_get_dce_iface: didn't match");
139  } else {
140  SCLogDebug("rs_smb_tx_get_dce_iface: matched!");
141  ret = 1;
142  // TODO validate frag
143  }
144  SCReturnInt(ret);
145 }
146 
147 /**
148  * \brief Creates a SigMatch for the "dce_iface" keyword being sent as argument,
149  * and appends it to the Signature(s).
150  *
151  * \param de_ctx Pointer to the detection engine context.
152  * \param s Pointer to signature for the current Signature being parsed
153  * from the rules.
154  * \param arg Pointer to the string holding the keyword value.
155  *
156  * \retval 0 on success, -1 on failure.
157  */
158 
159 static int DetectDceIfaceSetup(DetectEngineCtx *de_ctx, Signature *s, const char *arg)
160 {
161  SCEnter();
162 
163  if (s->alproto != ALPROTO_UNKNOWN && s->alproto != ALPROTO_DCERPC &&
164  s->alproto != ALPROTO_SMB) {
165  SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains conflicting keywords.");
166  return -1;
167  }
168  void *did = rs_dcerpc_iface_parse(arg);
169  if (did == NULL) {
170  SCLogError(SC_ERR_INVALID_SIGNATURE, "Error parsing dce_iface option in "
171  "signature");
172  return -1;
173  }
174 
175  SigMatch *sm = SigMatchAlloc();
176  if (sm == NULL) {
177  return -1;
178  }
179 
180  sm->type = DETECT_DCE_IFACE;
181  sm->ctx = did;
182 
183  SigMatchAppendSMToList(s, sm, g_dce_generic_list_id);
184  return 0;
185 }
186 
187 static void DetectDceIfaceFree(DetectEngineCtx *de_ctx, void *ptr)
188 {
189  SCEnter();
190  if (ptr != NULL) {
191  rs_dcerpc_iface_free(ptr);
192  }
193  SCReturn;
194 }
195 
196 /************************************Unittests*********************************/
197 
198 #ifdef UNITTESTS
199 
200 /**
201  * \test Test a valid dce_iface entry for a bind and bind_ack
202  */
203 static int DetectDceIfaceTestParse1(void)
204 {
205  Signature *s = NULL;
206  ThreadVars th_v;
207  Packet *p = NULL;
208  Flow f;
209  TcpSession ssn;
210  DetectEngineThreadCtx *det_ctx = NULL;
211  DetectEngineCtx *de_ctx = NULL;
212  DCERPCState *dcerpc_state = NULL;
213  int r = 0;
214 
215  uint8_t dcerpc_bind[] = {
216  0x05, 0x00, 0x0b, 0x03, 0x10, 0x00, 0x00, 0x00,
217  0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
218  0xb8, 0x10, 0xb8, 0x10, 0x00, 0x00, 0x00, 0x00,
219  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
220  0x6a, 0x28, 0x19, 0x39, 0x0c, 0xb1, 0xd0, 0x11,
221  0x9b, 0xa8, 0x00, 0xc0, 0x4f, 0xd9, 0x2e, 0xf5,
222  0x00, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a,
223  0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00,
224  0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00,
225  };
226 
227  uint8_t dcerpc_bindack[] = {
228  0x05, 0x00, 0x0c, 0x03, 0x10, 0x00, 0x00, 0x00,
229  0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
230  0xb8, 0x10, 0xb8, 0x10, 0x26, 0x3d, 0x00, 0x00,
231  0x0c, 0x00, 0x5c, 0x50, 0x49, 0x50, 0x45, 0x5c,
232  0x6c, 0x73, 0x61, 0x73, 0x73, 0x00, 0x00, 0x00,
233  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
234  0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11,
235  0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60,
236  0x02, 0x00, 0x00, 0x00
237  };
238 
239  uint8_t dcerpc_request[] = {
240  0x05, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00,
241  0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
242  0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00,
243  0xad, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
244  };
245 
246  uint32_t dcerpc_bind_len = sizeof(dcerpc_bind);
247  uint32_t dcerpc_bindack_len = sizeof(dcerpc_bindack);
248  uint32_t dcerpc_request_len = sizeof(dcerpc_request);
249 
251 
252  memset(&th_v, 0, sizeof(th_v));
253  memset(&f, 0, sizeof(f));
254  memset(&ssn, 0, sizeof(ssn));
255 
256  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
257 
258  FLOW_INITIALIZE(&f);
259  f.protoctx = (void *)&ssn;
260  f.proto = IPPROTO_TCP;
261  p->flow = &f;
266 
268 
270  FAIL_IF(de_ctx == NULL);
271  de_ctx->flags |= DE_QUIET;
272 
273  s = DetectEngineAppendSig(de_ctx,"alert tcp any any -> any any "
274  "(msg:\"DCERPC\"; "
275  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5,=0,any_frag; "
276  "sid:1;)");
277  FAIL_IF(s == NULL);
278 
280  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
281 
282  SCLogDebug("handling to_server chunk");
283 
285  STREAM_TOSERVER | STREAM_START, dcerpc_bind,
286  dcerpc_bind_len);
287  FAIL_IF(r != 0);
288 
289  dcerpc_state = f.alstate;
290  FAIL_IF(dcerpc_state == NULL);
291 
292  /* do detect */
293  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
294  FAIL_IF(PacketAlertCheck(p, 1));
295 
296  SCLogDebug("handling to_client chunk");
297 
299  STREAM_TOCLIENT, dcerpc_bindack,
300  dcerpc_bindack_len);
301  FAIL_IF(r != 0);
302 
303  /* do detect */
304  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
305  FAIL_IF(PacketAlertCheck(p, 1));
306 
308  STREAM_TOSERVER, dcerpc_request,
309  dcerpc_request_len);
310  FAIL_IF(r != 0);
311 
312  /* do detect */
313  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
314 
315  FAIL_IF(!PacketAlertCheck(p, 1));
316  if (alp_tctx != NULL)
318  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
321  FLOW_DESTROY(&f);
322  UTHFreePackets(&p, 1);
323  PASS;
324 }
325 
326 /* Disabled because of bug_753. Would be enabled, once we rewrite
327  * dce parser */
328 #if 0
329 
330 /**
331  * \test Test a valid dce_iface entry with a bind, bind_ack and 3 request/responses.
332  */
333 static int DetectDceIfaceTestParse13(void)
334 {
335  int result = 0;
336  Signature *s = NULL;
337  ThreadVars th_v;
338  Packet *p = NULL;
339  Flow f;
340  TcpSession ssn;
341  DetectEngineThreadCtx *det_ctx = NULL;
342  DetectEngineCtx *de_ctx = NULL;
343  DCERPCState *dcerpc_state = NULL;
344  int r = 0;
345 
346  uint8_t dcerpc_bind[] = {
347  0x05, 0x00, 0x0b, 0x03, 0x10, 0x00, 0x00, 0x00,
348  0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
349  0xb8, 0x10, 0xb8, 0x10, 0x00, 0x00, 0x00, 0x00,
350  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
351  0x01, 0xd0, 0x8c, 0x33, 0x44, 0x22, 0xf1, 0x31,
352  0xaa, 0xaa, 0x90, 0x00, 0x38, 0x00, 0x10, 0x03,
353  0x01, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a,
354  0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00,
355  0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00,
356  };
357 
358  uint8_t dcerpc_bindack[] = {
359  0x05, 0x00, 0x0c, 0x03, 0x10, 0x00, 0x00, 0x00,
360  0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
361  0xb8, 0x10, 0xb8, 0x10, 0x65, 0x8e, 0x00, 0x00,
362  0x0d, 0x00, 0x5c, 0x50, 0x49, 0x50, 0x45, 0x5c,
363  0x77, 0x69, 0x6e, 0x72, 0x65, 0x67, 0x00, 0x6d,
364  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
365  0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11,
366  0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60,
367  0x02, 0x00, 0x00, 0x00,
368  };
369 
370  uint8_t dcerpc_request1[] = {
371  0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00,
372  0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
373  0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
374  0x2c, 0xfd, 0xb5, 0x00, 0x40, 0xaa, 0x01, 0x00,
375  0x00, 0x00, 0x00, 0x02,
376  };
377 
378  uint8_t dcerpc_response1[] = {
379  0x05, 0x00, 0x02, 0x03, 0x10, 0x00, 0x00, 0x00,
380  0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
381  0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
382  0x00, 0x00, 0x00, 0x00, 0xf6, 0x72, 0x28, 0x9c,
383  0xf0, 0x57, 0xd8, 0x11, 0xb0, 0x05, 0x00, 0x0c,
384  0x29, 0x87, 0xea, 0xe9, 0x00, 0x00, 0x00, 0x00,
385  };
386 
387  uint8_t dcerpc_request2[] = {
388  0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00,
389  0xa4, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
390  0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00,
391  0x00, 0x00, 0x00, 0x00, 0xf6, 0x72, 0x28, 0x9c,
392  0xf0, 0x57, 0xd8, 0x11, 0xb0, 0x05, 0x00, 0x0c,
393  0x29, 0x87, 0xea, 0xe9, 0x5c, 0x00, 0x5c, 0x00,
394  0xa8, 0xb9, 0x14, 0x00, 0x2e, 0x00, 0x00, 0x00,
395  0x00, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00,
396  0x53, 0x00, 0x4f, 0x00, 0x46, 0x00, 0x54, 0x00,
397  0x57, 0x00, 0x41, 0x00, 0x52, 0x00, 0x45, 0x00,
398  0x5c, 0x00, 0x4d, 0x00, 0x69, 0x00, 0x63, 0x00,
399  0x72, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x6f, 0x00,
400  0x66, 0x00, 0x74, 0x00, 0x5c, 0x00, 0x57, 0x00,
401  0x69, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x6f, 0x00,
402  0x77, 0x00, 0x73, 0x00, 0x5c, 0x00, 0x43, 0x00,
403  0x75, 0x00, 0x72, 0x00, 0x72, 0x00, 0x65, 0x00,
404  0x6e, 0x00, 0x74, 0x00, 0x56, 0x00, 0x65, 0x00,
405  0x72, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00,
406  0x6e, 0x00, 0x5c, 0x00, 0x52, 0x00, 0x75, 0x00,
407  0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
408  0x03, 0x00, 0x00, 0x00,
409  };
410 
411  uint8_t dcerpc_response2[] = {
412  0x05, 0x00, 0x02, 0x03, 0x10, 0x00, 0x00, 0x00,
413  0x30, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
414  0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
415  0x00, 0x00, 0x00, 0x00, 0xf7, 0x72, 0x28, 0x9c,
416  0xf0, 0x57, 0xd8, 0x11, 0xb0, 0x05, 0x00, 0x0c,
417  0x29, 0x87, 0xea, 0xe9, 0x00, 0x00, 0x00, 0x00,
418  };
419 
420  uint8_t dcerpc_request3[] = {
421  0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00,
422  0x70, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
423  0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00,
424  0x00, 0x00, 0x00, 0x00, 0xf7, 0x72, 0x28, 0x9c,
425  0xf0, 0x57, 0xd8, 0x11, 0xb0, 0x05, 0x00, 0x0c,
426  0x29, 0x87, 0xea, 0xe9, 0x0c, 0x00, 0x0c, 0x00,
427  0x98, 0xda, 0x14, 0x00, 0x06, 0x00, 0x00, 0x00,
428  0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
429  0x4f, 0x00, 0x73, 0x00, 0x61, 0x00, 0x33, 0x00,
430  0x32, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
431  0x18, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x54, 0x00,
432  0x4f, 0x00, 0x53, 0x00, 0x41, 0x00, 0x33, 0x00,
433  0x32, 0x00, 0x2e, 0x00, 0x45, 0x00, 0x58, 0x00,
434  0x45, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
435  };
436 
437  uint8_t dcerpc_response3[] = {
438  0x05, 0x00, 0x02, 0x03, 0x10, 0x00, 0x00, 0x00,
439  0x1c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
440  0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
441  0x00, 0x00, 0x00, 0x00,
442  };
443 
444  uint32_t dcerpc_bind_len = sizeof(dcerpc_bind);
445  uint32_t dcerpc_bindack_len = sizeof(dcerpc_bindack);
446 
447  uint32_t dcerpc_request1_len = sizeof(dcerpc_request1);
448  uint32_t dcerpc_response1_len = sizeof(dcerpc_response1);
449 
450  uint32_t dcerpc_request2_len = sizeof(dcerpc_request2);
451  uint32_t dcerpc_response2_len = sizeof(dcerpc_response2);
452 
453  uint32_t dcerpc_request3_len = sizeof(dcerpc_request3);
454  uint32_t dcerpc_response3_len = sizeof(dcerpc_response3);
455 
457 
458  memset(&th_v, 0, sizeof(th_v));
459  memset(&p, 0, sizeof(p));
460  memset(&f, 0, sizeof(f));
461  memset(&ssn, 0, sizeof(ssn));
462 
463  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
464 
465  FLOW_INITIALIZE(&f);
466  f.protoctx = (void *)&ssn;
467  f.proto = IPPROTO_TCP;
468  p->flow = &f;
473 
475 
477  if (de_ctx == NULL)
478  goto end;
479 
480  de_ctx->flags |= DE_QUIET;
481 
482  s = DetectEngineAppendSig(de_ctx,"alert tcp any any -> any any "
483  "(msg:\"DCERPC\"; dce_iface:338cd001-2244-31f1-aaaa-900038001003,=1,any_frag; sid:1;)");
484  if (s == NULL)
485  goto end;
486 
488  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
489 
490  SCLogDebug("chunk 1, bind");
491 
493  dcerpc_bind, dcerpc_bind_len);
494  if (r != 0) {
495  SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r);
496  goto end;
497  }
498 
499  dcerpc_state = f.alstate;
500  if (dcerpc_state == NULL) {
501  SCLogDebug("no dcerpc state: ");
502  goto end;
503  }
504 
507  /* do detect */
508  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
509 
510  if (PacketAlertCheck(p, 1)) {
511  SCLogDebug("sig 1 didn't match after bind request: ");
512  goto end;
513  }
514 
515  SCLogDebug("chunk 2, bind_ack");
516 
518  dcerpc_bindack_len);
519  if (r != 0) {
520  SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r);
521  goto end;
522  }
523 
526  /* do detect */
527  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
528 
529  if (PacketAlertCheck(p, 1)) {
530  SCLogDebug("sig 1 matched again after bind ack: ");
531  goto end;
532  }
533 
534  SCLogDebug("chunk 3, request 1");
535 
536  /* request1 */
537  r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, dcerpc_request1,
538  dcerpc_request1_len);
539  if (r != 0) {
540  SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r);
541  goto end;
542  }
543 
546  /* do detect */
547  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
548 
549  if (!(PacketAlertCheck(p, 1))) {
550  SCLogDebug("sig 1 didn't match after request1: ");
551  goto end;
552  }
553 
554  SCLogDebug("sending response1");
555 
556  /* response1 */
557  r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT, dcerpc_response1,
558  dcerpc_response1_len);
559  if (r != 0) {
560  SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r);
561  goto end;
562  }
563 
566  /* do detect */
567  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
568 
569  if (PacketAlertCheck(p, 1)) {
570  SCLogDebug("sig 1 matched after response1, but shouldn't: ");
571  goto end;
572  }
573 
574  SCLogDebug("sending request2");
575 
576  /* request2 */
577  r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, dcerpc_request2,
578  dcerpc_request2_len);
579  if (r != 0) {
580  SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r);
581  goto end;
582  }
583 
586  /* do detect */
587  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
588 
589  if (!(PacketAlertCheck(p, 1))) {
590  SCLogDebug("sig 1 didn't match after request2: ");
591  goto end;
592  }
593 
594  /* response2 */
595  r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT, dcerpc_response2,
596  dcerpc_response2_len);
597  if (r != 0) {
598  SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r);
599  goto end;
600  }
601 
604  /* do detect */
605  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
606 
607  if (PacketAlertCheck(p, 1)) {
608  SCLogDebug("sig 1 matched after response2, but shouldn't have: ");
609  goto end;
610  }
611 
612  /* request3 */
613  r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, dcerpc_request3,
614  dcerpc_request3_len);
615  if (r != 0) {
616  SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r);
617  goto end;
618  }
619 
622  /* do detect */
623  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
624 
625  if (!(PacketAlertCheck(p, 1))) {
626  SCLogDebug("sig 1 didn't match after request3: ");
627  goto end;
628  }
629 
630  /* response3 */
632  dcerpc_response3, dcerpc_response3_len);
633  if (r != 0) {
634  SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r);
635  goto end;
636  }
637 
640  /* do detect */
641  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
642 
643  if (PacketAlertCheck(p, 1)) {
644  SCLogDebug("sig 1 matched after response3, but shouldn't have: ");
645  goto end;
646  }
647 
648  result = 1;
649 
650  end:
651  if (alp_tctx != NULL)
655 
656  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
658 
660  UTHFreePackets(&p, 1);
661  return result;
662 }
663 
664 #endif
665 
666 /**
667  * \test Test a valid dce_iface entry for a bind and bind_ack
668  */
669 static int DetectDceIfaceTestParse2(void)
670 {
671  int result = 0;
672  Signature *s = NULL;
673  ThreadVars th_v;
674  Packet *p = NULL;
675  Flow f;
676  TcpSession ssn;
677  DetectEngineThreadCtx *det_ctx = NULL;
678  DetectEngineCtx *de_ctx = NULL;
679  DCERPCState *dcerpc_state = NULL;
680  int r = 0;
681 
682  uint8_t dcerpc_bind[] = {
683  0x05, 0x00, 0x0b, 0x03, 0x10, 0x00, 0x00, 0x00,
684  0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
685  0xb8, 0x10, 0xb8, 0x10, 0x00, 0x00, 0x00, 0x00,
686  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
687  0x6a, 0x28, 0x19, 0x39, 0x0c, 0xb1, 0xd0, 0x11,
688  0x9b, 0xa8, 0x00, 0xc0, 0x4f, 0xd9, 0x2e, 0xf5,
689  0x00, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a,
690  0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00,
691  0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00,
692  };
693 
694  uint8_t dcerpc_bindack[] = {
695  0x05, 0x00, 0x0c, 0x03, 0x10, 0x00, 0x00, 0x00,
696  0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
697  0xb8, 0x10, 0xb8, 0x10, 0x26, 0x3d, 0x00, 0x00,
698  0x0c, 0x00, 0x5c, 0x50, 0x49, 0x50, 0x45, 0x5c,
699  0x6c, 0x73, 0x61, 0x73, 0x73, 0x00, 0x00, 0x00,
700  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
701  0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11,
702  0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60,
703  0x02, 0x00, 0x00, 0x00
704  };
705 
706  uint8_t dcerpc_request[] = {
707  0x05, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00,
708  0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
709  0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00,
710  0xad, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
711  };
712 
713  uint32_t dcerpc_bind_len = sizeof(dcerpc_bind);
714  uint32_t dcerpc_bindack_len = sizeof(dcerpc_bindack);
715  uint32_t dcerpc_request_len = sizeof(dcerpc_request);
716 
718 
719  memset(&th_v, 0, sizeof(th_v));
720  memset(&p, 0, sizeof(p));
721  memset(&f, 0, sizeof(f));
722  memset(&ssn, 0, sizeof(ssn));
723 
724  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
725 
726  FLOW_INITIALIZE(&f);
727  f.protoctx = (void *)&ssn;
728  f.proto = IPPROTO_TCP;
729  p->flow = &f;
734 
736 
738  if (de_ctx == NULL)
739  goto end;
740 
741  de_ctx->flags |= DE_QUIET;
742 
743  s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
744  "(msg:\"DCERPC\"; "
745  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5,=0; "
746  "sid:1;)");
747  if (s == NULL)
748  goto end;
749 
751  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
752 
753  FLOWLOCK_WRLOCK(&f);
755  STREAM_TOSERVER | STREAM_START, dcerpc_bind,
756  dcerpc_bind_len);
757  if (r != 0) {
758  SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r);
759  FLOWLOCK_UNLOCK(&f);
760  goto end;
761  }
762  FLOWLOCK_UNLOCK(&f);
763 
764  dcerpc_state = f.alstate;
765  if (dcerpc_state == NULL) {
766  SCLogDebug("no dcerpc state: ");
767  goto end;
768  }
769 
770  /* do detect */
771  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
772 
773  if (PacketAlertCheck(p, 1))
774  goto end;
775 
776  FLOWLOCK_WRLOCK(&f);
778  STREAM_TOCLIENT, dcerpc_bindack,
779  dcerpc_bindack_len);
780  if (r != 0) {
781  SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r);
782  FLOWLOCK_UNLOCK(&f);
783  goto end;
784  }
785  FLOWLOCK_UNLOCK(&f);
786 
787  /* do detect */
788  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
789 
790  if (PacketAlertCheck(p, 1)) {
791  SCLogDebug("sig 1 matched but shouldn't have: ");
792  goto end;
793  }
794 
795  FLOWLOCK_WRLOCK(&f);
797  STREAM_TOSERVER, dcerpc_request,
798  dcerpc_request_len);
799  if (r != 0) {
800  SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r);
801  FLOWLOCK_UNLOCK(&f);
802  goto end;
803  }
804  FLOWLOCK_UNLOCK(&f);
805 
806  /* do detect */
807  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
808 
809  if (!PacketAlertCheck(p, 1)) {
810  SCLogDebug("sig 1 matched but shouldn't have: ");
811  goto end;
812  }
813 
814  result = 1;
815 
816  end:
817  if (alp_tctx != NULL)
821 
822  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
824 
826  FLOW_DESTROY(&f);
827  UTHFreePackets(&p, 1);
828  return result;
829 }
830 
831 static void DetectDceIfaceRegisterTests(void)
832 {
833  UtRegisterTest("DetectDceIfaceTestParse1", DetectDceIfaceTestParse1);
834  /* Disabled because of bug_753. Would be enabled, once we rewrite
835  * dce parser */
836 #if 0
837  UtRegisterTest("DetectDceIfaceTestParse13", DetectDceIfaceTestParse13, 1);
838 #endif
839  UtRegisterTest("DetectDceIfaceTestParse2", DetectDceIfaceTestParse2);
840 }
841 #endif /* UNITTESTS */
app-layer-dcerpc.h
detect-engine.h
detect-dce-iface.h
PKT_HAS_FLOW
#define PKT_HAS_FLOW
Definition: decode.h:1104
ALPROTO_DCERPC
@ ALPROTO_DCERPC
Definition: app-layer-protos.h:38
SigTableElmt_::Free
void(* Free)(DetectEngineCtx *, void *)
Definition: detect.h:1200
flow-util.h
SigTableElmt_::name
const char * name
Definition: detect.h:1210
stream-tcp.h
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:103
Signature_::alproto
AppProto alproto
Definition: detect.h:531
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:298
Flow_::proto
uint8_t proto
Definition: flow.h:365
PacketAlertCheck
int PacketAlertCheck(Packet *p, uint32_t sid)
Check if a certain sid alerted, this is used in the test functions.
Definition: detect-engine-alert.c:138
Packet_::flags
uint32_t flags
Definition: decode.h:447
DetectDceIfaceRegister
void DetectDceIfaceRegister(void)
Registers the keyword handlers for the "dce_iface" keyword.
Definition: detect-dce-iface.c:75
Flow_
Flow data structure.
Definition: flow.h:347
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
SigTableElmt_::AppLayerTxMatch
int(* AppLayerTxMatch)(DetectEngineThreadCtx *, Flow *, uint8_t flags, void *alstate, void *txv, const Signature *, const SigMatchCtx *)
Definition: detect.h:1181
AppLayerParserThreadCtxFree
void AppLayerParserThreadCtxFree(AppLayerParserThreadCtx *tctx)
Destroys the app layer parser thread context obtained using AppLayerParserThreadCtxAlloc().
Definition: app-layer-parser.c:278
FLOW_PKT_TOSERVER
#define FLOW_PKT_TOSERVER
Definition: flow.h:219
rust.h
DE_QUIET
#define DE_QUIET
Definition: detect.h:293
stream-tcp-reassemble.h
UTHBuildPacket
Packet * UTHBuildPacket(uint8_t *payload, uint16_t payload_len, uint8_t ipproto)
UTHBuildPacket is a wrapper that build packets with default ip and port fields.
Definition: util-unittest-helper.c:337
m
SCMutex m
Definition: flow-hash.h:6
SigCleanSignatures
void SigCleanSignatures(DetectEngineCtx *de_ctx)
Definition: detect-engine-build.c:39
Packet_::flowflags
uint8_t flowflags
Definition: decode.h:443
SIG_FLAG_TOCLIENT
#define SIG_FLAG_TOCLIENT
Definition: detect.h:237
Flow_::protoctx
void * protoctx
Definition: flow.h:441
SigMatchData_
Data needed for Match()
Definition: detect.h:328
SigTableElmt_::Setup
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1195
util-unittest.h
util-unittest-helper.h
DetectEngineInspectGenericList
int DetectEngineInspectGenericList(ThreadVars *tv, const DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, const Signature *s, const SigMatchData *smd, Flow *f, const uint8_t flags, void *alstate, void *txv, uint64_t tx_id)
Do the content inspection & validation for a signature.
Definition: detect-engine.c:1596
FLOWLOCK_UNLOCK
#define FLOWLOCK_UNLOCK(fb)
Definition: flow.h:264
STREAM_START
#define STREAM_START
Definition: stream.h:29
FLOW_INITIALIZE
#define FLOW_INITIALIZE(f)
Definition: flow-util.h:39
SIG_FLAG_TOSERVER
#define SIG_FLAG_TOSERVER
Definition: detect.h:236
util-debug.h
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:17
DetectEngineThreadCtx_
Definition: detect.h:1009
STREAM_TOSERVER
#define STREAM_TOSERVER
Definition: stream.h:31
alp_tctx
AppLayerParserThreadCtx * alp_tctx
Definition: fuzz_applayerparserparse.c:19
DetectSetupParseRegexes
void DetectSetupParseRegexes(const char *parse_str, DetectParseRegex *detect_parse)
Definition: detect-parse.c:2476
FLOWLOCK_WRLOCK
#define FLOWLOCK_WRLOCK(fb)
Definition: flow.h:261
SCEnter
#define SCEnter(...)
Definition: util-debug.h:300
detect-engine-mpm.h
detect.h
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:58
TRUE
#define TRUE
Definition: suricata-common.h:33
SigMatch_::ctx
SigMatchCtx * ctx
Definition: detect.h:322
SigMatchSignatures
void SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
wrapper for old tests
Definition: detect.c:1688
SigGroupCleanup
int SigGroupCleanup(DetectEngineCtx *de_ctx)
Definition: detect-engine-build.c:1943
SCReturn
#define SCReturn
Definition: util-debug.h:302
Packet_
Definition: decode.h:412
StreamTcpFreeConfig
void StreamTcpFreeConfig(char quiet)
Definition: stream-tcp.c:668
DETECT_DCE_IFACE
@ DETECT_DCE_IFACE
Definition: detect-engine-register.h:184
detect-engine-state.h
Data structures and function prototypes for keeping state for the detection engine.
queue.h
FLOW_PKT_TOCLIENT
#define FLOW_PKT_TOCLIENT
Definition: flow.h:220
SigMatchAlloc
SigMatch * SigMatchAlloc(void)
Definition: detect-parse.c:235
PARSE_REGEX
#define PARSE_REGEX
Definition: detect-dce-iface.c:52
SigGroupBuild
int SigGroupBuild(DetectEngineCtx *de_ctx)
Convert the signature list into the runtime match structure.
Definition: detect-engine-build.c:1878
SigMatch_::type
uint8_t type
Definition: detect.h:320
AppLayerParserThreadCtxAlloc
AppLayerParserThreadCtx * AppLayerParserThreadCtxAlloc(void)
Gets a new app layer protocol's parser thread context.
Definition: app-layer-parser.c:252
SigMatchCtx_
Used to start a pointer to SigMatch context Should never be dereferenced without casting to something...
Definition: detect.h:314
DetectEngineAppendSig
Signature * DetectEngineAppendSig(DetectEngineCtx *de_ctx, const char *sigstr)
Parse and append a Signature into the Detection Engine Context signature list.
Definition: detect-parse.c:2344
Packet_::flow
struct Flow_ * flow
Definition: decode.h:449
DetectEngineThreadCtxInit
TmEcode DetectEngineThreadCtxInit(ThreadVars *, void *, void **)
initialize thread specific detection engine context
Definition: detect-engine.c:2797
FAIL_IF
#define FAIL_IF(expr)
Fail a test if expression evaluates to false.
Definition: util-unittest.h:71
DetectBufferTypeRegister
int DetectBufferTypeRegister(const char *name)
Definition: detect-engine.c:836
flags
uint8_t flags
Definition: decode-gre.h:0
SigTableElmt_::alias
const char * alias
Definition: detect.h:1211
AppLayerParserParse
int AppLayerParserParse(ThreadVars *tv, AppLayerParserThreadCtx *alp_tctx, Flow *f, AppProto alproto, uint8_t flags, const uint8_t *input, uint32_t input_len)
Definition: app-layer-parser.c:1179
suricata-common.h
DetectEngineThreadCtxDeinit
TmEcode DetectEngineThreadCtxDeinit(ThreadVars *, void *)
Definition: detect-engine.c:3005
sigmatch_table
SigTableElmt sigmatch_table[DETECT_TBLSIZE]
Definition: detect-parse.c:73
DetectParseRegex_
Definition: detect-parse.h:42
STREAM_TOCLIENT
#define STREAM_TOCLIENT
Definition: stream.h:32
SCLogError
#define SCLogError(err_code,...)
Macro used to log ERROR messages.
Definition: util-debug.h:257
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:29
Flow_::alstate
void * alstate
Definition: flow.h:476
detect-parse.h
Signature_
Signature container.
Definition: detect.h:527
SigMatch_
a single match condition for a signature
Definition: detect.h:319
StreamTcpInitConfig
void StreamTcpInitConfig(char)
To initialize the stream global configuration data.
Definition: stream-tcp.c:365
ALPROTO_UNKNOWN
@ ALPROTO_UNKNOWN
Definition: app-layer-protos.h:29
FLOW_PKT_ESTABLISHED
#define FLOW_PKT_ESTABLISHED
Definition: flow.h:221
DetectEngineCtxInit
DetectEngineCtx * DetectEngineCtxInit(void)
Definition: detect-engine.c:2048
STREAM_EOF
#define STREAM_EOF
Definition: stream.h:30
ALPROTO_SMB
@ ALPROTO_SMB
Definition: app-layer-protos.h:37
DetectEngineCtx_::flags
uint8_t flags
Definition: detect.h:767
AppLayerParserThreadCtx_
Definition: app-layer-parser.c:87
TcpSession_
Definition: stream-tcp-private.h:261
flow.h
DetectAppLayerInspectEngineRegister
void DetectAppLayerInspectEngineRegister(const char *name, AppProto alproto, uint32_t dir, int progress, InspectEngineFuncPtr Callback)
register inspect engine at start up time
Definition: detect-engine.c:171
Flow_::alproto
AppProto alproto
application level protocol
Definition: flow.h:450
SCReturnInt
#define SCReturnInt(x)
Definition: util-debug.h:304
flow-var.h
SigMatchAppendSMToList
void SigMatchAppendSMToList(Signature *s, SigMatch *new, int list)
Append a SigMatch to the list type.
Definition: detect-parse.c:349
FLOW_DESTROY
#define FLOW_DESTROY(f)
Definition: flow-util.h:130
PKT_STREAM_EST
#define PKT_STREAM_EST
Definition: decode.h:1102
SigTableElmt_::RegisterTests
void(* RegisterTests)(void)
Definition: detect.h:1202
app-layer.h
SC_ERR_CONFLICTING_RULE_KEYWORDS
@ SC_ERR_CONFLICTING_RULE_KEYWORDS
Definition: util-error.h:171
UTHFreePackets
void UTHFreePackets(Packet **p, int numpkts)
UTHFreePackets: function to release the allocated data from UTHBuildPacket and the packet itself.
Definition: util-unittest-helper.c:468