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