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