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