suricata
detect-dns-query.c
Go to the documentation of this file.
1 /* Copyright (C) 2013-2023 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  * \ingroup dnslayer
20  *
21  * @{
22  */
23 
24 
25 /**
26  * \file
27  *
28  * \author Victor Julien <victor@inliniac.net>
29  */
30 
31 #include "suricata-common.h"
32 #include "threads.h"
33 #include "decode.h"
34 #include "detect.h"
35 
36 #include "detect-parse.h"
37 #include "detect-engine.h"
38 #include "detect-engine-build.h"
39 #include "detect-engine-mpm.h"
42 #include "detect-content.h"
43 #include "detect-pcre.h"
44 
45 #include "flow.h"
46 #include "flow-util.h"
47 #include "flow-var.h"
48 
49 #include "util-debug.h"
50 #include "util-unittest.h"
51 #include "util-spm.h"
52 #include "util-print.h"
53 
54 #include "stream-tcp.h"
55 
56 #include "app-layer.h"
57 #include "app-layer-parser.h"
58 #include "detect-dns-query.h"
59 
60 #include "util-profiling.h"
61 #include "util-unittest-helper.h"
62 #include "rust.h"
63 
64 static int DetectDnsQuerySetup (DetectEngineCtx *, Signature *, const char *);
65 #ifdef UNITTESTS
66 static void DetectDnsQueryRegisterTests(void);
67 #endif
68 static int g_dns_query_buffer_id = 0;
69 
70 static InspectionBuffer *DnsQueryGetData(DetectEngineThreadCtx *det_ctx,
71  const DetectEngineTransforms *transforms, Flow *f, const uint8_t flags, void *txv,
72  int list_id, uint32_t local_id)
73 {
74  SCEnter();
75 
76  InspectionBuffer *buffer = InspectionBufferMultipleForListGet(det_ctx, list_id, local_id);
77  if (buffer == NULL)
78  return NULL;
79  if (buffer->initialized)
80  return buffer;
81 
82  const uint8_t *data;
83  uint32_t data_len;
84  if (SCDnsTxGetQueryName(txv, false, local_id, &data, &data_len) == 0) {
86  return NULL;
87  }
88  InspectionBufferSetupMulti(buffer, transforms, data, data_len);
89  buffer->flags = DETECT_CI_FLAGS_SINGLE;
90 
91  SCReturnPtr(buffer, "InspectionBuffer");
92 }
93 
94 /**
95  * \brief Registration function for keyword: dns_query
96  */
98 {
101  sigmatch_table[DETECT_AL_DNS_QUERY].desc = "sticky buffer to match DNS query-buffer";
102  sigmatch_table[DETECT_AL_DNS_QUERY].url = "/rules/dns-keywords.html#dns-query";
103  sigmatch_table[DETECT_AL_DNS_QUERY].Setup = DetectDnsQuerySetup;
104 #ifdef UNITTESTS
105  sigmatch_table[DETECT_AL_DNS_QUERY].RegisterTests = DetectDnsQueryRegisterTests;
106 #endif
109 
111  "dns_query", ALPROTO_DNS, SIG_FLAG_TOSERVER, 1, DnsQueryGetData, 2, 1);
112 
114  "dns request query");
116 
117  g_dns_query_buffer_id = DetectBufferTypeGetByName("dns_query");
118 
119  /* register these generic engines from here for now */
124 
126  "dns requests");
127  DetectBufferTypeSetDescriptionByName("dns_response", "dns responses");
128 }
129 
130 
131 /**
132  * \brief setup the dns_query sticky buffer keyword used in the rule
133  *
134  * \param de_ctx Pointer to the Detection Engine Context
135  * \param s Pointer to the Signature to which the current keyword belongs
136  * \param str Should hold an empty string always
137  *
138  * \retval 0 On success
139  * \retval -1 On failure
140  */
141 
142 static int DetectDnsQuerySetup(DetectEngineCtx *de_ctx, Signature *s, const char *str)
143 {
144  if (DetectBufferSetActiveList(de_ctx, s, g_dns_query_buffer_id) < 0)
145  return -1;
147  return -1;
148  return 0;
149 }
150 
151 #ifdef UNITTESTS
152 #include "detect-isdataat.h"
153 #include "detect-engine-alert.h"
154 
155 /** \test simple google.com query matching */
156 static int DetectDnsQueryTest01(void)
157 {
158  /* google.com */
159  uint8_t buf[] = { 0x10, 0x32, 0x01, 0x00, 0x00, 0x01,
160  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
161  0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C,
162  0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00,
163  0x00, 0x10, 0x00, 0x01, };
164  Flow f;
165  void *dns_state = NULL;
166  Packet *p = NULL;
167  Signature *s = NULL;
168  ThreadVars tv;
169  DetectEngineThreadCtx *det_ctx = NULL;
171 
172  memset(&tv, 0, sizeof(ThreadVars));
173  memset(&f, 0, sizeof(Flow));
174 
175  p = UTHBuildPacketReal(buf, sizeof(buf), IPPROTO_UDP,
176  "192.168.1.5", "192.168.1.1",
177  41424, 53);
178 
179  FLOW_INITIALIZE(&f);
180  f.flags |= FLOW_IPV4;
181  f.proto = IPPROTO_UDP;
183 
184  p->flow = &f;
185  p->flags |= PKT_HAS_FLOW;
187  f.alproto = ALPROTO_DNS;
188 
192  de_ctx->flags |= DE_QUIET;
193 
194  s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any "
195  "(msg:\"Test dns_query option\"; "
196  "dns_query; content:\"google\"; nocase; sid:1;)");
197  FAIL_IF_NULL(s);
198 
200  DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
201 
202  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS,
203  STREAM_TOSERVER, buf, sizeof(buf));
204  if (r != 0) {
205  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
206  FAIL;
207  }
208 
209  dns_state = f.alstate;
210  FAIL_IF_NULL(dns_state);
211 
212  /* do detect */
213  SigMatchSignatures(&tv, de_ctx, det_ctx, p);
214 
215  if (!(PacketAlertCheck(p, 1))) {
216  printf("sig 1 didn't alert, but it should have: ");
217  FAIL;
218  }
219 
220  if (alp_tctx != NULL)
222  if (det_ctx != NULL)
223  DetectEngineThreadCtxDeinit(&tv, det_ctx);
224  if (de_ctx != NULL)
226  if (de_ctx != NULL)
228 
229  FLOW_DESTROY(&f);
230  UTHFreePacket(p);
231  PASS;
232 }
233 
234 /** \test multi tx google.(com|net) query matching */
235 static int DetectDnsQueryTest02(void)
236 {
237  /* google.com */
238  uint8_t buf1[] = { 0x10, 0x32, 0x01, 0x00, 0x00, 0x01,
239  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
240  0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C,
241  0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00,
242  0x00, 0x01, 0x00, 0x01, };
243 
244  uint8_t buf2[] = { 0x10, 0x32, /* tx id */
245  0x81, 0x80, /* flags: resp, recursion desired, recursion available */
246  0x00, 0x01, /* 1 query */
247  0x00, 0x01, /* 1 answer */
248  0x00, 0x00, 0x00, 0x00, /* no auth rr, additional rr */
249  /* query record */
250  0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C, /* name */
251  0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00, /* name cont */
252  0x00, 0x01, 0x00, 0x01, /* type a, class in */
253  /* answer */
254  0xc0, 0x0c, /* ref to name in query above */
255  0x00, 0x01, 0x00, 0x01, /* type a, class in */
256  0x00, 0x01, 0x40, 0xef, /* ttl */
257  0x00, 0x04, /* data len */
258  0x01, 0x02, 0x03, 0x04 }; /* addr */
259 
260  /* google.net */
261  uint8_t buf3[] = { 0x11, 0x33, 0x01, 0x00, 0x00, 0x01,
262  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
263  0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C,
264  0x65, 0x03, 0x6E, 0x65, 0x74, 0x00,
265  0x00, 0x10, 0x00, 0x01, };
266  Flow f;
267  void *dns_state = NULL;
268  Packet *p1 = NULL, *p2 = NULL, *p3 = NULL;
269  Signature *s = NULL;
270  ThreadVars tv;
271  DetectEngineThreadCtx *det_ctx = NULL;
273 
274  memset(&tv, 0, sizeof(ThreadVars));
275  memset(&f, 0, sizeof(Flow));
276 
277  p1 = UTHBuildPacketReal(buf1, sizeof(buf1), IPPROTO_UDP,
278  "192.168.1.5", "192.168.1.1",
279  41424, 53);
280  p2 = UTHBuildPacketReal(buf1, sizeof(buf1), IPPROTO_UDP,
281  "192.168.1.5", "192.168.1.1",
282  41424, 53);
283  p3 = UTHBuildPacketReal(buf1, sizeof(buf1), IPPROTO_UDP,
284  "192.168.1.5", "192.168.1.1",
285  41424, 53);
286 
287  FLOW_INITIALIZE(&f);
288  f.flags |= FLOW_IPV4;
289  f.proto = IPPROTO_UDP;
291  f.alproto = ALPROTO_DNS;
292 
293  p1->flow = &f;
294  p1->flags |= PKT_HAS_FLOW;
296  p1->pcap_cnt = 1;
297 
298  p2->flow = &f;
299  p2->flags |= PKT_HAS_FLOW;
300  p2->flowflags |= FLOW_PKT_TOCLIENT;
301  p2->pcap_cnt = 2;
302 
303  p3->flow = &f;
304  p3->flags |= PKT_HAS_FLOW;
305  p3->flowflags |= FLOW_PKT_TOSERVER;
306  p3->pcap_cnt = 3;
307 
311  de_ctx->flags |= DE_QUIET;
312 
313  s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any "
314  "(msg:\"Test dns_query option\"; "
315  "dns_query; content:\"google.com\"; nocase; sid:1;)");
316  FAIL_IF_NULL(s);
317  s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any "
318  "(msg:\"Test dns_query option\"; "
319  "dns_query; content:\"google.net\"; nocase; sid:2;)");
320  FAIL_IF_NULL(s);
321 
323  DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
324 
325  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS,
326  STREAM_TOSERVER, buf1, sizeof(buf1));
327  if (r != 0) {
328  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
329  FAIL;
330  }
331 
332  dns_state = f.alstate;
333  FAIL_IF_NULL(dns_state);
334 
335  /* do detect */
336  SigMatchSignatures(&tv, de_ctx, det_ctx, p1);
337 
338  if (!(PacketAlertCheck(p1, 1))) {
339  printf("(p1) sig 1 didn't alert, but it should have: ");
340  FAIL;
341  }
342  if (PacketAlertCheck(p1, 2)) {
343  printf("(p1) sig 2 did alert, but it should not have: ");
344  FAIL;
345  }
346 
347  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS, STREAM_TOCLIENT,
348  buf2, sizeof(buf2));
349  if (r != 0) {
350  printf("toserver client 1 returned %" PRId32 ", expected 0: ", r);
351  FAIL;
352  }
353 
354  /* do detect */
355  SigMatchSignatures(&tv, de_ctx, det_ctx, p2);
356 
357  if (PacketAlertCheck(p2, 1)) {
358  printf("(p2) sig 1 alerted, but it should not have: ");
359  FAIL;
360  }
361  if (PacketAlertCheck(p2, 2)) {
362  printf("(p2) sig 2 alerted, but it should not have: ");
363  FAIL;
364  }
365 
366  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS, STREAM_TOSERVER,
367  buf3, sizeof(buf3));
368  if (r != 0) {
369  printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r);
370  FAIL;
371  }
372 
373  /* do detect */
374  SigMatchSignatures(&tv, de_ctx, det_ctx, p3);
375 
376  if (PacketAlertCheck(p3, 1)) {
377  printf("(p3) sig 1 alerted, but it should not have: ");
378  FAIL;
379  }
380  if (!(PacketAlertCheck(p3, 2))) {
381  printf("(p3) sig 2 didn't alert, but it should have: ");
382  FAIL;
383  }
384 
385  if (alp_tctx != NULL)
387  if (det_ctx != NULL)
388  DetectEngineThreadCtxDeinit(&tv, det_ctx);
389  if (de_ctx != NULL)
391  if (de_ctx != NULL)
393 
394  FLOW_DESTROY(&f);
395  UTHFreePacket(p1);
396  UTHFreePacket(p2);
397  UTHFreePacket(p3);
398  PASS;
399 }
400 
401 /** \test simple google.com query matching (TCP) */
402 static int DetectDnsQueryTest03(void)
403 {
404  /* google.com */
405  uint8_t buf[] = { 0x00, 28,
406  0x10, 0x32, 0x01, 0x00, 0x00, 0x01,
407  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
408  0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C,
409  0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00,
410  0x00, 0x10, 0x00, 0x01, };
411  Flow f;
412  void *dns_state = NULL;
413  Packet *p = NULL;
414  Signature *s = NULL;
415  ThreadVars tv;
416  DetectEngineThreadCtx *det_ctx = NULL;
417  TcpSession ssn;
419 
420  memset(&tv, 0, sizeof(ThreadVars));
421  memset(&f, 0, sizeof(Flow));
422  memset(&ssn, 0, sizeof(TcpSession));
423 
424  p = UTHBuildPacketReal(buf, sizeof(buf), IPPROTO_TCP,
425  "192.168.1.5", "192.168.1.1",
426  41424, 53);
427 
428  FLOW_INITIALIZE(&f);
429  f.protoctx = (void *)&ssn;
430  f.flags |= FLOW_IPV4;
431  f.proto = IPPROTO_TCP;
433 
434  p->flow = &f;
437  f.alproto = ALPROTO_DNS;
438 
439  StreamTcpInitConfig(true);
440 
444  de_ctx->flags |= DE_QUIET;
445 
446  s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any "
447  "(msg:\"Test dns_query option\"; "
448  "dns_query; content:\"google\"; nocase; sid:1;)");
449  FAIL_IF_NULL(s);
450 
452  DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
453 
454  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS,
455  STREAM_TOSERVER, buf, sizeof(buf));
456  if (r != 0) {
457  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
458  FAIL;
459  }
460 
461  dns_state = f.alstate;
462  FAIL_IF_NULL(dns_state);
463 
464  /* do detect */
465  SigMatchSignatures(&tv, de_ctx, det_ctx, p);
466 
467  if (!(PacketAlertCheck(p, 1))) {
468  printf("sig 1 didn't alert, but it should have: ");
469  FAIL;
470  }
471 
472  if (alp_tctx != NULL)
474  if (det_ctx != NULL)
475  DetectEngineThreadCtxDeinit(&tv, det_ctx);
476  if (de_ctx != NULL)
478  if (de_ctx != NULL)
480 
481  StreamTcpFreeConfig(true);
482  FLOW_DESTROY(&f);
483  UTHFreePacket(p);
484  PASS;
485 }
486 
487 
488 /** \test simple google.com query matching, pcre */
489 static int DetectDnsQueryTest04(void)
490 {
491  /* google.com */
492  uint8_t buf[] = { 0x10, 0x32, 0x01, 0x00, 0x00, 0x01,
493  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
494  0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C,
495  0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00,
496  0x00, 0x10, 0x00, 0x01, };
497  Flow f;
498  void *dns_state = NULL;
499  Packet *p = NULL;
500  Signature *s = NULL;
501  ThreadVars tv;
502  DetectEngineThreadCtx *det_ctx = NULL;
504 
505  memset(&tv, 0, sizeof(ThreadVars));
506  memset(&f, 0, sizeof(Flow));
507 
508  p = UTHBuildPacketReal(buf, sizeof(buf), IPPROTO_UDP,
509  "192.168.1.5", "192.168.1.1",
510  41424, 53);
511 
512  FLOW_INITIALIZE(&f);
513  f.flags |= FLOW_IPV4;
514  f.proto = IPPROTO_UDP;
516 
517  p->flow = &f;
518  p->flags |= PKT_HAS_FLOW;
520  f.alproto = ALPROTO_DNS;
521 
525  de_ctx->flags |= DE_QUIET;
526 
527  s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any "
528  "(msg:\"Test dns_query option\"; "
529  "dns_query; content:\"google\"; nocase; "
530  "pcre:\"/google\\.com$/i\"; sid:1;)");
531  FAIL_IF_NULL(s);
532  s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any "
533  "(msg:\"Test dns_query option\"; "
534  "dns_query; content:\"google\"; nocase; "
535  "pcre:\"/^\\.[a-z]{2,3}$/iR\"; sid:2;)");
536  FAIL_IF_NULL(s);
537 
539  DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
540 
541  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS,
542  STREAM_TOSERVER, buf, sizeof(buf));
543  if (r != 0) {
544  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
545  FAIL;
546  }
547 
548  dns_state = f.alstate;
549  FAIL_IF_NULL(dns_state);
550 
551  /* do detect */
552  SigMatchSignatures(&tv, de_ctx, det_ctx, p);
553 
554  if (!(PacketAlertCheck(p, 1))) {
555  printf("sig 1 didn't alert, but it should have: ");
556  FAIL;
557  }
558  if (!(PacketAlertCheck(p, 2))) {
559  printf("sig 2 didn't alert, but it should have: ");
560  FAIL;
561  }
562 
563  if (alp_tctx != NULL)
565  if (det_ctx != NULL)
566  DetectEngineThreadCtxDeinit(&tv, det_ctx);
567  if (de_ctx != NULL)
569  if (de_ctx != NULL)
571 
572  FLOW_DESTROY(&f);
573  UTHFreePacket(p);
574  PASS;
575 }
576 
577 /** \test multi tx google.(com|net) query matching +
578  * app layer event */
579 static int DetectDnsQueryTest05(void)
580 {
581  /* google.com */
582  uint8_t buf1[] = { 0x10, 0x32, 0x01, 0x00, 0x00, 0x01,
583  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
584  0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C,
585  0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00,
586  0x00, 0x01, 0x00, 0x01, };
587 
588  uint8_t buf2[] = { 0x10, 0x32, /* tx id */
589  0x81, 0x80|0x40, /* flags: resp, recursion desired, recursion available */
590  0x00, 0x01, /* 1 query */
591  0x00, 0x01, /* 1 answer */
592  0x00, 0x00, 0x00, 0x00, /* no auth rr, additional rr */
593  /* query record */
594  0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C, /* name */
595  0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00, /* name cont */
596  0x00, 0x01, 0x00, 0x01, /* type a, class in */
597  /* answer */
598  0xc0, 0x0c, /* ref to name in query above */
599  0x00, 0x01, 0x00, 0x01, /* type a, class in */
600  0x00, 0x01, 0x40, 0xef, /* ttl */
601  0x00, 0x04, /* data len */
602  0x01, 0x02, 0x03, 0x04 }; /* addr */
603 
604  /* google.net */
605  uint8_t buf3[] = { 0x11, 0x33, 0x01, 0x00, 0x00, 0x01,
606  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
607  0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C,
608  0x65, 0x03, 0x6E, 0x65, 0x74, 0x00,
609  0x00, 0x10, 0x00, 0x01, };
610  Flow f;
611  void *dns_state = NULL;
612  Packet *p1 = NULL, *p2 = NULL, *p3 = NULL;
613  Signature *s = NULL;
614  ThreadVars tv;
615  DetectEngineThreadCtx *det_ctx = NULL;
617 
618  memset(&tv, 0, sizeof(ThreadVars));
619  memset(&f, 0, sizeof(Flow));
620 
621  p1 = UTHBuildPacketReal(buf1, sizeof(buf1), IPPROTO_UDP,
622  "192.168.1.5", "192.168.1.1",
623  41424, 53);
624  p2 = UTHBuildPacketReal(buf2, sizeof(buf2), IPPROTO_UDP,
625  "192.168.1.5", "192.168.1.1",
626  41424, 53);
627  p3 = UTHBuildPacketReal(buf3, sizeof(buf3), IPPROTO_UDP,
628  "192.168.1.5", "192.168.1.1",
629  41424, 53);
630 
631  FLOW_INITIALIZE(&f);
632  f.flags |= FLOW_IPV4;
633  f.proto = IPPROTO_UDP;
635  f.alproto = ALPROTO_DNS;
636 
637  p1->flow = &f;
638  p1->flags |= PKT_HAS_FLOW;
640  p1->pcap_cnt = 1;
641 
642  p2->flow = &f;
643  p2->flags |= PKT_HAS_FLOW;
644  p2->flowflags |= FLOW_PKT_TOCLIENT;
645  p2->pcap_cnt = 2;
646 
647  p3->flow = &f;
648  p3->flags |= PKT_HAS_FLOW;
649  p3->flowflags |= FLOW_PKT_TOSERVER;
650  p3->pcap_cnt = 3;
651 
655  de_ctx->flags |= DE_QUIET;
656 
657  s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any "
658  "(msg:\"Test dns_query option\"; "
659  "dns_query; content:\"google.com\"; nocase; sid:1;)");
660  FAIL_IF_NULL(s);
661  s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any "
662  "(msg:\"Test dns_query option\"; "
663  "dns_query; content:\"google.net\"; nocase; sid:2;)");
664  FAIL_IF_NULL(s);
665  s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any "
666  "(msg:\"Test Z flag event\"; "
667  "app-layer-event:dns.z_flag_set; sid:3;)");
668  FAIL_IF_NULL(s);
669 
671  DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
672 
673  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS,
674  STREAM_TOSERVER, buf1, sizeof(buf1));
675  if (r != 0) {
676  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
677  FAIL;
678  }
679 
680  dns_state = f.alstate;
681  FAIL_IF_NULL(dns_state);
682 
683  /* do detect */
684  SigMatchSignatures(&tv, de_ctx, det_ctx, p1);
685 
686  if (!(PacketAlertCheck(p1, 1))) {
687  printf("(p1) sig 1 didn't alert, but it should have: ");
688  FAIL;
689  }
690  if (PacketAlertCheck(p1, 2)) {
691  printf("(p1) sig 2 did alert, but it should not have: ");
692  FAIL;
693  }
694 
695  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS, STREAM_TOCLIENT,
696  buf2, sizeof(buf2));
697  if (r != 0) {
698  printf("toserver client 1 returned %" PRId32 ", expected 0\n", r);
699  FAIL;
700  }
701 
702  /* do detect */
703  SigMatchSignatures(&tv, de_ctx, det_ctx, p2);
704 
705  if (PacketAlertCheck(p2, 1)) {
706  printf("(p2) sig 1 alerted, but it should not have: ");
707  FAIL;
708  }
709  if (PacketAlertCheck(p2, 2)) {
710  printf("(p2) sig 2 alerted, but it should not have: ");
711  FAIL;
712  }
713  if (!(PacketAlertCheck(p2, 3))) {
714  printf("(p2) sig 3 didn't alert, but it should have: ");
715  FAIL;
716  }
717 
718  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DNS, STREAM_TOSERVER,
719  buf3, sizeof(buf3));
720  if (r != 0) {
721  printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r);
722  FAIL;
723  }
724 
725  /* do detect */
726  SigMatchSignatures(&tv, de_ctx, det_ctx, p3);
727 
728  if (PacketAlertCheck(p3, 1)) {
729  printf("(p3) sig 1 alerted, but it should not have: ");
730  FAIL;
731  }
732  if (!(PacketAlertCheck(p3, 2))) {
733  printf("(p3) sig 2 didn't alert, but it should have: ");
734  FAIL;
735  }
736  /** \todo should not alert, bug #839
737  if (PacketAlertCheck(p3, 3)) {
738  printf("(p3) sig 3 did alert, but it should not have: ");
739  goto end;
740  }
741  */
742 
743  if (alp_tctx != NULL)
745  if (det_ctx != NULL)
746  DetectEngineThreadCtxDeinit(&tv, det_ctx);
747  if (de_ctx != NULL)
749  if (de_ctx != NULL)
751 
752  FLOW_DESTROY(&f);
753  UTHFreePacket(p1);
754  UTHFreePacket(p2);
755  UTHFreePacket(p3);
756  PASS;
757 }
758 
759 static void DetectDnsQueryRegisterTests(void)
760 {
761  UtRegisterTest("DetectDnsQueryTest01", DetectDnsQueryTest01);
762  UtRegisterTest("DetectDnsQueryTest02", DetectDnsQueryTest02);
763  UtRegisterTest("DetectDnsQueryTest03 -- tcp", DetectDnsQueryTest03);
764  UtRegisterTest("DetectDnsQueryTest04 -- pcre", DetectDnsQueryTest04);
765  UtRegisterTest("DetectDnsQueryTest05 -- app layer event", DetectDnsQueryTest05);
766 }
767 #endif
SigTableElmt_::url
const char * url
Definition: detect.h:1307
DetectSignatureSetAppProto
int DetectSignatureSetAppProto(Signature *s, AppProto alproto)
Definition: detect-parse.c:1737
detect-content.h
detect-engine.h
FAIL_IF_NULL
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
Definition: util-unittest.h:89
SIGMATCH_INFO_STICKY_BUFFER
#define SIGMATCH_INFO_STICKY_BUFFER
Definition: detect.h:1512
SigTableElmt_::desc
const char * desc
Definition: detect.h:1306
sigmatch_table
SigTableElmt * sigmatch_table
Definition: detect-parse.c:127
PKT_HAS_FLOW
#define PKT_HAS_FLOW
Definition: decode.h:1264
flow-util.h
ALPROTO_DNS
@ ALPROTO_DNS
Definition: app-layer-protos.h:41
SigTableElmt_::name
const char * name
Definition: detect.h:1304
InspectionBuffer::initialized
bool initialized
Definition: detect.h:377
stream-tcp.h
DetectEngineTransforms
Definition: detect.h:408
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:103
Packet_::pcap_cnt
uint64_t pcap_cnt
Definition: decode.h:592
detect-isdataat.h
Flow_::proto
uint8_t proto
Definition: flow.h:378
DetectBufferSetActiveList
int DetectBufferSetActiveList(DetectEngineCtx *de_ctx, Signature *s, const int list)
Definition: detect-engine.c:1356
PacketAlertCheck
int PacketAlertCheck(Packet *p, uint32_t sid)
Check if a certain sid alerted, this is used in the test functions.
Definition: detect-engine-alert.c:141
InspectionBuffer
Definition: detect.h:373
Packet_::flags
uint32_t flags
Definition: decode.h:510
threads.h
Flow_
Flow data structure.
Definition: flow.h:356
Flow_::protomap
uint8_t protomap
Definition: flow.h:450
SigTableElmt_::flags
uint16_t flags
Definition: detect.h:1298
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:841
DetectBufferTypeSupportsMultiInstance
void DetectBufferTypeSupportsMultiInstance(const char *name)
Definition: detect-engine.c:1043
DetectEngineCtxFree
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
Definition: detect-engine.c:2611
AppLayerParserThreadCtxFree
void AppLayerParserThreadCtxFree(AppLayerParserThreadCtx *tctx)
Destroys the app layer parser thread context obtained using AppLayerParserThreadCtxAlloc().
Definition: app-layer-parser.c:300
FLOW_PKT_TOSERVER
#define FLOW_PKT_TOSERVER
Definition: flow.h:232
rust.h
DE_QUIET
#define DE_QUIET
Definition: detect.h:323
mpm_default_matcher
uint8_t mpm_default_matcher
Definition: util-mpm.c:48
InspectionBuffer::flags
uint8_t flags
Definition: detect.h:378
SigMatchSignatures
void SigMatchSignatures(ThreadVars *tv, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
wrapper for old tests
Definition: detect.c:1938
DetectEngineAppendSig
Signature * DetectEngineAppendSig(DetectEngineCtx *, const char *)
Parse and append a Signature into the Detection Engine Context signature list.
Definition: detect-parse.c:2587
Packet_::flowflags
uint8_t flowflags
Definition: decode.h:504
SIG_FLAG_TOCLIENT
#define SIG_FLAG_TOCLIENT
Definition: detect.h:268
UTHBuildPacketReal
Packet * UTHBuildPacketReal(uint8_t *payload, uint16_t payload_len, uint8_t ipproto, const char *src, const char *dst, uint16_t sport, uint16_t dport)
UTHBuildPacketReal is a function that create tcp/udp packets for unittests specifying ip and port sou...
Definition: util-unittest-helper.c:260
Flow_::protoctx
void * protoctx
Definition: flow.h:446
SigTableElmt_::Setup
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1289
detect-pcre.h
FLOW_IPV4
#define FLOW_IPV4
Definition: flow.h:99
detect-engine-prefilter.h
util-unittest.h
util-unittest-helper.h
DetectBufferTypeGetByName
int DetectBufferTypeGetByName(const char *name)
Definition: detect-engine.c:1093
DetectAppLayerMultiRegister
void DetectAppLayerMultiRegister(const char *name, AppProto alproto, uint32_t dir, int progress, InspectionMultiBufferGetDataPtr GetData, int priority, int tx_min_progress)
Definition: detect-engine.c:2201
detect-dns-query.h
StreamTcpInitConfig
void StreamTcpInitConfig(bool)
To initialize the stream global configuration data.
Definition: stream-tcp.c:461
FLOW_INITIALIZE
#define FLOW_INITIALIZE(f)
Definition: flow-util.h:38
SIG_FLAG_TOSERVER
#define SIG_FLAG_TOSERVER
Definition: detect.h:267
InspectionBufferSetupMultiEmpty
void InspectionBufferSetupMultiEmpty(InspectionBuffer *buffer)
setup the buffer empty
Definition: detect-engine.c:1567
decode.h
util-debug.h
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:17
DetectEngineThreadCtx_
Definition: detect.h:1093
alp_tctx
AppLayerParserThreadCtx * alp_tctx
Definition: fuzz_applayerparserparse.c:22
util-print.h
SCEnter
#define SCEnter(...)
Definition: util-debug.h:271
detect-engine-mpm.h
detect.h
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:58
DetectEngineThreadCtxInit
TmEcode DetectEngineThreadCtxInit(ThreadVars *tv, void *initdata, void **data)
initialize thread specific detection engine context
Definition: detect-engine.c:3347
DetectEngineCtx_::mpm_matcher
uint8_t mpm_matcher
Definition: detect.h:844
app-layer-parser.h
SigGroupCleanup
int SigGroupCleanup(DetectEngineCtx *de_ctx)
Definition: detect-engine-build.c:2211
util-profiling.h
FlowGetProtoMapping
uint8_t FlowGetProtoMapping(uint8_t proto)
Function to map the protocol to the defined FLOW_PROTO_* enumeration.
Definition: flow-util.c:98
Packet_
Definition: decode.h:473
detect-engine-build.h
detect-engine-alert.h
SCReturnPtr
#define SCReturnPtr(x, type)
Definition: util-debug.h:287
FLOW_PKT_TOCLIENT
#define FLOW_PKT_TOCLIENT
Definition: flow.h:233
SigGroupBuild
int SigGroupBuild(DetectEngineCtx *de_ctx)
Convert the signature list into the runtime match structure.
Definition: detect-engine-build.c:2144
AppLayerParserThreadCtxAlloc
AppLayerParserThreadCtx * AppLayerParserThreadCtxAlloc(void)
Gets a new app layer protocol's parser thread context.
Definition: app-layer-parser.c:279
detect-engine-content-inspection.h
Packet_::flow
struct Flow_ * flow
Definition: decode.h:512
DETECT_CI_FLAGS_SINGLE
#define DETECT_CI_FLAGS_SINGLE
Definition: detect-engine-content-inspection.h:49
StreamTcpFreeConfig
void StreamTcpFreeConfig(bool quiet)
Definition: stream-tcp.c:792
flags
uint8_t flags
Definition: decode-gre.h:0
SigTableElmt_::alias
const char * alias
Definition: detect.h:1305
AppLayerParserParse
int AppLayerParserParse(ThreadVars *tv, AppLayerParserThreadCtx *alp_tctx, Flow *f, AppProto alproto, uint8_t flags, const uint8_t *input, uint32_t input_len)
Definition: app-layer-parser.c:1265
suricata-common.h
DetectEngineThreadCtxDeinit
TmEcode DetectEngineThreadCtxDeinit(ThreadVars *tv, void *data)
Definition: detect-engine.c:3574
util-spm.h
InspectionBufferSetupMulti
void InspectionBufferSetupMulti(InspectionBuffer *buffer, const DetectEngineTransforms *transforms, const uint8_t *data, const uint32_t data_len)
setup the buffer with our initial data
Definition: detect-engine.c:1580
DetectEngineInspectGenericList
uint8_t DetectEngineInspectGenericList(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, const struct DetectEngineAppInspectionEngine_ *engine, const Signature *s, Flow *f, uint8_t flags, void *alstate, void *txv, uint64_t tx_id)
Do the content inspection & validation for a signature.
Definition: detect-engine.c:2111
DetectDnsQueryRegister
void DetectDnsQueryRegister(void)
Registration function for keyword: dns_query.
Definition: detect-dns-query.c:97
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:32
str
#define str(s)
Definition: suricata-common.h:291
UTHFreePacket
void UTHFreePacket(Packet *p)
UTHFreePacket: function to release the allocated data from UTHBuildPacket and the packet itself.
Definition: util-unittest-helper.c:467
Flow_::alstate
void * alstate
Definition: flow.h:481
Flow_::flags
uint32_t flags
Definition: flow.h:426
detect-parse.h
Signature_
Signature container.
Definition: detect.h:601
FAIL
#define FAIL
Fail a test.
Definition: util-unittest.h:60
FLOW_PKT_ESTABLISHED
#define FLOW_PKT_ESTABLISHED
Definition: flow.h:234
DetectEngineCtxInit
DetectEngineCtx * DetectEngineCtxInit(void)
Definition: detect-engine.c:2572
DETECT_AL_DNS_QUERY
@ DETECT_AL_DNS_QUERY
Definition: detect-engine-register.h:241
InspectionBufferMultipleForListGet
InspectionBuffer * InspectionBufferMultipleForListGet(DetectEngineThreadCtx *det_ctx, const int list_id, const uint32_t local_id)
for a InspectionBufferMultipleForList get a InspectionBuffer
Definition: detect-engine.c:1520
SIGMATCH_NOOPT
#define SIGMATCH_NOOPT
Definition: detect.h:1488
DetectAppLayerInspectEngineRegister
void DetectAppLayerInspectEngineRegister(const char *name, AppProto alproto, uint32_t dir, int progress, InspectEngineFuncPtr Callback, InspectionBufferGetDataPtr GetData)
Registers an app inspection engine.
Definition: detect-engine.c:240
DetectEngineCtx_::flags
uint8_t flags
Definition: detect.h:843
AppLayerParserThreadCtx_
Definition: app-layer-parser.c:58
DetectBufferTypeSetDescriptionByName
void DetectBufferTypeSetDescriptionByName(const char *name, const char *desc)
Definition: detect-engine.c:1190
TcpSession_
Definition: stream-tcp-private.h:283
flow.h
Flow_::alproto
AppProto alproto
application level protocol
Definition: flow.h:455
flow-var.h
FLOW_DESTROY
#define FLOW_DESTROY(f)
Definition: flow-util.h:121
PKT_STREAM_EST
#define PKT_STREAM_EST
Definition: decode.h:1261
SigTableElmt_::RegisterTests
void(* RegisterTests)(void)
Definition: detect.h:1296
app-layer.h