suricata
detect-dce-opnum.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2022 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_opnum 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 
35 #include "flow.h"
36 #include "flow-var.h"
37 #include "flow-util.h"
38 
39 #include "app-layer.h"
40 #include "queue.h"
41 #include "stream-tcp-reassemble.h"
42 #include "detect-dce-opnum.h"
43 #include "detect-dce-iface.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-9]{1,5}(\\s*-\\s*[0-9]{1,5}\\s*)?)(,\\s*[0-9]{1,5}(\\s*-\\s*[0-9]{1,5})?\\s*)*$"
53 
54 static DetectParseRegex parse_regex;
55 
56 static int DetectDceOpnumMatchRust(DetectEngineThreadCtx *det_ctx,
57  Flow *f, uint8_t flags, void *state, void *txv,
58  const Signature *s, const SigMatchCtx *m);
59 static int DetectDceOpnumSetup(DetectEngineCtx *, Signature *, const char *);
60 static void DetectDceOpnumFree(DetectEngineCtx *, void *);
61 #ifdef UNITTESTS
62 static void DetectDceOpnumRegisterTests(void);
63 #endif
64 static int g_dce_generic_list_id = 0;
65 
66 /**
67  * \brief Registers the keyword handlers for the "dce_opnum" keyword.
68  */
70 {
71  sigmatch_table[DETECT_DCE_OPNUM].name = "dcerpc.opnum";
72  sigmatch_table[DETECT_DCE_OPNUM].alias = "dce_opnum";
73  sigmatch_table[DETECT_DCE_OPNUM].AppLayerTxMatch = DetectDceOpnumMatchRust;
74  sigmatch_table[DETECT_DCE_OPNUM].Setup = DetectDceOpnumSetup;
75  sigmatch_table[DETECT_DCE_OPNUM].Free = DetectDceOpnumFree;
76 #ifdef UNITTESTS
77  sigmatch_table[DETECT_DCE_OPNUM].RegisterTests = DetectDceOpnumRegisterTests;
78 #endif
79  DetectSetupParseRegexes(PARSE_REGEX, &parse_regex);
80 
81  g_dce_generic_list_id = DetectBufferTypeRegister("dce_generic");
82 }
83 
84 /**
85  * \brief App layer match function for the "dce_opnum" keyword.
86  *
87  * \param t Pointer to the ThreadVars instance.
88  * \param det_ctx Pointer to the DetectEngineThreadCtx.
89  * \param f Pointer to the flow.
90  * \param flags Pointer to the flags indicating the flow direction.
91  * \param state Pointer to the app layer state data.
92  * \param s Pointer to the Signature instance.
93  * \param m Pointer to the SigMatch.
94  *
95  * \retval 1 On Match.
96  * \retval 0 On no match.
97  */
98 static int DetectDceOpnumMatchRust(DetectEngineThreadCtx *det_ctx,
99  Flow *f, uint8_t flags, void *state, void *txv,
100  const Signature *s, const SigMatchCtx *m)
101 {
102  SCEnter();
103 
104  if (f->alproto == ALPROTO_DCERPC) {
105  return rs_dcerpc_opnum_match(txv, (void *)m);
106  }
107 
108  if (rs_smb_tx_match_dce_opnum(txv, (void *)m) != 1)
109  SCReturnInt(0);
110 
111  SCReturnInt(1);
112 }
113 
114 /**
115  * \brief Creates a SigMatch for the "dce_opnum" keyword being sent as argument,
116  * and appends it to the rs_dcerpc_opnum_matchSignature(s).
117  *
118  * \param de_ctx Pointer to the detection engine context.
119  * \param s Pointer to signature for the current Signature being parsed
120  * from the rules.
121  * \param arg Pointer to the string holding the keyword value.
122  *
123  * \retval 0 on success, -1 on failure
124  */
125 
126 static int DetectDceOpnumSetup(DetectEngineCtx *de_ctx, Signature *s, const char *arg)
127 {
128  if (arg == NULL) {
129  SCLogError(SC_ERR_INVALID_SIGNATURE, "Error parsing dce_opnum option in "
130  "signature, option needs a value");
131  return -1;
132  }
133 
134  if (s->alproto != ALPROTO_UNKNOWN && s->alproto != ALPROTO_DCERPC &&
135  s->alproto != ALPROTO_SMB) {
136  SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains conflicting keywords.");
137  return -1;
138  }
139  void *dod = rs_dcerpc_opnum_parse(arg);
140  if (dod == NULL) {
141  SCLogError(SC_ERR_INVALID_SIGNATURE, "Error parsing dce_opnum option in "
142  "signature");
143  return -1;
144  }
145 
146  SigMatch *sm = SigMatchAlloc();
147  if (sm == NULL) {
148  DetectDceOpnumFree(de_ctx, dod);
149  return -1;
150  }
151 
152  sm->type = DETECT_DCE_OPNUM;
153  sm->ctx = (void *)dod;
154 
155  SigMatchAppendSMToList(s, sm, g_dce_generic_list_id);
157  return 0;
158 }
159 
160 static void DetectDceOpnumFree(DetectEngineCtx *de_ctx, void *ptr)
161 {
162  SCEnter();
163  if (ptr != NULL) {
164  rs_dcerpc_opnum_free(ptr);
165  }
166  SCReturn;
167 }
168 
169 /************************************Unittests*********************************/
170 
171 #ifdef UNITTESTS
172 
173 /* Disabled because of bug_753. Would be enabled, once we rewrite
174  * dce parser */
175 #if 0
176 
177 /**
178  * \test Test a valid dce_opnum(with multiple values) with a bind, bind_ack,
179  * and multiple request/responses with a match test after each frag parsing.
180  */
181 static int DetectDceOpnumTestParse10(void)
182 {
183  int result = 0;
184  Signature *s = NULL;
185  ThreadVars th_v;
186  Packet *p = NULL;
187  Flow f;
188  TcpSession ssn;
189  DetectEngineThreadCtx *det_ctx = NULL;
190  DetectEngineCtx *de_ctx = NULL;
191  DCERPCState *dcerpc_state = NULL;
192  int r = 0;
193 
194  uint8_t dcerpc_bind[] = {
195  0x05, 0x00, 0x0b, 0x03, 0x10, 0x00, 0x00, 0x00,
196  0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
197  0xb8, 0x10, 0xb8, 0x10, 0x00, 0x00, 0x00, 0x00,
198  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
199  0x01, 0xd0, 0x8c, 0x33, 0x44, 0x22, 0xf1, 0x31,
200  0xaa, 0xaa, 0x90, 0x00, 0x38, 0x00, 0x10, 0x03,
201  0x01, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a,
202  0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00,
203  0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00,
204  };
205 
206  uint8_t dcerpc_bindack[] = {
207  0x05, 0x00, 0x0c, 0x03, 0x10, 0x00, 0x00, 0x00,
208  0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
209  0xb8, 0x10, 0xb8, 0x10, 0x65, 0x8e, 0x00, 0x00,
210  0x0d, 0x00, 0x5c, 0x50, 0x49, 0x50, 0x45, 0x5c,
211  0x77, 0x69, 0x6e, 0x72, 0x65, 0x67, 0x00, 0x6d,
212  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
213  0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11,
214  0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60,
215  0x02, 0x00, 0x00, 0x00,
216  };
217 
218  uint8_t dcerpc_request1[] = {
219  0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00,
220  0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
221  0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
222  0x2c, 0xfd, 0xb5, 0x00, 0x40, 0xaa, 0x01, 0x00,
223  0x00, 0x00, 0x00, 0x02,
224  };
225 
226  uint8_t dcerpc_response1[] = {
227  0x05, 0x00, 0x02, 0x03, 0x10, 0x00, 0x00, 0x00,
228  0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
229  0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
230  0x00, 0x00, 0x00, 0x00, 0xf6, 0x72, 0x28, 0x9c,
231  0xf0, 0x57, 0xd8, 0x11, 0xb0, 0x05, 0x00, 0x0c,
232  0x29, 0x87, 0xea, 0xe9, 0x00, 0x00, 0x00, 0x00,
233  };
234 
235  uint8_t dcerpc_request2[] = {
236  0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00,
237  0xa4, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
238  0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00,
239  0x00, 0x00, 0x00, 0x00, 0xf6, 0x72, 0x28, 0x9c,
240  0xf0, 0x57, 0xd8, 0x11, 0xb0, 0x05, 0x00, 0x0c,
241  0x29, 0x87, 0xea, 0xe9, 0x5c, 0x00, 0x5c, 0x00,
242  0xa8, 0xb9, 0x14, 0x00, 0x2e, 0x00, 0x00, 0x00,
243  0x00, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00,
244  0x53, 0x00, 0x4f, 0x00, 0x46, 0x00, 0x54, 0x00,
245  0x57, 0x00, 0x41, 0x00, 0x52, 0x00, 0x45, 0x00,
246  0x5c, 0x00, 0x4d, 0x00, 0x69, 0x00, 0x63, 0x00,
247  0x72, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x6f, 0x00,
248  0x66, 0x00, 0x74, 0x00, 0x5c, 0x00, 0x57, 0x00,
249  0x69, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x6f, 0x00,
250  0x77, 0x00, 0x73, 0x00, 0x5c, 0x00, 0x43, 0x00,
251  0x75, 0x00, 0x72, 0x00, 0x72, 0x00, 0x65, 0x00,
252  0x6e, 0x00, 0x74, 0x00, 0x56, 0x00, 0x65, 0x00,
253  0x72, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00,
254  0x6e, 0x00, 0x5c, 0x00, 0x52, 0x00, 0x75, 0x00,
255  0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
256  0x03, 0x00, 0x00, 0x00,
257  };
258 
259  uint8_t dcerpc_response2[] = {
260  0x05, 0x00, 0x02, 0x03, 0x10, 0x00, 0x00, 0x00,
261  0x30, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
262  0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
263  0x00, 0x00, 0x00, 0x00, 0xf7, 0x72, 0x28, 0x9c,
264  0xf0, 0x57, 0xd8, 0x11, 0xb0, 0x05, 0x00, 0x0c,
265  0x29, 0x87, 0xea, 0xe9, 0x00, 0x00, 0x00, 0x00,
266  };
267 
268  uint8_t dcerpc_request3[] = {
269  0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00,
270  0x70, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
271  0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00,
272  0x00, 0x00, 0x00, 0x00, 0xf7, 0x72, 0x28, 0x9c,
273  0xf0, 0x57, 0xd8, 0x11, 0xb0, 0x05, 0x00, 0x0c,
274  0x29, 0x87, 0xea, 0xe9, 0x0c, 0x00, 0x0c, 0x00,
275  0x98, 0xda, 0x14, 0x00, 0x06, 0x00, 0x00, 0x00,
276  0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
277  0x4f, 0x00, 0x73, 0x00, 0x61, 0x00, 0x33, 0x00,
278  0x32, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
279  0x18, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x54, 0x00,
280  0x4f, 0x00, 0x53, 0x00, 0x41, 0x00, 0x33, 0x00,
281  0x32, 0x00, 0x2e, 0x00, 0x45, 0x00, 0x58, 0x00,
282  0x45, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
283  };
284 
285  uint8_t dcerpc_response3[] = {
286  0x05, 0x00, 0x02, 0x03, 0x10, 0x00, 0x00, 0x00,
287  0x1c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
288  0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
289  0x00, 0x00, 0x00, 0x00,
290  };
291 
292  uint32_t dcerpc_bind_len = sizeof(dcerpc_bind);
293  uint32_t dcerpc_bindack_len = sizeof(dcerpc_bindack);
294 
295  uint32_t dcerpc_request1_len = sizeof(dcerpc_request1);
296  uint32_t dcerpc_response1_len = sizeof(dcerpc_response1);
297 
298  uint32_t dcerpc_request2_len = sizeof(dcerpc_request2);
299  uint32_t dcerpc_response2_len = sizeof(dcerpc_response2);
300 
301  uint32_t dcerpc_request3_len = sizeof(dcerpc_request3);
302  uint32_t dcerpc_response3_len = sizeof(dcerpc_response3);
303 
305 
306  memset(&th_v, 0, sizeof(th_v));
307  memset(&f, 0, sizeof(f));
308  memset(&ssn, 0, sizeof(ssn));
309 
310  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
311 
312  FLOW_INITIALIZE(&f);
313  f.protoctx = (void *)&ssn;
314  f.proto = IPPROTO_TCP;
315  p->flow = &f;
320 
321  StreamTcpInitConfig(true);
322 
324  if (de_ctx == NULL) {
325  goto end;
326  }
327 
328  de_ctx->flags |= DE_QUIET;
329 
330  s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
331  "(msg:\"DCERPC\"; dce_opnum:2,15,22; sid:1;)");
332  if (s == NULL) {
333  goto end;
334  }
335 
337  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
338 
339  SCLogDebug("sending bind");
340 
341  r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER | STREAM_START,
342  dcerpc_bind, dcerpc_bind_len);
343  if (r != 0) {
344  SCLogDebug("AppLayerParse for dcerpc bind failed. Returned %" PRId32, r);
345  goto end;
346  }
347 
348  dcerpc_state = f.alstate;
349  if (dcerpc_state == NULL) {
350  SCLogDebug("no dcerpc state: ");
351  goto end;
352  }
355  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
356 
357  SCLogDebug("sending bind_ack");
358 
359  r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT,
360  dcerpc_bindack, dcerpc_bindack_len);
361  if (r != 0) {
362  SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r);
363  goto end;
364  }
367  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
368 
369  SCLogDebug("sending request1");
370 
371  /* request1 */
372  r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER,
373  dcerpc_request1, dcerpc_request1_len);
374  if (r != 0) {
375  SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r);
376  goto end;
377  }
378 
381  /* do detect */
382  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
383 
384  if (!PacketAlertCheck(p, 1)) {
385  printf("sig 1 didn't match, but should have: ");
386  goto end;
387  }
388 
389  SCLogDebug("sending response1");
390 
391  /* response1 */
392  r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT,
393  dcerpc_response1, dcerpc_response1_len);
394  if (r != 0) {
395  SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r);
396  goto end;
397  }
398 
401  /* do detect */
402  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
403 
404  if (PacketAlertCheck(p, 1)) {
405  printf("sig 1 did match, shouldn't have on response1: ");
406  goto end;
407  }
408 
409  /* request2 */
410  r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER,
411  dcerpc_request2, dcerpc_request2_len);
412  if (r != 0) {
413  SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r);
414  goto end;
415  }
416 
419  /* do detect */
420  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
421 
422  if (!PacketAlertCheck(p, 1)) {
423  printf("sig 1 didn't match, but should have on request2: ");
424  goto end;
425  }
426 
427  /* response2 */
428  r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT,
429  dcerpc_response2, dcerpc_response2_len);
430  if (r != 0) {
431  SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r);
432  goto end;
433  }
434 
437  /* do detect */
438  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
439 
440  if (PacketAlertCheck(p, 1)) {
441  printf("sig 1 did match, shouldn't have on response2: ");
442  goto end;
443  }
444 
445  /* request3 */
446  r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER,
447  dcerpc_request3, dcerpc_request3_len);
448  if (r != 0) {
449  SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r);
450  goto end;
451  }
452 
455  /* do detect */
456  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
457 
458  if (!PacketAlertCheck(p, 1)) {
459  printf("sig 1 didn't match, but should have on request3: ");
460  goto end;
461  }
462 
463  /* response3 */
464  r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT | STREAM_EOF,
465  dcerpc_response3, dcerpc_response3_len);
466  if (r != 0) {
467  SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r);
468  goto end;
469  }
470 
473  /* do detect */
474  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
475 
476  if (PacketAlertCheck(p, 1)) {
477  printf("sig 1 did match, shouldn't have on response2: ");
478  goto end;
479  }
480 
481  result = 1;
482 
483  end:
484  if (alp_tctx != NULL)
488 
489  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
491 
492  StreamTcpFreeConfig(true);
493  FLOW_DESTROY(&f);
494 
495  UTHFreePackets(&p, 1);
496  return result;
497 }
498 
499 /**
500  * \test Test a valid dce_opnum entry(with multiple values) with multiple
501  * request/responses.
502  */
503 static int DetectDceOpnumTestParse11(void)
504 {
505  int result = 0;
506  Signature *s = NULL;
507  ThreadVars th_v;
508  Packet *p = NULL;
509  Flow f;
510  TcpSession ssn;
511  DetectEngineThreadCtx *det_ctx = NULL;
512  DetectEngineCtx *de_ctx = NULL;
513  DCERPCState *dcerpc_state = NULL;
514  int r = 0;
515 
516  uint8_t dcerpc_request1[] = {
517  0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00,
518  0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
519  0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
520  0x2c, 0xfd, 0xb5, 0x00, 0x40, 0xaa, 0x01, 0x00,
521  0x00, 0x00, 0x00, 0x02,
522  };
523 
524  uint8_t dcerpc_response1[] = {
525  0x05, 0x00, 0x02, 0x03, 0x10, 0x00, 0x00, 0x00,
526  0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
527  0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
528  0x00, 0x00, 0x00, 0x00, 0xf6, 0x72, 0x28, 0x9c,
529  0xf0, 0x57, 0xd8, 0x11, 0xb0, 0x05, 0x00, 0x0c,
530  0x29, 0x87, 0xea, 0xe9, 0x00, 0x00, 0x00, 0x00,
531  };
532 
533  uint8_t dcerpc_request2[] = {
534  0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00,
535  0xa4, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
536  0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00,
537  0x00, 0x00, 0x00, 0x00, 0xf6, 0x72, 0x28, 0x9c,
538  0xf0, 0x57, 0xd8, 0x11, 0xb0, 0x05, 0x00, 0x0c,
539  0x29, 0x87, 0xea, 0xe9, 0x5c, 0x00, 0x5c, 0x00,
540  0xa8, 0xb9, 0x14, 0x00, 0x2e, 0x00, 0x00, 0x00,
541  0x00, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00,
542  0x53, 0x00, 0x4f, 0x00, 0x46, 0x00, 0x54, 0x00,
543  0x57, 0x00, 0x41, 0x00, 0x52, 0x00, 0x45, 0x00,
544  0x5c, 0x00, 0x4d, 0x00, 0x69, 0x00, 0x63, 0x00,
545  0x72, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x6f, 0x00,
546  0x66, 0x00, 0x74, 0x00, 0x5c, 0x00, 0x57, 0x00,
547  0x69, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x6f, 0x00,
548  0x77, 0x00, 0x73, 0x00, 0x5c, 0x00, 0x43, 0x00,
549  0x75, 0x00, 0x72, 0x00, 0x72, 0x00, 0x65, 0x00,
550  0x6e, 0x00, 0x74, 0x00, 0x56, 0x00, 0x65, 0x00,
551  0x72, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00,
552  0x6e, 0x00, 0x5c, 0x00, 0x52, 0x00, 0x75, 0x00,
553  0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
554  0x03, 0x00, 0x00, 0x00,
555  };
556 
557  uint8_t dcerpc_response2[] = {
558  0x05, 0x00, 0x02, 0x03, 0x10, 0x00, 0x00, 0x00,
559  0x30, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
560  0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
561  0x00, 0x00, 0x00, 0x00, 0xf7, 0x72, 0x28, 0x9c,
562  0xf0, 0x57, 0xd8, 0x11, 0xb0, 0x05, 0x00, 0x0c,
563  0x29, 0x87, 0xea, 0xe9, 0x00, 0x00, 0x00, 0x00,
564  };
565 
566  uint8_t dcerpc_request3[] = {
567  0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00,
568  0x70, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
569  0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00,
570  0x00, 0x00, 0x00, 0x00, 0xf7, 0x72, 0x28, 0x9c,
571  0xf0, 0x57, 0xd8, 0x11, 0xb0, 0x05, 0x00, 0x0c,
572  0x29, 0x87, 0xea, 0xe9, 0x0c, 0x00, 0x0c, 0x00,
573  0x98, 0xda, 0x14, 0x00, 0x06, 0x00, 0x00, 0x00,
574  0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
575  0x4f, 0x00, 0x73, 0x00, 0x61, 0x00, 0x33, 0x00,
576  0x32, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
577  0x18, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x54, 0x00,
578  0x4f, 0x00, 0x53, 0x00, 0x41, 0x00, 0x33, 0x00,
579  0x32, 0x00, 0x2e, 0x00, 0x45, 0x00, 0x58, 0x00,
580  0x45, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
581  };
582 
583  uint8_t dcerpc_response3[] = {
584  0x05, 0x00, 0x02, 0x03, 0x10, 0x00, 0x00, 0x00,
585  0x1c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
586  0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
587  0x00, 0x00, 0x00, 0x00,
588  };
589 
590  uint32_t dcerpc_request1_len = sizeof(dcerpc_request1);
591  uint32_t dcerpc_response1_len = sizeof(dcerpc_response1);
592 
593  uint32_t dcerpc_request2_len = sizeof(dcerpc_request2);
594  uint32_t dcerpc_response2_len = sizeof(dcerpc_response2);
595 
596  uint32_t dcerpc_request3_len = sizeof(dcerpc_request3);
597  uint32_t dcerpc_response3_len = sizeof(dcerpc_response3);
598 
600 
601  memset(&th_v, 0, sizeof(th_v));
602  memset(&f, 0, sizeof(f));
603  memset(&ssn, 0, sizeof(ssn));
604 
605  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
606 
607  FLOW_INITIALIZE(&f);
608  f.protoctx = (void *)&ssn;
609  f.proto = IPPROTO_TCP;
610  p->flow = &f;
615 
616  StreamTcpInitConfig(true);
617 
619  if (de_ctx == NULL)
620  goto end;
621 
622  de_ctx->flags |= DE_QUIET;
623 
624  s = de_ctx->sig_list = SigInit(de_ctx,
625  "alert tcp any any -> any any "
626  "(msg:\"DCERPC\"; "
627  "dce_opnum:2-22; "
628  "sid:1;)");
629  if (s == NULL)
630  goto end;
631 
633  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
634 
635  /* request1 */
636  r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER | STREAM_START,
637  dcerpc_request1, dcerpc_request1_len);
638  if (r != 0) {
639  SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r);
640  printf("AppLayerParse for dcerpcrequest1 failed. Returned %" PRId32, r);
641  goto end;
642  }
643 
644  dcerpc_state = f.alstate;
645  if (dcerpc_state == NULL) {
646  SCLogDebug("no dcerpc state: ");
647  printf("no dcerpc state: ");
648  goto end;
649  }
650 
653  /* do detect */
654  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
655 
656  if (!PacketAlertCheck(p, 1))
657  goto end;
658 
659  /* response1 */
660  r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT,
661  dcerpc_response1, dcerpc_response1_len);
662  if (r != 0) {
663  SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r);
664  printf("AppLayerParse for dcerpcresponse1 failed. Returned %" PRId32, r);
665  goto end;
666  }
667 
670  /* do detect */
671  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
672 
673  if (PacketAlertCheck(p, 1))
674  goto end;
675 
676  /* request2 */
677  r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER,
678  dcerpc_request2, dcerpc_request2_len);
679  if (r != 0) {
680  SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r);
681  printf("AppLayerParse for dcerpcrequest2 failed. Returned %" PRId32, r);
682  goto end;
683  }
684 
687  /* do detect */
688  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
689 
690  if (!PacketAlertCheck(p, 1))
691  goto end;
692 
693  /* response2 */
694  r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT,
695  dcerpc_response2, dcerpc_response2_len);
696  if (r != 0) {
697  SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r);
698  printf("AppLayerParse for dcerpcresponse2 failed. Returned %" PRId32, r);
699  goto end;
700  }
701 
704  /* do detect */
705  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
706 
707  if (PacketAlertCheck(p, 1))
708  goto end;
709 
710  /* request3 */
711  r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER,
712  dcerpc_request3, dcerpc_request3_len);
713  if (r != 0) {
714  SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r);
715  printf("AppLayerParse for dcerpc request3 failed. Returned %" PRId32, r);
716  goto end;
717  }
718 
721  /* do detect */
722  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
723 
724  if (!PacketAlertCheck(p, 1))
725  goto end;
726 
727  /* response3 */
728  r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT | STREAM_EOF,
729  dcerpc_response3, dcerpc_response3_len);
730  if (r != 0) {
731  SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r);
732  printf("AppLayerParse for dcerpc response3 failed. Returned %" PRId32, r);
733  goto end;
734  }
735 
738  /* do detect */
739  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
740 
741  if (PacketAlertCheck(p, 1))
742  goto end;
743 
744  result = 1;
745 
746  end:
747  if (alp_tctx != NULL)
751 
752  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
754 
755  StreamTcpFreeConfig(true);
756  FLOW_DESTROY(&f);
757 
758  UTHFreePackets(&p, 1);
759  return result;
760 }
761 
762 /**
763  * \test Test a valid dce_opnum(with multiple values) with a bind, bind_ack,
764  * and multiple request/responses with a match test after each frag parsing.
765  */
766 static int DetectDceOpnumTestParse12(void)
767 {
768  int result = 0;
769  Signature *s = NULL;
770  ThreadVars th_v;
771  Packet *p = NULL;
772  Flow f;
773  TcpSession ssn;
774  DetectEngineThreadCtx *det_ctx = NULL;
775  DetectEngineCtx *de_ctx = NULL;
776  DCERPCState *dcerpc_state = NULL;
777  int r = 0;
778 
779  uint8_t dcerpc_bind[] = {
780  0x05, 0x00, 0x0b, 0x03, 0x10, 0x00, 0x00, 0x00,
781  0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
782  0xd0, 0x16, 0xd0, 0x16, 0x00, 0x00, 0x00, 0x00,
783  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
784  0x40, 0xfd, 0x2c, 0x34, 0x6c, 0x3c, 0xce, 0x11,
785  0xa8, 0x93, 0x08, 0x00, 0x2b, 0x2e, 0x9c, 0x6d,
786  0x00, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a,
787  0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00,
788  0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00,
789  };
790 
791  uint8_t dcerpc_bindack[] = {
792  0x05, 0x00, 0x0c, 0x03, 0x10, 0x00, 0x00, 0x00,
793  0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
794  0xb8, 0x10, 0xb8, 0x10, 0x7d, 0xd8, 0x00, 0x00,
795  0x0d, 0x00, 0x5c, 0x70, 0x69, 0x70, 0x65, 0x5c,
796  0x6c, 0x6c, 0x73, 0x72, 0x70, 0x63, 0x00, 0x00,
797  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
798  0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11,
799  0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60,
800  0x02, 0x00, 0x00, 0x00,
801  };
802 
803  uint8_t dcerpc_request1[] = {
804  0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00,
805  0x9a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
806  0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, //opnum is 0x28 0x00
807  0x00, 0x00, 0x00, 0x00, 0x07, 0x9f, 0x13, 0xd9,
808  0x2d, 0x97, 0xf4, 0x4a, 0xac, 0xc2, 0xbc, 0x70,
809  0xec, 0xaa, 0x9a, 0xd3, 0x01, 0x00, 0x00, 0x00,
810  0x01, 0x00, 0x00, 0x00, 0x40, 0x80, 0x40, 0x00,
811  0x44, 0x80, 0x40, 0x00, 0x01, 0x00, 0x00, 0x00,
812  0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
813  0x09, 0x00, 0x00, 0x00, 0x4d, 0x6f, 0x00, 0x4e,
814  0x61, 0x6d, 0x65, 0x00, 0x35, 0x39, 0x31, 0x63,
815  0x64, 0x30, 0x35, 0x38, 0x00, 0x00, 0x00, 0x00,
816  0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
817  0x17, 0x00, 0x00, 0x00, 0xd0, 0x2e, 0x08, 0x00,
818  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
819  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
820  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
821  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
822  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
823  0x00, 0x00
824  };
825 
826  uint8_t dcerpc_response1[] = {
827  0x05, 0x00, 0x02, 0x03, 0x10, 0x00, 0x00, 0x00,
828  0x1c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
829  0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
830  0x00, 0x00, 0x00, 0x00,
831  };
832 
833  uint8_t dcerpc_request2[] = {
834  0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00,
835  0x54, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
836  0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00,
837  0x00, 0x00, 0x00, 0x00, 0x07, 0x9f, 0x13, 0xd9,
838  0x2d, 0x97, 0xf4, 0x4a, 0xac, 0xc2, 0xbc, 0x70,
839  0xec, 0xaa, 0x9a, 0xd3, 0x09, 0x00, 0x00, 0x00,
840  0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
841  0x4d, 0x6f, 0x00, 0x4e, 0x61, 0x6d, 0x65, 0x00,
842  0x35, 0x39, 0x31, 0x63, 0x64, 0x30, 0x35, 0x38,
843  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
844  0x4e, 0x6f, 0x6e, 0x65
845  };
846 
847  uint8_t dcerpc_response2[] = {
848  0x05, 0x00, 0x02, 0x03, 0x10, 0x00, 0x00, 0x00,
849  0x8c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
850  0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
851  0xd8, 0x17, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00,
852  0x58, 0x1d, 0x08, 0x00, 0xe8, 0x32, 0x08, 0x00,
853  0x01, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
854  0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
855  0x4d, 0x6f, 0x00, 0x4e, 0x61, 0x6d, 0x65, 0x00,
856  0x35, 0x39, 0x31, 0x63, 0x64, 0x30, 0x35, 0x38,
857  0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00,
858  0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00,
859  0xd0, 0x2e, 0x08, 0x00, 0x41, 0x41, 0x41, 0x41,
860  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
861  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
862  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
863  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
864  0x41, 0x41, 0x41, 0x41, 0x00, 0x00, 0x00, 0x00,
865  0x00, 0x00, 0x00, 0x00,
866  };
867 
868  uint32_t dcerpc_bind_len = sizeof(dcerpc_bind);
869  uint32_t dcerpc_bindack_len = sizeof(dcerpc_bindack);
870 
871  uint32_t dcerpc_request1_len = sizeof(dcerpc_request1);
872  uint32_t dcerpc_response1_len = sizeof(dcerpc_response1);
873 
874  uint32_t dcerpc_request2_len = sizeof(dcerpc_request2);
875  uint32_t dcerpc_response2_len = sizeof(dcerpc_response2);
876 
878 
879  memset(&th_v, 0, sizeof(th_v));
880  memset(&f, 0, sizeof(f));
881  memset(&ssn, 0, sizeof(ssn));
882 
883  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
884 
885  FLOW_INITIALIZE(&f);
886  f.protoctx = (void *)&ssn;
887  f.proto = IPPROTO_TCP;
888  p->flow = &f;
893 
894  StreamTcpInitConfig(true);
895 
897  if (de_ctx == NULL)
898  goto end;
899 
900  de_ctx->flags |= DE_QUIET;
901 
902  s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
903  "(msg:\"DCERPC\"; dce_opnum:30, 40; sid:1;)");
904  if (s == NULL)
905  goto end;
906 
908  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
909 
910  r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER | STREAM_START,
911  dcerpc_bind, dcerpc_bind_len);
912  if (r != 0) {
913  printf("AppLayerParse for dcerpc failed. Returned %" PRId32, r);
914  goto end;
915  }
918  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
919 
920  dcerpc_state = f.alstate;
921  if (dcerpc_state == NULL) {
922  printf("no dcerpc state: ");
923  goto end;
924  }
925 
926  r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT, dcerpc_bindack,
927  dcerpc_bindack_len);
928  if (r != 0) {
929  printf("AppLayerParse for dcerpc failed. Returned %" PRId32, r);
930  goto end;
931  }
934  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
935 
936  /* request1 */
937  SCLogDebug("Sending request1");
938 
939  r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, dcerpc_request1,
940  dcerpc_request1_len);
941  if (r != 0) {
942  printf("AppLayerParse for dcerpc failed. Returned %" PRId32, r);
943  goto end;
944  }
945 
946  dcerpc_state = f.alstate;
947  if (dcerpc_state == NULL) {
948  printf("no dcerpc state: ");
949  goto end;
950  }
951 
952  if (dcerpc_state->dcerpc.dcerpcrequest.opnum != 40) {
953  printf("dcerpc state holding invalid opnum. Holding %d, while we are "
954  "expecting 40: ", dcerpc_state->dcerpc.dcerpcrequest.opnum);
955  goto end;
956  }
957 
960  /* do detect */
961  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
962 
963  if (!PacketAlertCheck(p, 1)) {
964  printf("signature 1 didn't match, should have: ");
965  goto end;
966  }
967 
968  /* response1 */
969  r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT, dcerpc_response1,
970  dcerpc_response1_len);
971  if (r != 0) {
972  printf("AppLayerParse for dcerpc failed. Returned %" PRId32, r);
973  goto end;
974  }
975 
976  dcerpc_state = f.alstate;
977  if (dcerpc_state == NULL) {
978  printf("no dcerpc state: ");
979  goto end;
980  }
981 
982  if (dcerpc_state->dcerpc.dcerpcrequest.opnum != 40) {
983  printf("dcerpc state holding invalid opnum. Holding %d, while we are "
984  "expecting 40\n", dcerpc_state->dcerpc.dcerpcrequest.opnum);
985  goto end;
986  }
987 
990  /* do detect */
991  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
992 
993  if (PacketAlertCheck(p, 1)) {
994  printf("sig 1 matched on response 1, but shouldn't: ");
995  goto end;
996  }
997 
998  /* request2 */
999  r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, dcerpc_request2,
1000  dcerpc_request2_len);
1001  if (r != 0) {
1002  printf("AppLayerParse for dcerpc failed. Returned %" PRId32, r);
1003  goto end;
1004  }
1005 
1006  dcerpc_state = f.alstate;
1007  if (dcerpc_state == NULL) {
1008  printf("no dcerpc state: ");
1009  goto end;
1010  }
1011 
1012  if (dcerpc_state->dcerpc.dcerpcrequest.opnum != 30) {
1013  printf("dcerpc state holding invalid opnum. Holding %d, while we are "
1014  "expecting 30\n", dcerpc_state->dcerpc.dcerpcrequest.opnum);
1015  goto end;
1016  }
1017 
1020  /* do detect */
1021  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1022 
1023  if (!PacketAlertCheck(p, 1)) {
1024  printf("sig 1 didn't match on request 2: ");
1025  goto end;
1026  }
1027 
1028  /* response2 */
1029  r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT | STREAM_EOF, dcerpc_response2,
1030  dcerpc_response2_len);
1031  if (r != 0) {
1032  printf("AppLayerParse for dcerpc failed. Returned %" PRId32, r);
1033  goto end;
1034  }
1035 
1036  dcerpc_state = f.alstate;
1037  if (dcerpc_state == NULL) {
1038  printf("no dcerpc state: ");
1039  goto end;
1040  }
1041 
1042  if (dcerpc_state->dcerpc.dcerpcrequest.opnum != 30) {
1043  printf("dcerpc state holding invalid opnum. Holding %d, while we are "
1044  "expecting 30\n", dcerpc_state->dcerpc.dcerpcrequest.opnum);
1045  goto end;
1046  }
1047 
1050  /* do detect */
1051  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1052 
1053  if (PacketAlertCheck(p, 1)) {
1054  printf("sig 1 matched on response2, but shouldn't: ");
1055  goto end;
1056  }
1057 
1058  result = 1;
1059 
1060 end:
1061  if (alp_tctx != NULL)
1065 
1066  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1068 
1069  StreamTcpFreeConfig(true);
1070  FLOW_DESTROY(&f);
1071 
1072  UTHFreePackets(&p, 1);
1073  return result;
1074 }
1075 
1076 /**
1077  * \test Test a valid dce_opnum(with multiple values) with a bind, bind_ack,
1078  * and multiple request/responses with a match test after each frag parsing.
1079  */
1080 static int DetectDceOpnumTestParse13(void)
1081 {
1082  int result = 0;
1083  Signature *s = NULL;
1084  ThreadVars th_v;
1085  Packet *p = NULL;
1086  Flow f;
1087  TcpSession ssn;
1088  DetectEngineThreadCtx *det_ctx = NULL;
1089  DetectEngineCtx *de_ctx = NULL;
1090  DCERPCState *dcerpc_state = NULL;
1091  int r = 0;
1092 
1093  uint8_t dcerpc_request1[] = {
1094  0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00,
1095  0x9a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1096  0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00,
1097  0x00, 0x00, 0x00, 0x00, 0x07, 0x9f, 0x13, 0xd9,
1098  0x2d, 0x97, 0xf4, 0x4a, 0xac, 0xc2, 0xbc, 0x70,
1099  0xec, 0xaa, 0x9a, 0xd3, 0x01, 0x00, 0x00, 0x00,
1100  0x01, 0x00, 0x00, 0x00, 0x40, 0x80, 0x40, 0x00,
1101  0x44, 0x80, 0x40, 0x00, 0x01, 0x00, 0x00, 0x00,
1102  0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1103  0x09, 0x00, 0x00, 0x00, 0x4d, 0x6f, 0x00, 0x4e,
1104  0x61, 0x6d, 0x65, 0x00, 0x35, 0x39, 0x31, 0x63,
1105  0x64, 0x30, 0x35, 0x38, 0x00, 0x00, 0x00, 0x00,
1106  0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1107  0x17, 0x00, 0x00, 0x00, 0xd0, 0x2e, 0x08, 0x00,
1108  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
1109  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
1110  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
1111  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
1112  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
1113  0x00, 0x00
1114  };
1115 
1116  uint8_t dcerpc_response1[] = {
1117  0x05, 0x00, 0x02, 0x03, 0x10, 0x00, 0x00, 0x00,
1118  0x1c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1119  0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1120  0x00, 0x00, 0x00, 0x00,
1121  };
1122 
1123  uint8_t dcerpc_request2[] = {
1124  0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00,
1125  0x54, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1126  0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00,
1127  0x00, 0x00, 0x00, 0x00, 0x07, 0x9f, 0x13, 0xd9,
1128  0x2d, 0x97, 0xf4, 0x4a, 0xac, 0xc2, 0xbc, 0x70,
1129  0xec, 0xaa, 0x9a, 0xd3, 0x09, 0x00, 0x00, 0x00,
1130  0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
1131  0x4d, 0x6f, 0x00, 0x4e, 0x61, 0x6d, 0x65, 0x00,
1132  0x35, 0x39, 0x31, 0x63, 0x64, 0x30, 0x35, 0x38,
1133  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1134  0x4e, 0x6f, 0x6e, 0x65
1135  };
1136 
1137  uint8_t dcerpc_response2[] = {
1138  0x05, 0x00, 0x02, 0x03, 0x10, 0x00, 0x00, 0x00,
1139  0x8c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1140  0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1141  0xd8, 0x17, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00,
1142  0x58, 0x1d, 0x08, 0x00, 0xe8, 0x32, 0x08, 0x00,
1143  0x01, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
1144  0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
1145  0x4d, 0x6f, 0x00, 0x4e, 0x61, 0x6d, 0x65, 0x00,
1146  0x35, 0x39, 0x31, 0x63, 0x64, 0x30, 0x35, 0x38,
1147  0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00,
1148  0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00,
1149  0xd0, 0x2e, 0x08, 0x00, 0x41, 0x41, 0x41, 0x41,
1150  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
1151  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
1152  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
1153  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
1154  0x41, 0x41, 0x41, 0x41, 0x00, 0x00, 0x00, 0x00,
1155  0x00, 0x00, 0x00, 0x00,
1156  };
1157 
1158  uint32_t dcerpc_request1_len = sizeof(dcerpc_request1);
1159  uint32_t dcerpc_response1_len = sizeof(dcerpc_response1);
1160 
1161  uint32_t dcerpc_request2_len = sizeof(dcerpc_request2);
1162  uint32_t dcerpc_response2_len = sizeof(dcerpc_response2);
1163 
1165 
1166  memset(&th_v, 0, sizeof(th_v));
1167  memset(&f, 0, sizeof(f));
1168  memset(&ssn, 0, sizeof(ssn));
1169 
1170  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1171 
1172  FLOW_INITIALIZE(&f);
1173  f.protoctx = (void *)&ssn;
1174  f.proto = IPPROTO_TCP;
1175  p->flow = &f;
1179  f.alproto = ALPROTO_DCERPC;
1180 
1181  StreamTcpInitConfig(true);
1182 
1184  if (de_ctx == NULL)
1185  goto end;
1186 
1187  de_ctx->flags |= DE_QUIET;
1188 
1189  s = de_ctx->sig_list = SigInit(de_ctx,
1190  "alert tcp any any -> any any "
1191  "(msg:\"DCERPC\"; "
1192  "dce_opnum:30, 40; "
1193  "sid:1;)");
1194  if (s == NULL)
1195  goto end;
1196 
1198  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1199 
1200  /* request1 */
1201  r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, dcerpc_request1,
1202  dcerpc_request1_len);
1203  if (r != 0) {
1204  printf("AppLayerParse for dcerpc failed. Returned %" PRId32, r);
1205  goto end;
1206  }
1207 
1208  dcerpc_state = f.alstate;
1209  if (dcerpc_state == NULL) {
1210  printf("no dcerpc state: ");
1211  goto end;
1212  }
1213 
1214  if (dcerpc_state->dcerpc.dcerpcrequest.opnum != 40) {
1215  printf("dcerpc state holding invalid opnum after request1. Holding %d, while we are "
1216  "expecting 40\n", dcerpc_state->dcerpc.dcerpcrequest.opnum);
1217  goto end;
1218  }
1219 
1222  /* do detect */
1223  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1224 
1225  if (!PacketAlertCheck(p, 1))
1226  goto end;
1227 
1228  /* response1 */
1229  r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT, dcerpc_response1,
1230  dcerpc_response1_len);
1231  if (r != 0) {
1232  printf("AppLayerParse for dcerpc failed. Returned %" PRId32, r);
1233  goto end;
1234  }
1235 
1236  dcerpc_state = f.alstate;
1237  if (dcerpc_state == NULL) {
1238  printf("no dcerpc state: ");
1239  goto end;
1240  }
1241 
1242  if (dcerpc_state->dcerpc.dcerpcrequest.opnum != 40) {
1243  printf("dcerpc state holding invalid opnum after response1. Holding %d, while we are "
1244  "expecting 40\n", dcerpc_state->dcerpc.dcerpcrequest.opnum);
1245  goto end;
1246  }
1247 
1250  /* do detect */
1251  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1252 
1253  if (PacketAlertCheck(p, 1))
1254  goto end;
1255 
1256  /* request2 */
1257  printf("Sending Request2\n");
1258  r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, dcerpc_request2,
1259  dcerpc_request2_len);
1260  if (r != 0) {
1261  printf("AppLayerParse for dcerpc failed. Returned %" PRId32, r);
1262  goto end;
1263  }
1264 
1265  dcerpc_state = f.alstate;
1266  if (dcerpc_state == NULL) {
1267  printf("no dcerpc state: ");
1268  goto end;
1269  }
1270 
1271  if (dcerpc_state->dcerpc.dcerpcrequest.opnum != 30) {
1272  printf("dcerpc state holding invalid opnum after request2. Holding %d, while we are "
1273  "expecting 30\n", dcerpc_state->dcerpc.dcerpcrequest.opnum);
1274  goto end;
1275  }
1276 
1279  /* do detect */
1280  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1281 
1282  if (!PacketAlertCheck(p, 1))
1283  goto end;
1284 
1285  /* response2 */
1286  r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT | STREAM_EOF, dcerpc_response2,
1287  dcerpc_response2_len);
1288  if (r != 0) {
1289  printf("AppLayerParse for dcerpc failed. Returned %" PRId32, r);
1290  goto end;
1291  }
1292 
1293  dcerpc_state = f.alstate;
1294  if (dcerpc_state == NULL) {
1295  printf("no dcerpc state: ");
1296  goto end;
1297  }
1298 
1299  if (dcerpc_state->dcerpc.dcerpcrequest.opnum != 30) {
1300  printf("dcerpc state holding invalid opnum after response2. Holding %d, while we are "
1301  "expecting 30\n", dcerpc_state->dcerpc.dcerpcrequest.opnum);
1302  goto end;
1303  }
1304 
1307  /* do detect */
1308  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1309 
1310  if (PacketAlertCheck(p, 1))
1311  goto end;
1312 
1313  result = 1;
1314 
1315  end:
1316  if (alp_tctx != NULL)
1320 
1321  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1323 
1324  StreamTcpFreeConfig(true);
1325  FLOW_DESTROY(&f);
1326 
1327  UTHFreePackets(&p, 1);
1328  return result;
1329 }
1330 #endif
1331 
1332 static void DetectDceOpnumRegisterTests(void)
1333 {
1334  /* Disabled because of bug_753. Would be enabled, once we rewrite
1335  * dce parser */
1336 #if 0
1337  UtRegisterTest("DetectDceOpnumTestParse10", DetectDceOpnumTestParse10, 1);
1338  UtRegisterTest("DetectDceOpnumTestParse11", DetectDceOpnumTestParse11, 1);
1339  UtRegisterTest("DetectDceOpnumTestParse12", DetectDceOpnumTestParse12, 1);
1340  UtRegisterTest("DetectDceOpnumTestParse13", DetectDceOpnumTestParse13, 1);
1341 #endif
1342 }
1343 #endif /* UNITTESTS */
detect-engine.h
detect-dce-iface.h
PKT_HAS_FLOW
#define PKT_HAS_FLOW
Definition: decode.h:1175
ALPROTO_DCERPC
@ ALPROTO_DCERPC
Definition: app-layer-protos.h:38
SigTableElmt_::Free
void(* Free)(DetectEngineCtx *, void *)
Definition: detect.h:1257
flow-util.h
DetectParseRegex
Definition: detect-parse.h:42
SigTableElmt_::name
const char * name
Definition: detect.h:1267
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:552
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:298
Flow_::proto
uint8_t proto
Definition: flow.h:375
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:137
Packet_::flags
uint32_t flags
Definition: decode.h:462
Flow_
Flow data structure.
Definition: flow.h:353
SigInit
Signature * SigInit(DetectEngineCtx *, const char *)
Parses a signature and adds it to the Detection Engine Context.
Definition: detect-parse.c:2115
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:811
SC_ERR_INVALID_SIGNATURE
@ SC_ERR_INVALID_SIGNATURE
Definition: util-error.h:69
DetectEngineCtxFree
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
Definition: detect-engine.c:2433
SigTableElmt_::AppLayerTxMatch
int(* AppLayerTxMatch)(DetectEngineThreadCtx *, Flow *, uint8_t flags, void *alstate, void *txv, const Signature *, const SigMatchCtx *)
Definition: detect.h:1238
FLOW_PKT_TOSERVER
#define FLOW_PKT_TOSERVER
Definition: flow.h:225
rust.h
DE_QUIET
#define DE_QUIET
Definition: detect.h:295
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
SigMatchSignatures
void SigMatchSignatures(ThreadVars *tv, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
wrapper for old tests
Definition: detect.c:1790
SignatureInitData_::init_flags
uint32_t init_flags
Definition: detect.h:511
m
SCMutex m
Definition: flow-hash.h:6
SigCleanSignatures
void SigCleanSignatures(DetectEngineCtx *de_ctx)
Definition: detect-engine-build.c:42
Packet_::flowflags
uint8_t flowflags
Definition: decode.h:458
Flow_::protoctx
void * protoctx
Definition: flow.h:451
PARSE_REGEX
#define PARSE_REGEX
Definition: detect-dce-opnum.c:52
SigTableElmt_::Setup
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1252
util-unittest.h
util-unittest-helper.h
StreamTcpInitConfig
void StreamTcpInitConfig(bool)
To initialize the stream global configuration data.
Definition: stream-tcp.c:357
FLOW_INITIALIZE
#define FLOW_INITIALIZE(f)
Definition: flow-util.h:39
util-debug.h
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:17
DetectEngineThreadCtx_
Definition: detect.h:1060
alp_tctx
AppLayerParserThreadCtx * alp_tctx
Definition: fuzz_applayerparserparse.c:20
DetectSetupParseRegexes
void DetectSetupParseRegexes(const char *parse_str, DetectParseRegex *detect_parse)
Definition: detect-parse.c:2597
SCEnter
#define SCEnter(...)
Definition: util-debug.h:300
detect-engine-mpm.h
detect.h
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:58
SigMatch_::ctx
SigMatchCtx * ctx
Definition: detect.h:324
SigGroupCleanup
int SigGroupCleanup(DetectEngineCtx *de_ctx)
Definition: detect-engine-build.c:2016
SCReturn
#define SCReturn
Definition: util-debug.h:302
Packet_
Definition: decode.h:427
SIG_FLAG_INIT_DCERPC
#define SIG_FLAG_INIT_DCERPC
Definition: detect.h:266
Signature_::init_data
SignatureInitData * init_data
Definition: detect.h:619
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:226
SigMatchAlloc
SigMatch * SigMatchAlloc(void)
Definition: detect-parse.c:235
SigGroupBuild
int SigGroupBuild(DetectEngineCtx *de_ctx)
Convert the signature list into the runtime match structure.
Definition: detect-engine-build.c:1948
AppLayerParserThreadCtxAlloc
AppLayerParserThreadCtx * AppLayerParserThreadCtxAlloc(void)
Gets a new app layer protocol's parser thread context.
Definition: app-layer-parser.c:299
SigMatchCtx_
Used to start a pointer to SigMatch context Should never be dereferenced without casting to something...
Definition: detect.h:316
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:2420
Packet_::flow
struct Flow_ * flow
Definition: decode.h:464
DetectEngineThreadCtxInit
TmEcode DetectEngineThreadCtxInit(ThreadVars *, void *, void **)
initialize thread specific detection engine context
Definition: detect-engine.c:3142
DetectBufferTypeRegister
int DetectBufferTypeRegister(const char *name)
Definition: detect-engine.c:1023
StreamTcpFreeConfig
void StreamTcpFreeConfig(bool quiet)
Definition: stream-tcp.c:662
flags
uint8_t flags
Definition: decode-gre.h:0
SigTableElmt_::alias
const char * alias
Definition: detect.h:1268
DetectDceOpnumRegister
void DetectDceOpnumRegister(void)
Registers the keyword handlers for the "dce_opnum" keyword.
Definition: detect-dce-opnum.c:69
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:1237
suricata-common.h
DetectEngineThreadCtxDeinit
TmEcode DetectEngineThreadCtxDeinit(ThreadVars *, void *)
Definition: detect-engine.c:3354
SigMatch_::type
uint16_t type
Definition: detect.h:322
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:817
DETECT_DCE_OPNUM
@ DETECT_DCE_OPNUM
Definition: detect-engine-register.h:188
Flow_::alstate
void * alstate
Definition: flow.h:486
AppLayerDestroyCtxThread
void AppLayerDestroyCtxThread(AppLayerThreadCtx *app_tctx)
Destroys the context created by AppLayeGetCtxThread().
Definition: app-layer.c:945
detect-parse.h
Signature_
Signature container.
Definition: detect.h:548
SigMatch_
a single match condition for a signature
Definition: detect.h:321
ALPROTO_UNKNOWN
@ ALPROTO_UNKNOWN
Definition: app-layer-protos.h:29
FLOW_PKT_ESTABLISHED
#define FLOW_PKT_ESTABLISHED
Definition: flow.h:227
DetectEngineCtxInit
DetectEngineCtx * DetectEngineCtxInit(void)
Definition: detect-engine.c:2394
ALPROTO_SMB
@ ALPROTO_SMB
Definition: app-layer-protos.h:37
DetectEngineCtx_::flags
uint8_t flags
Definition: detect.h:812
AppLayerParserThreadCtx_
Definition: app-layer-parser.c:86
TcpSession_
Definition: stream-tcp-private.h:260
flow.h
Flow_::alproto
AppProto alproto
application level protocol
Definition: flow.h:460
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
detect-dce-opnum.h
PKT_STREAM_EST
#define PKT_STREAM_EST
Definition: decode.h:1172
SigTableElmt_::RegisterTests
void(* RegisterTests)(void)
Definition: detect.h:1259
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