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