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);
185  return 0;
186 }
187 
188 static void DetectDceIfaceFree(DetectEngineCtx *de_ctx, void *ptr)
189 {
190  SCEnter();
191  if (ptr != NULL) {
192  rs_dcerpc_iface_free(ptr);
193  }
194  SCReturn;
195 }
196 
197 /************************************Unittests*********************************/
198 
199 #ifdef UNITTESTS
200 
201 /**
202  * \test Test a valid dce_iface entry for a bind and bind_ack
203  */
204 static int DetectDceIfaceTestParse1(void)
205 {
206  Signature *s = NULL;
207  ThreadVars th_v;
208  Packet *p = NULL;
209  Flow f;
210  TcpSession ssn;
211  DetectEngineThreadCtx *det_ctx = NULL;
212  DetectEngineCtx *de_ctx = NULL;
213  DCERPCState *dcerpc_state = NULL;
214  int r = 0;
215 
216  uint8_t dcerpc_bind[] = {
217  0x05, 0x00, 0x0b, 0x03, 0x10, 0x00, 0x00, 0x00,
218  0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
219  0xb8, 0x10, 0xb8, 0x10, 0x00, 0x00, 0x00, 0x00,
220  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
221  0x6a, 0x28, 0x19, 0x39, 0x0c, 0xb1, 0xd0, 0x11,
222  0x9b, 0xa8, 0x00, 0xc0, 0x4f, 0xd9, 0x2e, 0xf5,
223  0x00, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a,
224  0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00,
225  0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00,
226  };
227 
228  uint8_t dcerpc_bindack[] = {
229  0x05, 0x00, 0x0c, 0x03, 0x10, 0x00, 0x00, 0x00,
230  0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
231  0xb8, 0x10, 0xb8, 0x10, 0x26, 0x3d, 0x00, 0x00,
232  0x0c, 0x00, 0x5c, 0x50, 0x49, 0x50, 0x45, 0x5c,
233  0x6c, 0x73, 0x61, 0x73, 0x73, 0x00, 0x00, 0x00,
234  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
235  0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11,
236  0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60,
237  0x02, 0x00, 0x00, 0x00
238  };
239 
240  uint8_t dcerpc_request[] = {
241  0x05, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00,
242  0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
243  0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00,
244  0xad, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
245  };
246 
247  uint32_t dcerpc_bind_len = sizeof(dcerpc_bind);
248  uint32_t dcerpc_bindack_len = sizeof(dcerpc_bindack);
249  uint32_t dcerpc_request_len = sizeof(dcerpc_request);
250 
252 
253  memset(&th_v, 0, sizeof(th_v));
254  memset(&f, 0, sizeof(f));
255  memset(&ssn, 0, sizeof(ssn));
256 
257  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
258 
259  FLOW_INITIALIZE(&f);
260  f.protoctx = (void *)&ssn;
261  f.proto = IPPROTO_TCP;
262  p->flow = &f;
267 
269 
271  FAIL_IF(de_ctx == NULL);
272  de_ctx->flags |= DE_QUIET;
273 
274  s = DetectEngineAppendSig(de_ctx,"alert tcp any any -> any any "
275  "(msg:\"DCERPC\"; "
276  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5,=0,any_frag; "
277  "sid:1;)");
278  FAIL_IF(s == NULL);
279 
281  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
282 
283  SCLogDebug("handling to_server chunk");
284 
286  STREAM_TOSERVER | STREAM_START, dcerpc_bind,
287  dcerpc_bind_len);
288  FAIL_IF(r != 0);
289 
290  dcerpc_state = f.alstate;
291  FAIL_IF(dcerpc_state == NULL);
292 
293  /* do detect */
294  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
295  FAIL_IF(PacketAlertCheck(p, 1));
296 
297  SCLogDebug("handling to_client chunk");
298 
300  STREAM_TOCLIENT, dcerpc_bindack,
301  dcerpc_bindack_len);
302  FAIL_IF(r != 0);
303 
304  /* do detect */
305  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
306  FAIL_IF(PacketAlertCheck(p, 1));
307 
309  STREAM_TOSERVER, dcerpc_request,
310  dcerpc_request_len);
311  FAIL_IF(r != 0);
312 
313  /* do detect */
314  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
315 
316  FAIL_IF(!PacketAlertCheck(p, 1));
317  if (alp_tctx != NULL)
319  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
322  FLOW_DESTROY(&f);
323  UTHFreePackets(&p, 1);
324  PASS;
325 }
326 
327 /* Disabled because of bug_753. Would be enabled, once we rewrite
328  * dce parser */
329 #if 0
330 
331 /**
332  * \test Test a valid dce_iface entry with a bind, bind_ack and 3 request/responses.
333  */
334 static int DetectDceIfaceTestParse13(void)
335 {
336  int result = 0;
337  Signature *s = NULL;
338  ThreadVars th_v;
339  Packet *p = NULL;
340  Flow f;
341  TcpSession ssn;
342  DetectEngineThreadCtx *det_ctx = NULL;
343  DetectEngineCtx *de_ctx = NULL;
344  DCERPCState *dcerpc_state = NULL;
345  int r = 0;
346 
347  uint8_t dcerpc_bind[] = {
348  0x05, 0x00, 0x0b, 0x03, 0x10, 0x00, 0x00, 0x00,
349  0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
350  0xb8, 0x10, 0xb8, 0x10, 0x00, 0x00, 0x00, 0x00,
351  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
352  0x01, 0xd0, 0x8c, 0x33, 0x44, 0x22, 0xf1, 0x31,
353  0xaa, 0xaa, 0x90, 0x00, 0x38, 0x00, 0x10, 0x03,
354  0x01, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a,
355  0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00,
356  0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00,
357  };
358 
359  uint8_t dcerpc_bindack[] = {
360  0x05, 0x00, 0x0c, 0x03, 0x10, 0x00, 0x00, 0x00,
361  0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
362  0xb8, 0x10, 0xb8, 0x10, 0x65, 0x8e, 0x00, 0x00,
363  0x0d, 0x00, 0x5c, 0x50, 0x49, 0x50, 0x45, 0x5c,
364  0x77, 0x69, 0x6e, 0x72, 0x65, 0x67, 0x00, 0x6d,
365  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
366  0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11,
367  0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60,
368  0x02, 0x00, 0x00, 0x00,
369  };
370 
371  uint8_t dcerpc_request1[] = {
372  0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00,
373  0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
374  0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
375  0x2c, 0xfd, 0xb5, 0x00, 0x40, 0xaa, 0x01, 0x00,
376  0x00, 0x00, 0x00, 0x02,
377  };
378 
379  uint8_t dcerpc_response1[] = {
380  0x05, 0x00, 0x02, 0x03, 0x10, 0x00, 0x00, 0x00,
381  0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
382  0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
383  0x00, 0x00, 0x00, 0x00, 0xf6, 0x72, 0x28, 0x9c,
384  0xf0, 0x57, 0xd8, 0x11, 0xb0, 0x05, 0x00, 0x0c,
385  0x29, 0x87, 0xea, 0xe9, 0x00, 0x00, 0x00, 0x00,
386  };
387 
388  uint8_t dcerpc_request2[] = {
389  0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00,
390  0xa4, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
391  0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00,
392  0x00, 0x00, 0x00, 0x00, 0xf6, 0x72, 0x28, 0x9c,
393  0xf0, 0x57, 0xd8, 0x11, 0xb0, 0x05, 0x00, 0x0c,
394  0x29, 0x87, 0xea, 0xe9, 0x5c, 0x00, 0x5c, 0x00,
395  0xa8, 0xb9, 0x14, 0x00, 0x2e, 0x00, 0x00, 0x00,
396  0x00, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00,
397  0x53, 0x00, 0x4f, 0x00, 0x46, 0x00, 0x54, 0x00,
398  0x57, 0x00, 0x41, 0x00, 0x52, 0x00, 0x45, 0x00,
399  0x5c, 0x00, 0x4d, 0x00, 0x69, 0x00, 0x63, 0x00,
400  0x72, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x6f, 0x00,
401  0x66, 0x00, 0x74, 0x00, 0x5c, 0x00, 0x57, 0x00,
402  0x69, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x6f, 0x00,
403  0x77, 0x00, 0x73, 0x00, 0x5c, 0x00, 0x43, 0x00,
404  0x75, 0x00, 0x72, 0x00, 0x72, 0x00, 0x65, 0x00,
405  0x6e, 0x00, 0x74, 0x00, 0x56, 0x00, 0x65, 0x00,
406  0x72, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00,
407  0x6e, 0x00, 0x5c, 0x00, 0x52, 0x00, 0x75, 0x00,
408  0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
409  0x03, 0x00, 0x00, 0x00,
410  };
411 
412  uint8_t dcerpc_response2[] = {
413  0x05, 0x00, 0x02, 0x03, 0x10, 0x00, 0x00, 0x00,
414  0x30, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
415  0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
416  0x00, 0x00, 0x00, 0x00, 0xf7, 0x72, 0x28, 0x9c,
417  0xf0, 0x57, 0xd8, 0x11, 0xb0, 0x05, 0x00, 0x0c,
418  0x29, 0x87, 0xea, 0xe9, 0x00, 0x00, 0x00, 0x00,
419  };
420 
421  uint8_t dcerpc_request3[] = {
422  0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00,
423  0x70, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
424  0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00,
425  0x00, 0x00, 0x00, 0x00, 0xf7, 0x72, 0x28, 0x9c,
426  0xf0, 0x57, 0xd8, 0x11, 0xb0, 0x05, 0x00, 0x0c,
427  0x29, 0x87, 0xea, 0xe9, 0x0c, 0x00, 0x0c, 0x00,
428  0x98, 0xda, 0x14, 0x00, 0x06, 0x00, 0x00, 0x00,
429  0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
430  0x4f, 0x00, 0x73, 0x00, 0x61, 0x00, 0x33, 0x00,
431  0x32, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
432  0x18, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x54, 0x00,
433  0x4f, 0x00, 0x53, 0x00, 0x41, 0x00, 0x33, 0x00,
434  0x32, 0x00, 0x2e, 0x00, 0x45, 0x00, 0x58, 0x00,
435  0x45, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
436  };
437 
438  uint8_t dcerpc_response3[] = {
439  0x05, 0x00, 0x02, 0x03, 0x10, 0x00, 0x00, 0x00,
440  0x1c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
441  0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
442  0x00, 0x00, 0x00, 0x00,
443  };
444 
445  uint32_t dcerpc_bind_len = sizeof(dcerpc_bind);
446  uint32_t dcerpc_bindack_len = sizeof(dcerpc_bindack);
447 
448  uint32_t dcerpc_request1_len = sizeof(dcerpc_request1);
449  uint32_t dcerpc_response1_len = sizeof(dcerpc_response1);
450 
451  uint32_t dcerpc_request2_len = sizeof(dcerpc_request2);
452  uint32_t dcerpc_response2_len = sizeof(dcerpc_response2);
453 
454  uint32_t dcerpc_request3_len = sizeof(dcerpc_request3);
455  uint32_t dcerpc_response3_len = sizeof(dcerpc_response3);
456 
458 
459  memset(&th_v, 0, sizeof(th_v));
460  memset(&p, 0, sizeof(p));
461  memset(&f, 0, sizeof(f));
462  memset(&ssn, 0, sizeof(ssn));
463 
464  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
465 
466  FLOW_INITIALIZE(&f);
467  f.protoctx = (void *)&ssn;
468  f.proto = IPPROTO_TCP;
469  p->flow = &f;
474 
476 
478  if (de_ctx == NULL)
479  goto end;
480 
481  de_ctx->flags |= DE_QUIET;
482 
483  s = DetectEngineAppendSig(de_ctx,"alert tcp any any -> any any "
484  "(msg:\"DCERPC\"; dce_iface:338cd001-2244-31f1-aaaa-900038001003,=1,any_frag; sid:1;)");
485  if (s == NULL)
486  goto end;
487 
489  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
490 
491  SCLogDebug("chunk 1, bind");
492 
494  dcerpc_bind, dcerpc_bind_len);
495  if (r != 0) {
496  SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r);
497  goto end;
498  }
499 
500  dcerpc_state = f.alstate;
501  if (dcerpc_state == NULL) {
502  SCLogDebug("no dcerpc state: ");
503  goto end;
504  }
505 
508  /* do detect */
509  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
510 
511  if (PacketAlertCheck(p, 1)) {
512  SCLogDebug("sig 1 didn't match after bind request: ");
513  goto end;
514  }
515 
516  SCLogDebug("chunk 2, bind_ack");
517 
519  dcerpc_bindack_len);
520  if (r != 0) {
521  SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r);
522  goto end;
523  }
524 
527  /* do detect */
528  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
529 
530  if (PacketAlertCheck(p, 1)) {
531  SCLogDebug("sig 1 matched again after bind ack: ");
532  goto end;
533  }
534 
535  SCLogDebug("chunk 3, request 1");
536 
537  /* request1 */
538  r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, dcerpc_request1,
539  dcerpc_request1_len);
540  if (r != 0) {
541  SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r);
542  goto end;
543  }
544 
547  /* do detect */
548  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
549 
550  if (!(PacketAlertCheck(p, 1))) {
551  SCLogDebug("sig 1 didn't match after request1: ");
552  goto end;
553  }
554 
555  SCLogDebug("sending response1");
556 
557  /* response1 */
558  r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT, dcerpc_response1,
559  dcerpc_response1_len);
560  if (r != 0) {
561  SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r);
562  goto end;
563  }
564 
567  /* do detect */
568  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
569 
570  if (PacketAlertCheck(p, 1)) {
571  SCLogDebug("sig 1 matched after response1, but shouldn't: ");
572  goto end;
573  }
574 
575  SCLogDebug("sending request2");
576 
577  /* request2 */
578  r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, dcerpc_request2,
579  dcerpc_request2_len);
580  if (r != 0) {
581  SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r);
582  goto end;
583  }
584 
587  /* do detect */
588  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
589 
590  if (!(PacketAlertCheck(p, 1))) {
591  SCLogDebug("sig 1 didn't match after request2: ");
592  goto end;
593  }
594 
595  /* response2 */
596  r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT, dcerpc_response2,
597  dcerpc_response2_len);
598  if (r != 0) {
599  SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r);
600  goto end;
601  }
602 
605  /* do detect */
606  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
607 
608  if (PacketAlertCheck(p, 1)) {
609  SCLogDebug("sig 1 matched after response2, but shouldn't have: ");
610  goto end;
611  }
612 
613  /* request3 */
614  r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, dcerpc_request3,
615  dcerpc_request3_len);
616  if (r != 0) {
617  SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r);
618  goto end;
619  }
620 
623  /* do detect */
624  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
625 
626  if (!(PacketAlertCheck(p, 1))) {
627  SCLogDebug("sig 1 didn't match after request3: ");
628  goto end;
629  }
630 
631  /* response3 */
633  dcerpc_response3, dcerpc_response3_len);
634  if (r != 0) {
635  SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r);
636  goto end;
637  }
638 
641  /* do detect */
642  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
643 
644  if (PacketAlertCheck(p, 1)) {
645  SCLogDebug("sig 1 matched after response3, but shouldn't have: ");
646  goto end;
647  }
648 
649  result = 1;
650 
651  end:
652  if (alp_tctx != NULL)
656 
657  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
659 
661  UTHFreePackets(&p, 1);
662  return result;
663 }
664 
665 #endif
666 
667 /**
668  * \test Test a valid dce_iface entry for a bind and bind_ack
669  */
670 static int DetectDceIfaceTestParse2(void)
671 {
672  int result = 0;
673  Signature *s = NULL;
674  ThreadVars th_v;
675  Packet *p = NULL;
676  Flow f;
677  TcpSession ssn;
678  DetectEngineThreadCtx *det_ctx = NULL;
679  DetectEngineCtx *de_ctx = NULL;
680  DCERPCState *dcerpc_state = NULL;
681  int r = 0;
682 
683  uint8_t dcerpc_bind[] = {
684  0x05, 0x00, 0x0b, 0x03, 0x10, 0x00, 0x00, 0x00,
685  0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
686  0xb8, 0x10, 0xb8, 0x10, 0x00, 0x00, 0x00, 0x00,
687  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
688  0x6a, 0x28, 0x19, 0x39, 0x0c, 0xb1, 0xd0, 0x11,
689  0x9b, 0xa8, 0x00, 0xc0, 0x4f, 0xd9, 0x2e, 0xf5,
690  0x00, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a,
691  0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00,
692  0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00,
693  };
694 
695  uint8_t dcerpc_bindack[] = {
696  0x05, 0x00, 0x0c, 0x03, 0x10, 0x00, 0x00, 0x00,
697  0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
698  0xb8, 0x10, 0xb8, 0x10, 0x26, 0x3d, 0x00, 0x00,
699  0x0c, 0x00, 0x5c, 0x50, 0x49, 0x50, 0x45, 0x5c,
700  0x6c, 0x73, 0x61, 0x73, 0x73, 0x00, 0x00, 0x00,
701  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
702  0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11,
703  0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60,
704  0x02, 0x00, 0x00, 0x00
705  };
706 
707  uint8_t dcerpc_request[] = {
708  0x05, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00,
709  0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
710  0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00,
711  0xad, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
712  };
713 
714  uint32_t dcerpc_bind_len = sizeof(dcerpc_bind);
715  uint32_t dcerpc_bindack_len = sizeof(dcerpc_bindack);
716  uint32_t dcerpc_request_len = sizeof(dcerpc_request);
717 
719 
720  memset(&th_v, 0, sizeof(th_v));
721  memset(&p, 0, sizeof(p));
722  memset(&f, 0, sizeof(f));
723  memset(&ssn, 0, sizeof(ssn));
724 
725  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
726 
727  FLOW_INITIALIZE(&f);
728  f.protoctx = (void *)&ssn;
729  f.proto = IPPROTO_TCP;
730  p->flow = &f;
735 
737 
739  if (de_ctx == NULL)
740  goto end;
741 
742  de_ctx->flags |= DE_QUIET;
743 
744  s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
745  "(msg:\"DCERPC\"; "
746  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5,=0; "
747  "sid:1;)");
748  if (s == NULL)
749  goto end;
750 
752  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
753 
754  FLOWLOCK_WRLOCK(&f);
756  STREAM_TOSERVER | STREAM_START, dcerpc_bind,
757  dcerpc_bind_len);
758  if (r != 0) {
759  SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r);
760  FLOWLOCK_UNLOCK(&f);
761  goto end;
762  }
763  FLOWLOCK_UNLOCK(&f);
764 
765  dcerpc_state = f.alstate;
766  if (dcerpc_state == NULL) {
767  SCLogDebug("no dcerpc state: ");
768  goto end;
769  }
770 
771  /* do detect */
772  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
773 
774  if (PacketAlertCheck(p, 1))
775  goto end;
776 
777  FLOWLOCK_WRLOCK(&f);
779  STREAM_TOCLIENT, dcerpc_bindack,
780  dcerpc_bindack_len);
781  if (r != 0) {
782  SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r);
783  FLOWLOCK_UNLOCK(&f);
784  goto end;
785  }
786  FLOWLOCK_UNLOCK(&f);
787 
788  /* do detect */
789  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
790 
791  if (PacketAlertCheck(p, 1)) {
792  SCLogDebug("sig 1 matched but shouldn't have: ");
793  goto end;
794  }
795 
796  FLOWLOCK_WRLOCK(&f);
798  STREAM_TOSERVER, dcerpc_request,
799  dcerpc_request_len);
800  if (r != 0) {
801  SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r);
802  FLOWLOCK_UNLOCK(&f);
803  goto end;
804  }
805  FLOWLOCK_UNLOCK(&f);
806 
807  /* do detect */
808  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
809 
810  if (!PacketAlertCheck(p, 1)) {
811  SCLogDebug("sig 1 matched but shouldn't have: ");
812  goto end;
813  }
814 
815  result = 1;
816 
817  end:
818  if (alp_tctx != NULL)
822 
823  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
825 
827  FLOW_DESTROY(&f);
828  UTHFreePackets(&p, 1);
829  return result;
830 }
831 
832 static void DetectDceIfaceRegisterTests(void)
833 {
834  UtRegisterTest("DetectDceIfaceTestParse1", DetectDceIfaceTestParse1);
835  /* Disabled because of bug_753. Would be enabled, once we rewrite
836  * dce parser */
837 #if 0
838  UtRegisterTest("DetectDceIfaceTestParse13", DetectDceIfaceTestParse13, 1);
839 #endif
840  UtRegisterTest("DetectDceIfaceTestParse2", DetectDceIfaceTestParse2);
841 }
842 #endif /* UNITTESTS */
app-layer-dcerpc.h
detect-engine.h
detect-dce-iface.h
PKT_HAS_FLOW
#define PKT_HAS_FLOW
Definition: decode.h:1109
ALPROTO_DCERPC
@ ALPROTO_DCERPC
Definition: app-layer-protos.h:38
SigTableElmt_::Free
void(* Free)(DetectEngineCtx *, void *)
Definition: detect.h:1201
flow-util.h
SigTableElmt_::name
const char * name
Definition: detect.h:1211
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:532
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:449
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:767
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:1182
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:294
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
SignatureInitData_::init_flags
uint32_t init_flags
Definition: detect.h:493
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:445
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:329
SigTableElmt_::Setup
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1196
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:1010
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:2493
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:323
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:1953
SCReturn
#define SCReturn
Definition: util-debug.h:302
Packet_
Definition: decode.h:414
StreamTcpFreeConfig
void StreamTcpFreeConfig(char quiet)
Definition: stream-tcp.c:668
SIG_FLAG_INIT_DCERPC
#define SIG_FLAG_INIT_DCERPC
Definition: detect.h:266
DETECT_DCE_IFACE
@ DETECT_DCE_IFACE
Definition: detect-engine-register.h:184
Signature_::init_data
SignatureInitData * init_data
Definition: detect.h:597
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:1888
SigMatch_::type
uint8_t type
Definition: detect.h:321
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:315
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:2361
Packet_::flow
struct Flow_ * flow
Definition: decode.h:451
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:1212
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:1203
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:528
SigMatch_
a single match condition for a signature
Definition: detect.h:320
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:768
AppLayerParserThreadCtx_
Definition: app-layer-parser.c:87
TcpSession_
Definition: stream-tcp-private.h:260
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:1107
SigTableElmt_::RegisterTests
void(* RegisterTests)(void)
Definition: detect.h:1203
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