suricata
detect-bytetest.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2010 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 Brian Rectanus <brectanu@gmail.com>
22  *
23  * Implements byte_test keyword.
24  */
25 
26 #include "suricata-common.h"
27 #include "debug.h"
28 #include "decode.h"
29 #include "detect.h"
30 #include "detect-engine.h"
31 #include "detect-parse.h"
32 
33 #include "detect-content.h"
34 #include "detect-uricontent.h"
35 #include "detect-bytetest.h"
36 #include "detect-bytejump.h"
37 #include "detect-byte-extract.h"
38 #include "app-layer.h"
39 
40 #include "util-byte.h"
41 #include "util-unittest.h"
42 #include "util-debug.h"
43 #include "detect-pcre.h"
44 
45 
46 /**
47  * \brief Regex for parsing our options
48  */
49 /** \todo We probably just need a simple tokenizer here */
50 #define PARSE_REGEX "^\\s*" \
51  "([^\\s,]+)" \
52  "\\s*,\\s*(\\!?)\\s*([^\\s,]*)" \
53  "\\s*,\\s*([^\\s,]+)" \
54  "\\s*,\\s*([^\\s,]+)" \
55  "(?:\\s*,\\s*([^\\s,]+))?" \
56  "(?:\\s*,\\s*([^\\s,]+))?" \
57  "(?:\\s*,\\s*([^\\s,]+))?" \
58  "(?:\\s*,\\s*([^\\s,]+))?" \
59  "(?:\\s*,\\s*([^\\s,]+))?" \
60  "\\s*$"
61 
62 static pcre *parse_regex;
63 static pcre_extra *parse_regex_study;
64 
65 static int DetectBytetestMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx,
66  Packet *p, const Signature *s, const SigMatchCtx *ctx);
67 static int DetectBytetestSetup(DetectEngineCtx *de_ctx, Signature *s, const char *optstr);
68 static void DetectBytetestFree(void *ptr);
69 static void DetectBytetestRegisterTests(void);
70 
72 {
73  sigmatch_table[DETECT_BYTETEST].name = "byte_test";
74  sigmatch_table[DETECT_BYTETEST].Match = DetectBytetestMatch;
75  sigmatch_table[DETECT_BYTETEST].Setup = DetectBytetestSetup;
76  sigmatch_table[DETECT_BYTETEST].Free = DetectBytetestFree;
77  sigmatch_table[DETECT_BYTETEST].RegisterTests = DetectBytetestRegisterTests;
78 
79  DetectSetupParseRegexes(PARSE_REGEX, &parse_regex, &parse_regex_study);
80 }
81 
82 /** \brief Bytetest detection code
83  *
84  * Byte test works on the packet payload.
85  *
86  * \param det_ctx thread de ctx
87  * \param s signature
88  * \param m sigmatch for this bytettest
89  * \param payload ptr to the start of the buffer to inspect
90  * \param payload_len length of the payload
91  * \retval 1 match
92  * \retval 0 no match
93  */
95  const Signature *s, const SigMatchCtx *ctx,
96  uint8_t *payload, uint32_t payload_len,
97  uint8_t flags, int32_t offset, uint64_t value)
98 {
99  SCEnter();
100 
101  const DetectBytetestData *data = (const DetectBytetestData *)ctx;
102  uint8_t *ptr = NULL;
103  int32_t len = 0;
104  uint64_t val = 0;
105  int extbytes;
106  int neg;
107  int match;
108 
109  if (payload_len == 0) {
110  SCReturnInt(0);
111  }
112 
113  /* Calculate the ptr value for the bytetest and length remaining in
114  * the packet from that point.
115  */
116  if (flags & DETECT_BYTETEST_RELATIVE) {
117  SCLogDebug("relative, working with det_ctx->buffer_offset %"PRIu32", "
118  "data->offset %"PRIi32"", det_ctx->buffer_offset, data->offset);
119 
120  ptr = payload + det_ctx->buffer_offset;
121  len = payload_len - det_ctx->buffer_offset;
122 
123  ptr += offset;
124  len -= offset;
125 
126  /* No match if there is no relative base */
127  if (ptr == NULL || len <= 0) {
128  SCReturnInt(0);
129  }
130  //PrintRawDataFp(stdout,ptr,len);
131  }
132  else {
133  SCLogDebug("absolute, data->offset %"PRIi32"", data->offset);
134 
135  ptr = payload + offset;
136  len = payload_len - offset;
137  }
138 
139  /* Validate that the to-be-extracted is within the packet
140  * \todo Should this validate it is in the *payload*?
141  */
142  if (ptr < payload || data->nbytes > len) {
143  SCLogDebug("Data not within payload pkt=%p, ptr=%p, len=%"PRIu32", nbytes=%d",
144  payload, ptr, len, data->nbytes);
145  SCReturnInt(0);
146  }
147 
148  neg = flags & DETECT_BYTETEST_NEGOP;
149 
150  /* Extract the byte data */
151  if (flags & DETECT_BYTETEST_STRING) {
152  extbytes = ByteExtractStringUint64(&val, data->base,
153  data->nbytes, (const char *)ptr);
154  if (extbytes <= 0) {
155  /* strtoull() return 0 if there is no numeric value in data string */
156  if (val == 0) {
157  SCLogDebug("No Numeric value");
158  SCReturnInt(0);
159  } else {
160  SCLogDebug("error extracting %d "
161  "bytes of string data: %d", data->nbytes, extbytes);
162  SCReturnInt(-1);
163  }
164  }
165 
166  SCLogDebug("comparing base %d string 0x%" PRIx64 " %s%c 0x%" PRIx64 "",
167  data->base, val, (neg ? "!" : ""), data->op, data->value);
168  }
169  else {
170  int endianness = (flags & DETECT_BYTETEST_LITTLE) ?
172  extbytes = ByteExtractUint64(&val, endianness, data->nbytes, ptr);
173  if (extbytes != data->nbytes) {
174  SCLogDebug("error extracting %d bytes "
175  "of numeric data: %d", data->nbytes, extbytes);
176  SCReturnInt(-1);
177  }
178 
179  SCLogDebug("comparing numeric 0x%" PRIx64 " %s%c 0x%" PRIx64 "",
180  val, (neg ? "!" : ""), data->op, data->value);
181  }
182 
183  /* Compare using the configured operator */
184  match = 0;
185  switch (data->op) {
187  if (val == value) {
188  match = 1;
189  }
190  break;
192  if (val < value) {
193  match = 1;
194  }
195  break;
197  if (val > value) {
198  match = 1;
199  }
200  break;
202  if (val & value) {
203  match = 1;
204  }
205  break;
207  if (val ^ value) {
208  match = 1;
209  }
210  break;
212  if (val >= value) {
213  match = 1;
214  }
215  break;
217  if (val <= value) {
218  match = 1;
219  }
220  break;
221  default:
222  /* Should never get here as we handle this in parsing. */
223  SCReturnInt(-1);
224  }
225 
226  /* A successful match depends on negation */
227  if ((!neg && match) || (neg && !match)) {
228  SCLogDebug("MATCH");
229  SCReturnInt(1);
230  }
231 
232  SCLogDebug("NO MATCH");
233  SCReturnInt(0);
234 
235 }
236 
237 static int DetectBytetestMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx,
238  Packet *p, const Signature *s, const SigMatchCtx *ctx)
239 {
240  return DetectBytetestDoMatch(det_ctx, s, ctx, p->payload, p->payload_len,
241  ((DetectBytetestData *)ctx)->flags, 0, 0);
242 }
243 
244 static DetectBytetestData *DetectBytetestParse(const char *optstr, char **value, char **offset)
245 {
246  DetectBytetestData *data = NULL;
247  char *args[9] = {
248  NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
249  NULL
250  };
251 #define MAX_SUBSTRINGS 30
252  int ret = 0, res = 0;
253  int ov[MAX_SUBSTRINGS];
254  int i;
255  uint32_t nbytes;
256  const char *str_ptr = NULL;
257 
258  /* Execute the regex and populate args with captures. */
259  ret = pcre_exec(parse_regex, parse_regex_study, optstr,
260  strlen(optstr), 0, 0, ov, MAX_SUBSTRINGS);
261  if (ret < 6 || ret > 10) {
262  SCLogError(SC_ERR_PCRE_PARSE, "parse error, ret %" PRId32
263  ", string %s", ret, optstr);
264  goto error;
265  }
266  for (i = 0; i < (ret - 1); i++) {
267  res = pcre_get_substring((char *)optstr, ov, MAX_SUBSTRINGS,
268  i + 1, &str_ptr);
269  if (res < 0) {
270  SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed "
271  "for arg %d", i + 1);
272  goto error;
273  }
274  args[i] = (char *)str_ptr;
275  }
276 
277  /* Initialize the data */
278  data = SCMalloc(sizeof(DetectBytetestData));
279  if (unlikely(data == NULL))
280  goto error;
282  data->flags = 0;
283 
284 
285  /*
286  * The first four options are required and positional. The
287  * remaining arguments are flags and are not positional.
288  */
289 
290  /* Number of bytes */
291  if (ByteExtractStringUint32(&nbytes, 10, 0, args[0]) <= 0) {
292  SCLogError(SC_ERR_INVALID_VALUE, "Malformed number of bytes: %s", str_ptr);
293  goto error;
294  }
295 
296  /* Operator is next two args: neg + op */
297  data->op = 0;
298  if (args[1] != NULL && *args[1] == '!') {
299  data->flags |= DETECT_BYTETEST_NEGOP;
300  }
301 
302  if (args[2] != NULL) {
303  if ((strcmp("=", args[2]) == 0) || ((data->flags & DETECT_BYTETEST_NEGOP)
304  && strcmp("", args[2]) == 0)) {
305  data->op |= DETECT_BYTETEST_OP_EQ;
306  } else if (strcmp("<", args[2]) == 0) {
307  data->op |= DETECT_BYTETEST_OP_LT;
308  } else if (strcmp(">", args[2]) == 0) {
309  data->op |= DETECT_BYTETEST_OP_GT;
310  } else if (strcmp("&", args[2]) == 0) {
311  data->op |= DETECT_BYTETEST_OP_AND;
312  } else if (strcmp("^", args[2]) == 0) {
313  data->op |= DETECT_BYTETEST_OP_OR;
314  } else if (strcmp(">=", args[2]) == 0) {
315  data->op |= DETECT_BYTETEST_OP_GE;
316  } else if (strcmp("<=", args[2]) == 0) {
317  data->op |= DETECT_BYTETEST_OP_LE;
318  } else {
319  SCLogError(SC_ERR_INVALID_OPERATOR, "Invalid operator");
320  goto error;
321  }
322  }
323 
324  /* Value */
325  if (args[3][0] != '-' && isalpha((unsigned char)args[3][0])) {
326  if (value == NULL) {
327  SCLogError(SC_ERR_INVALID_ARGUMENT, "byte_test supplied with "
328  "var name for value. \"value\" argument supplied to "
329  "this function has to be non-NULL");
330  goto error;
331  }
332  *value = SCStrdup(args[3]);
333  if (*value == NULL)
334  goto error;
335  } else {
336  if (ByteExtractStringUint64(&data->value, 0, 0, args[3]) <= 0) {
337  SCLogError(SC_ERR_INVALID_VALUE, "Malformed value: %s", str_ptr);
338  goto error;
339  }
340  }
341 
342  /* Offset */
343  if (args[4][0] != '-' && isalpha((unsigned char)args[4][0])) {
344  if (offset == NULL) {
345  SCLogError(SC_ERR_INVALID_ARGUMENT, "byte_test supplied with "
346  "var name for offset. \"offset\" argument supplied to "
347  "this function has to be non-NULL");
348  goto error;
349  }
350  *offset = SCStrdup(args[4]);
351  if (*offset == NULL)
352  goto error;
353  } else {
354  if (ByteExtractStringInt32(&data->offset, 0, 0, args[4]) <= 0) {
355  SCLogError(SC_ERR_INVALID_VALUE, " Malformed offset: %s", str_ptr);
356  goto error;
357  }
358  }
359 
360  /* The remaining options are flags. */
361  /** \todo Error on dups? */
362  for (i = 5; i < (ret - 1); i++) {
363  if (args[i] != NULL) {
364  if (strcmp("relative", args[i]) == 0) {
366  } else if (strcasecmp("string", args[i]) == 0) {
367  data->flags |= DETECT_BYTETEST_STRING;
368  } else if (strcasecmp("dec", args[i]) == 0) {
370  } else if (strcasecmp("hex", args[i]) == 0) {
372  } else if (strcasecmp("oct", args[i]) == 0) {
374  } else if (strcasecmp("big", args[i]) == 0) {
375  if (data->flags & DETECT_BYTETEST_LITTLE) {
376  data->flags ^= DETECT_BYTETEST_LITTLE;
377  }
378  data->flags |= DETECT_BYTETEST_BIG;
379  } else if (strcasecmp("little", args[i]) == 0) {
380  data->flags |= DETECT_BYTETEST_LITTLE;
381  } else if (strcasecmp("dce", args[i]) == 0) {
382  data->flags |= DETECT_BYTETEST_DCE;
383  } else {
384  SCLogError(SC_ERR_UNKNOWN_VALUE, "Unknown value: \"%s\"",
385  args[i]);
386  goto error;
387  }
388  }
389  }
390 
391  if (data->flags & DETECT_BYTETEST_STRING) {
392  /* 23 - This is the largest string (octal, with a zero prefix) that
393  * will not overflow uint64_t. The only way this length
394  * could be over 23 and still not overflow is if it were zero
395  * prefixed and we only support 1 byte of zero prefix for octal.
396  *
397  * "01777777777777777777777" = 0xffffffffffffffff
398  */
399  if (nbytes > 23) {
400  SCLogError(SC_ERR_INVALID_VALUE, "Cannot test more than 23 bytes with \"string\": %s",
401  optstr);
402  goto error;
403  }
404  } else {
405  if (nbytes > 8) {
406  SCLogError(SC_ERR_INVALID_VALUE, "Cannot test more than 8 bytes without \"string\": %s",
407  optstr);
408  goto error;
409  }
410  if (data->base != DETECT_BYTETEST_BASE_UNSET) {
411  SCLogError(SC_ERR_INVALID_VALUE, "Cannot use a base without \"string\": %s", optstr);
412  goto error;
413  }
414  }
415 
416  /* This is max 23 so it will fit in a byte (see above) */
417  data->nbytes = (uint8_t)nbytes;
418 
419  for (i = 0; i < (ret - 1); i++){
420  if (args[i] != NULL) SCFree(args[i]);
421  }
422  return data;
423 
424 error:
425  for (i = 0; i < (ret - 1); i++){
426  if (args[i] != NULL) SCFree(args[i]);
427  }
428  if (data != NULL) DetectBytetestFree(data);
429  return NULL;
430 }
431 
432 static int DetectBytetestSetup(DetectEngineCtx *de_ctx, Signature *s, const char *optstr)
433 {
434  SigMatch *sm = NULL;
435  SigMatch *prev_pm = NULL;
436  char *value = NULL;
437  char *offset = NULL;
438  int ret = -1;
439 
440  DetectBytetestData *data = DetectBytetestParse(optstr, &value, &offset);
441  if (data == NULL)
442  goto error;
443 
444  int sm_list;
445  if (s->init_data->list != DETECT_SM_LIST_NOTSET) {
446  if (DetectBufferGetActiveList(de_ctx, s) == -1)
447  goto error;
448 
449  sm_list = s->init_data->list;
450 
451  if (data->flags & DETECT_BYTETEST_RELATIVE) {
453  }
454 
455  } else if (data->flags & DETECT_BYTETEST_DCE) {
456  if (data->flags & DETECT_BYTETEST_RELATIVE) {
457  prev_pm = DetectGetLastSMFromLists(s,
460  DETECT_ISDATAAT, -1);
461  if (prev_pm == NULL) {
462  sm_list = DETECT_SM_LIST_PMATCH;
463  } else {
464  sm_list = SigMatchListSMBelongsTo(s, prev_pm);
465  if (sm_list < 0)
466  goto error;
467  }
468  } else {
469  sm_list = DETECT_SM_LIST_PMATCH;
470  }
471 
473  goto error;
474 
475  } else if (data->flags & DETECT_BYTETEST_RELATIVE) {
476  prev_pm = DetectGetLastSMFromLists(s,
479  DETECT_ISDATAAT, -1);
480  if (prev_pm == NULL) {
481  sm_list = DETECT_SM_LIST_PMATCH;
482  } else {
483  sm_list = SigMatchListSMBelongsTo(s, prev_pm);
484  if (sm_list < 0)
485  goto error;
486  }
487 
488  } else {
489  sm_list = DETECT_SM_LIST_PMATCH;
490  }
491 
492  if (data->flags & DETECT_BYTETEST_DCE) {
493  if ((data->flags & DETECT_BYTETEST_STRING) ||
494  (data->flags & DETECT_BYTETEST_LITTLE) ||
495  (data->flags & DETECT_BYTETEST_BIG) ||
496  (data->base == DETECT_BYTETEST_BASE_DEC) ||
497  (data->base == DETECT_BYTETEST_BASE_HEX) ||
498  (data->base == DETECT_BYTETEST_BASE_OCT) ) {
499  SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "Invalid option. "
500  "A byte_test keyword with dce holds other invalid modifiers.");
501  goto error;
502  }
503  }
504 
505  if (value != NULL) {
506  SigMatch *bed_sm = DetectByteExtractRetrieveSMVar(value, s);
507  if (bed_sm == NULL) {
508  SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown byte_extract var "
509  "seen in byte_test - %s\n", value);
510  goto error;
511  }
512  data->value = ((DetectByteExtractData *)bed_sm->ctx)->local_id;
514  SCFree(value);
515  value = NULL;
516  }
517 
518  if (offset != NULL) {
519  SigMatch *bed_sm = DetectByteExtractRetrieveSMVar(offset, s);
520  if (bed_sm == NULL) {
521  SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown byte_extract var "
522  "seen in byte_test - %s\n", offset);
523  goto error;
524  }
525  data->offset = ((DetectByteExtractData *)bed_sm->ctx)->local_id;
527  SCFree(offset);
528  offset = NULL;
529  }
530 
531  sm = SigMatchAlloc();
532  if (sm == NULL)
533  goto error;
534  sm->type = DETECT_BYTETEST;
535  sm->ctx = (SigMatchCtx *)data;
536  SigMatchAppendSMToList(s, sm, sm_list);
537 
538  if (!(data->flags & DETECT_BYTETEST_RELATIVE))
539  goto okay;
540 
541  if (prev_pm == NULL)
542  goto okay;
543  if (prev_pm->type == DETECT_CONTENT) {
544  DetectContentData *cd = (DetectContentData *)prev_pm->ctx;
546  } else if (prev_pm->type == DETECT_PCRE) {
547  DetectPcreData *pd = (DetectPcreData *)prev_pm->ctx;
549  }
550 
551  okay:
552  ret = 0;
553  return ret;
554  error:
555  if (offset)
556  SCFree(offset);
557  if (value)
558  SCFree(value);
559  DetectBytetestFree(data);
560  return ret;
561 }
562 
563 /**
564  * \brief this function will free memory associated with DetectBytetestData
565  *
566  * \param data pointer to DetectBytetestData
567  */
568 static void DetectBytetestFree(void *ptr)
569 {
570  if (ptr == NULL)
571  return;
572 
573  DetectBytetestData *data = (DetectBytetestData *)ptr;
574  SCFree(data);
575 }
576 
577 
578 /* UNITTESTS */
579 #ifdef UNITTESTS
580 #include "util-unittest-helper.h"
581 static int g_file_data_buffer_id = 0;
582 static int g_dce_stub_data_buffer_id = 0;
583 
584 /**
585  * \test DetectBytetestTestParse01 is a test to make sure that we return "something"
586  * when given valid bytetest opt
587  */
588 static int DetectBytetestTestParse01(void)
589 {
590  int result = 0;
591  DetectBytetestData *data = NULL;
592  data = DetectBytetestParse("4, =, 1 , 0", NULL, NULL);
593  if (data != NULL) {
594  DetectBytetestFree(data);
595  result = 1;
596  }
597 
598  return result;
599 }
600 
601 /**
602  * \test DetectBytetestTestParse02 is a test for setting the required opts
603  */
604 static int DetectBytetestTestParse02(void)
605 {
606  int result = 0;
607  DetectBytetestData *data = NULL;
608  data = DetectBytetestParse("4, !=, 1, 0", NULL, NULL);
609  if (data != NULL) {
610  if ( (data->op == DETECT_BYTETEST_OP_EQ)
611  && (data->nbytes == 4)
612  && (data->value == 1)
613  && (data->offset == 0)
614  && (data->flags == DETECT_BYTETEST_NEGOP)
615  && (data->base == DETECT_BYTETEST_BASE_UNSET))
616  {
617  result = 1;
618  }
619  DetectBytetestFree(data);
620  }
621 
622  return result;
623 }
624 
625 /**
626  * \test DetectBytetestTestParse03 is a test for setting the relative flag
627  */
628 static int DetectBytetestTestParse03(void)
629 {
630  int result = 0;
631  DetectBytetestData *data = NULL;
632  data = DetectBytetestParse("4, !=, 1, 0, relative", NULL, NULL);
633  if (data != NULL) {
634  if ( (data->op == DETECT_BYTETEST_OP_EQ)
635  && (data->nbytes == 4)
636  && (data->value == 1)
637  && (data->offset == 0)
638  && (data->flags == ( DETECT_BYTETEST_NEGOP
640  && (data->base == DETECT_BYTETEST_BASE_UNSET))
641  {
642  result = 1;
643  }
644  DetectBytetestFree(data);
645  }
646 
647  return result;
648 }
649 
650 /**
651  * \test DetectBytetestTestParse04 is a test for setting the string/oct flags
652  */
653 static int DetectBytetestTestParse04(void)
654 {
655  int result = 0;
656  DetectBytetestData *data = NULL;
657  data = DetectBytetestParse("4, !=, 1, 0, string, oct", NULL, NULL);
658  if (data != NULL) {
659  if ( (data->op == DETECT_BYTETEST_OP_EQ)
660  && (data->nbytes == 4)
661  && (data->value == 1)
662  && (data->offset == 0)
663  && (data->flags == ( DETECT_BYTETEST_NEGOP
665  && (data->base == DETECT_BYTETEST_BASE_OCT))
666  {
667  result = 1;
668  }
669  DetectBytetestFree(data);
670  }
671 
672  return result;
673 }
674 
675 /**
676  * \test DetectBytetestTestParse05 is a test for setting the string/dec flags
677  */
678 static int DetectBytetestTestParse05(void)
679 {
680  int result = 0;
681  DetectBytetestData *data = NULL;
682  data = DetectBytetestParse("4, =, 1, 0, string, dec", NULL, NULL);
683  if (data != NULL) {
684  if ( (data->op == DETECT_BYTETEST_OP_EQ)
685  && (data->nbytes == 4)
686  && (data->value == 1)
687  && (data->offset == 0)
688  && (data->flags == DETECT_BYTETEST_STRING)
689  && (data->base == DETECT_BYTETEST_BASE_DEC))
690  {
691  result = 1;
692  }
693  DetectBytetestFree(data);
694  }
695 
696  return result;
697 }
698 
699 /**
700  * \test DetectBytetestTestParse06 is a test for setting the string/hex flags
701  */
702 static int DetectBytetestTestParse06(void)
703 {
704  int result = 0;
705  DetectBytetestData *data = NULL;
706  data = DetectBytetestParse("4, >, 1, 0, string, hex", NULL, NULL);
707  if (data != NULL) {
708  if ( (data->op == DETECT_BYTETEST_OP_GT)
709  && (data->nbytes == 4)
710  && (data->value == 1)
711  && (data->offset == 0)
712  && (data->flags == DETECT_BYTETEST_STRING)
713  && (data->base == DETECT_BYTETEST_BASE_HEX))
714  {
715  result = 1;
716  }
717  DetectBytetestFree(data);
718  }
719 
720  return result;
721 }
722 
723 /**
724  * \test DetectBytetestTestParse07 is a test for setting the big flag
725  */
726 static int DetectBytetestTestParse07(void)
727 {
728  int result = 0;
729  DetectBytetestData *data = NULL;
730  data = DetectBytetestParse("4, <, 5, 0, big", NULL, NULL);
731  if (data != NULL) {
732  if ( (data->op == DETECT_BYTETEST_OP_LT)
733  && (data->nbytes == 4)
734  && (data->value == 5)
735  && (data->offset == 0)
736  && (data->flags == 4)
737  && (data->base == DETECT_BYTETEST_BASE_UNSET))
738  {
739  result = 1;
740  }
741  DetectBytetestFree(data);
742  }
743 
744  return result;
745 }
746 
747 /**
748  * \test DetectBytetestTestParse08 is a test for setting the little flag
749  */
750 static int DetectBytetestTestParse08(void)
751 {
752  int result = 0;
753  DetectBytetestData *data = NULL;
754  data = DetectBytetestParse("4, <, 5, 0, little", NULL, NULL);
755  if (data != NULL) {
756  if ( (data->op == DETECT_BYTETEST_OP_LT)
757  && (data->nbytes == 4)
758  && (data->value == 5)
759  && (data->offset == 0)
760  && (data->flags == DETECT_BYTETEST_LITTLE)
761  && (data->base == DETECT_BYTETEST_BASE_UNSET))
762  {
763  result = 1;
764  }
765  DetectBytetestFree(data);
766  }
767 
768  return result;
769 }
770 
771 /**
772  * \test DetectBytetestTestParse09 is a test for neg operator only
773  */
774 static int DetectBytetestTestParse09(void)
775 {
776  int result = 0;
777  DetectBytetestData *data = NULL;
778  data = DetectBytetestParse("4, !, 5, 0", NULL, NULL);
779  if (data != NULL) {
780  if ( (data->op == DETECT_BYTETEST_OP_EQ)
781  && (data->nbytes == 4)
782  && (data->value == 5)
783  && (data->offset == 0)
784  && (data->flags == DETECT_BYTETEST_NEGOP)
785  && (data->base == DETECT_BYTETEST_BASE_UNSET))
786  {
787  result = 1;
788  }
789  DetectBytetestFree(data);
790  }
791 
792  return result;
793 }
794 
795 /**
796  * \test DetectBytetestTestParse10 is a test for whitespace
797  */
798 static int DetectBytetestTestParse10(void)
799 {
800  int result = 0;
801  DetectBytetestData *data = NULL;
802  data = DetectBytetestParse(" 4 , ! &, 5 , 0 , little ", NULL, NULL);
803  if (data != NULL) {
804  if ( (data->op == DETECT_BYTETEST_OP_AND)
805  && (data->nbytes == 4)
806  && (data->value == 5)
807  && (data->offset == 0)
809  && (data->base == DETECT_BYTETEST_BASE_UNSET))
810  {
811  result = 1;
812  }
813  DetectBytetestFree(data);
814  }
815 
816  return result;
817 }
818 
819 /**
820  * \test DetectBytetestTestParse11 is a test for whitespace
821  */
822 static int DetectBytetestTestParse11(void)
823 {
824  int result = 0;
825  DetectBytetestData *data = NULL;
826  data = DetectBytetestParse("4,!^,5,0,little,string,relative,hex", NULL, NULL);
827  if (data != NULL) {
828  if ( (data->op == DETECT_BYTETEST_OP_OR)
829  && (data->nbytes == 4)
830  && (data->value == 5)
831  && (data->offset == 0)
832  && (data->flags == ( DETECT_BYTETEST_NEGOP
836  && (data->base == DETECT_BYTETEST_BASE_HEX))
837  {
838  result = 1;
839  }
840  DetectBytetestFree(data);
841  }
842 
843  return result;
844 }
845 
846 /**
847  * \test DetectBytetestTestParse12 is a test for hex w/o string
848  */
849 static int DetectBytetestTestParse12(void)
850 {
851  int result = 0;
852  DetectBytetestData *data = NULL;
853  data = DetectBytetestParse("4, =, 1, 0, hex", NULL, NULL);
854  if (data == NULL) {
855  result = 1;
856  }
857 
858  return result;
859 }
860 
861 /**
862  * \test DetectBytetestTestParse13 is a test for too many bytes to extract
863  */
864 static int DetectBytetestTestParse13(void)
865 {
866  int result = 0;
867  DetectBytetestData *data = NULL;
868  data = DetectBytetestParse("9, =, 1, 0", NULL, NULL);
869  if (data == NULL) {
870  result = 1;
871  }
872 
873  return result;
874 }
875 
876 /**
877  * \test DetectBytetestTestParse14 is a test for large string extraction
878  */
879 static int DetectBytetestTestParse14(void)
880 {
881  int result = 0;
882  DetectBytetestData *data = NULL;
883  data = DetectBytetestParse("23,=,0xffffffffffffffffULL,0,string,oct", NULL, NULL);
884  if (data != NULL) {
885  if ( (data->op == DETECT_BYTETEST_OP_EQ)
886  && (data->nbytes == 23)
887  && (data->value == 0xffffffffffffffffULL)
888  && (data->offset == 0)
889  && (data->flags == DETECT_BYTETEST_STRING)
890  && (data->base == DETECT_BYTETEST_BASE_OCT))
891  {
892  result = 1;
893  }
894  DetectBytetestFree(data);
895  }
896 
897  return result;
898 }
899 
900 /**
901  * \test DetectBytetestTestParse15 is a test for too many bytes to extract (string)
902  */
903 static int DetectBytetestTestParse15(void)
904 {
905  int result = 0;
906  DetectBytetestData *data = NULL;
907  data = DetectBytetestParse("24, =, 0xffffffffffffffffULL, 0, string", NULL, NULL);
908  if (data == NULL) {
909  result = 1;
910  }
911 
912  return result;
913 }
914 
915 /**
916  * \test DetectBytetestTestParse16 is a test for offset too big
917  */
918 static int DetectBytetestTestParse16(void)
919 {
920  int result = 0;
921  DetectBytetestData *data = NULL;
922  data = DetectBytetestParse("4,=,0,0xffffffffffffffffULL", NULL, NULL);
923  if (data == NULL) {
924  result = 1;
925  }
926 
927  return result;
928 }
929 
930 /**
931  * \test Test dce option.
932  */
933 static int DetectBytetestTestParse17(void)
934 {
935  int result = 0;
936  DetectBytetestData *data = NULL;
937  data = DetectBytetestParse("4, <, 5, 0, dce", NULL, NULL);
938  if (data != NULL) {
939  if ( (data->op == DETECT_BYTETEST_OP_LT) &&
940  (data->nbytes == 4) &&
941  (data->value == 5) &&
942  (data->offset == 0) &&
943  (data->flags & DETECT_BYTETEST_DCE) ) {
944  result = 1;
945  }
946  DetectBytetestFree(data);
947  }
948 
949  return result;
950 }
951 
952 /**
953  * \test Test dce option.
954  */
955 static int DetectBytetestTestParse18(void)
956 {
957  int result = 0;
958  DetectBytetestData *data = NULL;
959  data = DetectBytetestParse("4, <, 5, 0", NULL, NULL);
960  if (data != NULL) {
961  if ( (data->op == DETECT_BYTETEST_OP_LT) &&
962  (data->nbytes == 4) &&
963  (data->value == 5) &&
964  (data->offset == 0) &&
965  !(data->flags & DETECT_BYTETEST_DCE) ) {
966  result = 1;
967  }
968  DetectBytetestFree(data);
969  }
970 
971  return result;
972 }
973 
974 /**
975  * \test Test dce option.
976  */
977 static int DetectBytetestTestParse19(void)
978 {
979  Signature *s = SigAlloc();
980  if (s == NULL)
981  return 0;
982 
983  int result = 1;
984 
985  s->alproto = ALPROTO_DCERPC;
986 
987  result &= (DetectBytetestSetup(NULL, s, "1,=,1,6,dce") == 0);
988  result &= (DetectBytetestSetup(NULL, s, "1,=,1,6,string,dce") == -1);
989  result &= (DetectBytetestSetup(NULL, s, "1,=,1,6,big,dce") == -1);
990  result &= (DetectBytetestSetup(NULL, s, "1,=,1,6,little,dce") == -1);
991  result &= (DetectBytetestSetup(NULL, s, "1,=,1,6,hex,dce") == -1);
992  result &= (DetectBytetestSetup(NULL, s, "1,=,1,6,oct,dce") == -1);
993  result &= (DetectBytetestSetup(NULL, s, "1,=,1,6,dec,dce") == -1);
994 
995  SigFree(s);
996  return result;
997 }
998 
999 /**
1000  * \test Test dce option.
1001  */
1002 static int DetectBytetestTestParse20(void)
1003 {
1004  DetectEngineCtx *de_ctx = NULL;
1005  int result = 1;
1006  Signature *s = NULL;
1007  DetectBytetestData *bd = NULL;
1008 
1009  de_ctx = DetectEngineCtxInit();
1010  if (de_ctx == NULL)
1011  goto end;
1012 
1013  de_ctx->flags |= DE_QUIET;
1014  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
1015  "(msg:\"Testing bytetest_body\"; "
1016  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1017  "dce_stub_data; "
1018  "content:\"one\"; distance:0; "
1019  "byte_test:1,=,1,6,relative,dce; sid:1;)");
1020  if (de_ctx->sig_list == NULL) {
1021  result = 0;
1022  goto end;
1023  }
1024  s = de_ctx->sig_list;
1025  if (s->sm_lists_tail[g_dce_stub_data_buffer_id] == NULL) {
1026  result = 0;
1027  goto end;
1028  }
1029  result &= (s->sm_lists_tail[g_dce_stub_data_buffer_id]->type == DETECT_BYTETEST);
1030  bd = (DetectBytetestData *)s->sm_lists_tail[g_dce_stub_data_buffer_id]->ctx;
1031  if (!(bd->flags & DETECT_BYTETEST_DCE) &&
1032  !(bd->flags & DETECT_BYTETEST_RELATIVE) &&
1033  (bd->flags & DETECT_BYTETEST_STRING) &&
1034  (bd->flags & DETECT_BYTETEST_BIG) &&
1035  (bd->flags & DETECT_BYTETEST_LITTLE) &&
1036  (bd->flags & DETECT_BYTETEST_NEGOP) ) {
1037  result = 0;
1038  goto end;
1039  }
1040 
1041  s->next = SigInit(de_ctx, "alert tcp any any -> any any "
1042  "(msg:\"Testing bytetest_body\"; "
1043  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1044  "dce_stub_data; "
1045  "content:\"one\"; distance:0; "
1046  "byte_test:1,=,1,6,relative,dce; sid:1;)");
1047  if (s->next == NULL) {
1048  result = 0;
1049  goto end;
1050  }
1051  s = s->next;
1052  if (s->sm_lists_tail[g_dce_stub_data_buffer_id] == NULL) {
1053  result = 0;
1054  goto end;
1055  }
1056  result &= (s->sm_lists_tail[g_dce_stub_data_buffer_id]->type == DETECT_BYTETEST);
1057  bd = (DetectBytetestData *)s->sm_lists_tail[g_dce_stub_data_buffer_id]->ctx;
1058  if (!(bd->flags & DETECT_BYTETEST_DCE) &&
1059  !(bd->flags & DETECT_BYTETEST_RELATIVE) &&
1060  (bd->flags & DETECT_BYTETEST_STRING) &&
1061  (bd->flags & DETECT_BYTETEST_BIG) &&
1062  (bd->flags & DETECT_BYTETEST_LITTLE) &&
1063  (bd->flags & DETECT_BYTETEST_NEGOP) ) {
1064  result = 0;
1065  goto end;
1066  }
1067 
1068  s->next = SigInit(de_ctx, "alert tcp any any -> any any "
1069  "(msg:\"Testing bytetest_body\"; "
1070  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1071  "dce_stub_data; "
1072  "content:\"one\"; distance:0; "
1073  "byte_test:1,=,1,6,relative; sid:1;)");
1074  if (s->next == NULL) {
1075  result = 0;
1076  goto end;
1077  }
1078  s = s->next;
1079  if (s->sm_lists_tail[g_dce_stub_data_buffer_id] == NULL) {
1080  result = 0;
1081  goto end;
1082  }
1083  result &= (s->sm_lists_tail[g_dce_stub_data_buffer_id]->type == DETECT_BYTETEST);
1084  bd = (DetectBytetestData *)s->sm_lists_tail[g_dce_stub_data_buffer_id]->ctx;
1085  if ((bd->flags & DETECT_BYTETEST_DCE) &&
1086  !(bd->flags & DETECT_BYTETEST_RELATIVE) &&
1087  (bd->flags & DETECT_BYTETEST_STRING) &&
1088  (bd->flags & DETECT_BYTETEST_BIG) &&
1089  (bd->flags & DETECT_BYTETEST_LITTLE) &&
1090  (bd->flags & DETECT_BYTETEST_NEGOP) ) {
1091  result = 0;
1092  goto end;
1093  }
1094 
1095  end:
1096  SigGroupCleanup(de_ctx);
1097  SigCleanSignatures(de_ctx);
1098  DetectEngineCtxFree(de_ctx);
1099 
1100  return result;
1101 }
1102 
1103 /**
1104  * \test Test dce option.
1105  */
1106 static int DetectBytetestTestParse21(void)
1107 {
1108  DetectEngineCtx *de_ctx = NULL;
1109  int result = 1;
1110  Signature *s = NULL;
1111 
1112  de_ctx = DetectEngineCtxInit();
1113  if (de_ctx == NULL)
1114  goto end;
1115 
1116  de_ctx->flags |= DE_QUIET;
1117  s = SigInit(de_ctx, "alert tcp any any -> any any "
1118  "(msg:\"Testing bytetest_body\"; "
1119  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1120  "content:\"one\"; byte_test:1,=,1,6,string,dce; sid:1;)");
1121  if (s != NULL) {
1122  result = 0;
1123  goto end;
1124  }
1125 
1126  s = SigInit(de_ctx, "alert tcp any any -> any any "
1127  "(msg:\"Testing bytetest_body\"; "
1128  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1129  "content:\"one\"; byte_test:1,=,1,6,big,dce; sid:1;)");
1130  if (s != NULL) {
1131  result = 0;
1132  goto end;
1133  }
1134 
1135  s = SigInit(de_ctx, "alert tcp any any -> any any "
1136  "(msg:\"Testing bytetest_body\"; "
1137  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1138  "content:\"one\"; byte_test:1,=,1,6,little,dce; sid:1;)");
1139  if (s != NULL) {
1140  result = 0;
1141  goto end;
1142  }
1143 
1144  s = SigInit(de_ctx, "alert tcp any any -> any any "
1145  "(msg:\"Testing bytetest_body\"; "
1146  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1147  "content:\"one\"; byte_test:1,=,1,6,hex,dce; sid:1;)");
1148  if (s != NULL) {
1149  result = 0;
1150  goto end;
1151  }
1152 
1153  s = SigInit(de_ctx, "alert tcp any any -> any any "
1154  "(msg:\"Testing bytetest_body\"; "
1155  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1156  "content:\"one\"; byte_test:1,=,1,6,dec,dce; sid:1;)");
1157  if (s != NULL) {
1158  result = 0;
1159  goto end;
1160  }
1161 
1162  s = SigInit(de_ctx, "alert tcp any any -> any any "
1163  "(msg:\"Testing bytetest_body\"; "
1164  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1165  "content:\"one\"; byte_test:1,=,1,6,oct,dce; sid:1;)");
1166  if (s != NULL) {
1167  result = 0;
1168  goto end;
1169  }
1170 
1171  s = SigInit(de_ctx, "alert tcp any any -> any any "
1172  "(msg:\"Testing bytetest_body\"; "
1173  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1174  "content:\"one\"; byte_test:1,=,1,6,string,hex,dce; sid:1;)");
1175  if (s != NULL) {
1176  result = 0;
1177  goto end;
1178  }
1179 
1180  s = SigInit(de_ctx, "alert tcp any any -> any any "
1181  "(msg:\"Testing bytetest_body\"; "
1182  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1183  "content:\"one\"; byte_test:1,=,1,6,big,string,hex,dce; sid:1;)");
1184  if (s != NULL) {
1185  result = 0;
1186  goto end;
1187  }
1188 
1189  s = SigInit(de_ctx, "alert tcp any any -> any any "
1190  "(msg:\"Testing bytetest_body\"; "
1191  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1192  "content:\"one\"; byte_test:1,=,1,6,big,string,oct,dce; sid:1;)");
1193  if (s != NULL) {
1194  result = 0;
1195  goto end;
1196  }
1197 
1198  s = SigInit(de_ctx, "alert tcp any any -> any any "
1199  "(msg:\"Testing bytetest_body\"; "
1200  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1201  "content:\"one\"; byte_test:1,=,1,6,little,string,hex,dce; sid:1;)");
1202  if (s != NULL) {
1203  result = 0;
1204  goto end;
1205  }
1206 
1207  s = SigInit(de_ctx, "alert tcp any any -> any any "
1208  "(msg:\"Testing bytetest_body\"; "
1209  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1210  "content:\"one\"; byte_test:1,=,1,6,big,string,dec,dce; sid:1;)");
1211  if (s != NULL) {
1212  result = 0;
1213  goto end;
1214  }
1215 
1216  end:
1217  SigGroupCleanup(de_ctx);
1218  SigCleanSignatures(de_ctx);
1219  DetectEngineCtxFree(de_ctx);
1220 
1221  return result;
1222 }
1223 
1224 /**
1225  * \test Test file_data
1226  */
1227 static int DetectBytetestTestParse22(void)
1228 {
1229  DetectEngineCtx *de_ctx = NULL;
1230  int result = 0;
1231  Signature *s = NULL;
1232  DetectBytetestData *bd = NULL;
1233 
1234  de_ctx = DetectEngineCtxInit();
1235  if (de_ctx == NULL)
1236  goto end;
1237 
1238  de_ctx->flags |= DE_QUIET;
1239  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
1240  "(file_data; byte_test:1,=,1,6,relative; sid:1;)");
1241  if (de_ctx->sig_list == NULL) {
1242  printf("sig parse failed: ");
1243  goto end;
1244  }
1245 
1246  s = de_ctx->sig_list;
1247  if (s->sm_lists_tail[g_file_data_buffer_id] == NULL) {
1248  printf("empty server body list: ");
1249  goto end;
1250  }
1251 
1252  if (s->sm_lists_tail[g_file_data_buffer_id]->type != DETECT_BYTETEST) {
1253  printf("bytetest not last sm in server body list: ");
1254  goto end;
1255  }
1256 
1257  bd = (DetectBytetestData *)s->sm_lists_tail[g_file_data_buffer_id]->ctx;
1258  if (bd->flags & DETECT_BYTETEST_DCE &&
1260  (bd->flags & DETECT_BYTETEST_STRING) &&
1261  (bd->flags & DETECT_BYTETEST_BIG) &&
1262  (bd->flags & DETECT_BYTETEST_LITTLE) &&
1263  (bd->flags & DETECT_BYTETEST_NEGOP) ) {
1264  printf("wrong flags: ");
1265  goto end;
1266  }
1267 
1268  result = 1;
1269  end:
1270  SigGroupCleanup(de_ctx);
1271  SigCleanSignatures(de_ctx);
1272  DetectEngineCtxFree(de_ctx);
1273 
1274  return result;
1275 }
1276 
1277 /**
1278  * \test DetectByteTestTestPacket01 is a test to check matches of
1279  * byte_test and byte_test relative works if the previous keyword is pcre
1280  * (bug 142)
1281  */
1282 static int DetectByteTestTestPacket01 (void)
1283 {
1284  int result = 0;
1285  uint8_t *buf = (uint8_t *)"GET /AllWorkAndNoPlayMakesWillADullBoy HTTP/1.0"
1286  "User-Agent: Wget/1.11.4"
1287  "Accept: */*"
1288  "Host: www.google.com"
1289  "Connection: Keep-Alive"
1290  "Date: Mon, 04 Jan 2010 17:29:39 GMT";
1291  uint16_t buflen = strlen((char *)buf);
1292  Packet *p;
1293  p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP);
1294 
1295  if (p == NULL)
1296  goto end;
1297 
1298  char sig[] = "alert tcp any any -> any any (msg:\"pcre + byte_test + "
1299  "relative\"; pcre:\"/AllWorkAndNoPlayMakesWillADullBoy/\"; byte_test:1,=,1"
1300  ",6,relative,string,dec; sid:126; rev:1;)";
1301 
1302  result = UTHPacketMatchSig(p, sig);
1303 
1304  UTHFreePacket(p);
1305 end:
1306  return result;
1307 }
1308 
1309 /**
1310  * \test DetectByteTestTestPacket02 is a test to check matches of
1311  * byte_test and byte_test relative works if the previous keyword is byte_jump
1312  * (bug 158)
1313  */
1314 static int DetectByteTestTestPacket02 (void)
1315 {
1316  int result = 0;
1317  uint8_t *buf = (uint8_t *)"GET /AllWorkAndNoPlayMakesWillADullBoy HTTP/1.0"
1318  "User-Agent: Wget/1.11.4"
1319  "Accept: */*"
1320  "Host: www.google.com"
1321  "Connection: Keep-Alive"
1322  "Date: Mon, 04 Jan 2010 17:29:39 GMT";
1323  uint16_t buflen = strlen((char *)buf);
1324  Packet *p;
1325  p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP);
1326 
1327  if (p == NULL)
1328  goto end;
1329 
1330  char sig[] = "alert tcp any any -> any any (msg:\"content + byte_test + "
1331  "relative\"; byte_jump:1,44,string,dec; byte_test:1,=,0,0,relative,string,"
1332  "dec; sid:777; rev:1;)";
1333 
1334  result = UTHPacketMatchSig(p, sig);
1335 
1336  UTHFreePacket(p);
1337 end:
1338  return result;
1339 }
1340 
1341 static int DetectByteTestTestPacket03(void)
1342 {
1343  int result = 0;
1344  uint8_t *buf = NULL;
1345  uint16_t buflen = 0;
1346  buf = SCMalloc(4);
1347  if (unlikely(buf == NULL)) {
1348  printf("malloc failed\n");
1349  exit(EXIT_FAILURE);
1350  }
1351  memcpy(buf, "boom", 4);
1352  buflen = 4;
1353 
1354  Packet *p;
1355  p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP);
1356 
1357  if (p == NULL)
1358  goto end;
1359 
1360  char sig[] = "alert tcp any any -> any any (msg:\"content + byte_test\"; "
1361  "byte_test:1,=,65,214748364; sid:1; rev:1;)";
1362 
1363  result = !UTHPacketMatchSig(p, sig);
1364 
1365  UTHFreePacket(p);
1366 
1367 end:
1368  return result;
1369 }
1370 
1371 /** \test Test the byte_test signature matching with operator <= */
1372 static int DetectByteTestTestPacket04(void)
1373 {
1374  int result = 0;
1375  uint8_t *buf = (uint8_t *)"GET /AllWorkAndNoPlayMakesWillADullBoy HTTP/1.0"
1376  "User-Agent: Wget/1.11.4"
1377  "Accept: */*"
1378  "Host: www.google.com"
1379  "Connection: Keep-Alive"
1380  "Date: Mon, 04 Jan 2010 17:29:39 GMT";
1381  uint16_t buflen = strlen((char *)buf);
1382 
1383  Packet *p;
1384  p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP);
1385 
1386  if (p == NULL)
1387  goto end;
1388 
1389  char sig[] = "alert tcp any any -> any any (msg:\"content + byte_test +"
1390  "relative\"; content:\"GET \"; depth:4; content:\"HTTP/1.\"; "
1391  "byte_test:1,<=,0,0,relative,string,dec; sid:124; rev:1;)";
1392 
1393  result = UTHPacketMatchSig(p, sig);
1394 
1395  UTHFreePacket(p);
1396 
1397 end:
1398  return result;
1399 }
1400 
1401 /** \test Test the byte_test signature matching with operator >= */
1402 static int DetectByteTestTestPacket05(void)
1403 {
1404  int result = 0;
1405  uint8_t *buf = (uint8_t *)"GET /AllWorkAndNoPlayMakesWillADullBoy HTTP/1.0"
1406  "User-Agent: Wget/1.11.4"
1407  "Accept: */*"
1408  "Host: www.google.com"
1409  "Connection: Keep-Alive"
1410  "Date: Mon, 04 Jan 2010 17:29:39 GMT";
1411  uint16_t buflen = strlen((char *)buf);
1412 
1413  Packet *p;
1414  p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP);
1415 
1416  if (p == NULL)
1417  goto end;
1418 
1419  char sig[] = "alert tcp any any -> any any (msg:\"content + byte_test +"
1420  "relative\"; content:\"GET \"; depth:4; content:\"HTTP/1.\"; "
1421  "byte_test:1,>=,0,0,relative,string,dec; sid:125; rev:1;)";
1422 
1423  result = UTHPacketMatchSig(p, sig);
1424 
1425  UTHFreePacket(p);
1426 
1427 end:
1428  return result;
1429 }
1430 
1431 #endif /* UNITTESTS */
1432 
1433 
1434 /**
1435  * \brief this function registers unit tests for DetectBytetest
1436  */
1437 static void DetectBytetestRegisterTests(void)
1438 {
1439 #ifdef UNITTESTS
1440  g_file_data_buffer_id = DetectBufferTypeGetByName("file_data");
1441  g_dce_stub_data_buffer_id = DetectBufferTypeGetByName("dce_stub_data");
1442 
1443  UtRegisterTest("DetectBytetestTestParse01", DetectBytetestTestParse01);
1444  UtRegisterTest("DetectBytetestTestParse02", DetectBytetestTestParse02);
1445  UtRegisterTest("DetectBytetestTestParse03", DetectBytetestTestParse03);
1446  UtRegisterTest("DetectBytetestTestParse04", DetectBytetestTestParse04);
1447  UtRegisterTest("DetectBytetestTestParse05", DetectBytetestTestParse05);
1448  UtRegisterTest("DetectBytetestTestParse06", DetectBytetestTestParse06);
1449  UtRegisterTest("DetectBytetestTestParse07", DetectBytetestTestParse07);
1450  UtRegisterTest("DetectBytetestTestParse08", DetectBytetestTestParse08);
1451  UtRegisterTest("DetectBytetestTestParse09", DetectBytetestTestParse09);
1452  UtRegisterTest("DetectBytetestTestParse10", DetectBytetestTestParse10);
1453  UtRegisterTest("DetectBytetestTestParse11", DetectBytetestTestParse11);
1454  UtRegisterTest("DetectBytetestTestParse12", DetectBytetestTestParse12);
1455  UtRegisterTest("DetectBytetestTestParse13", DetectBytetestTestParse13);
1456  UtRegisterTest("DetectBytetestTestParse14", DetectBytetestTestParse14);
1457  UtRegisterTest("DetectBytetestTestParse15", DetectBytetestTestParse15);
1458  UtRegisterTest("DetectBytetestTestParse16", DetectBytetestTestParse16);
1459  UtRegisterTest("DetectBytetestTestParse17", DetectBytetestTestParse17);
1460  UtRegisterTest("DetectBytetestTestParse18", DetectBytetestTestParse18);
1461  UtRegisterTest("DetectBytetestTestParse19", DetectBytetestTestParse19);
1462  UtRegisterTest("DetectBytetestTestParse20", DetectBytetestTestParse20);
1463  UtRegisterTest("DetectBytetestTestParse21", DetectBytetestTestParse21);
1464  UtRegisterTest("DetectBytetestTestParse22", DetectBytetestTestParse22);
1465 
1466  UtRegisterTest("DetectByteTestTestPacket01", DetectByteTestTestPacket01);
1467  UtRegisterTest("DetectByteTestTestPacket02", DetectByteTestTestPacket02);
1468  UtRegisterTest("DetectByteTestTestPacket03", DetectByteTestTestPacket03);
1469  UtRegisterTest("DetectByteTestTestPacket04", DetectByteTestTestPacket04);
1470  UtRegisterTest("DetectByteTestTestPacket05", DetectByteTestTestPacket05);
1471 #endif /* UNITTESTS */
1472 }
1473 
#define MAX_SUBSTRINGS
SigTableElmt sigmatch_table[DETECT_TBLSIZE]
Definition: detect.h:1403
SignatureInitData * init_data
Definition: detect.h:560
uint16_t flags
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1146
#define SCLogDebug(...)
Definition: util-debug.h:335
int DetectSignatureSetAppProto(Signature *s, AppProto alproto)
#define DETECT_BYTETEST_LITTLE
#define DETECT_BYTETEST_BASE_DEC
void DetectBytetestRegister(void)
int ByteExtractStringInt32(int32_t *res, int base, uint16_t len, const char *str)
Definition: util-byte.c:363
#define DETECT_BYTETEST_BASE_UNSET
#define DETECT_BYTETEST_OP_LT
#define unlikely(expr)
Definition: util-optimize.h:35
#define DETECT_BYTETEST_OP_EQ
Signature * SigInit(DetectEngineCtx *, const char *)
Parses a signature and adds it to the Detection Engine Context.
Signature * sig_list
Definition: detect.h:726
uint64_t offset
#define PARSE_REGEX
Regex for parsing our options.
void SigCleanSignatures(DetectEngineCtx *de_ctx)
#define DETECT_BYTETEST_BASE_OCT
int ByteExtractStringUint32(uint32_t *res, int base, uint16_t len, const char *str)
Definition: util-byte.c:244
uint32_t buffer_offset
Definition: detect.h:991
#define DETECT_BYTETEST_BIG
const char * name
Definition: detect.h:1160
Signature container.
Definition: detect.h:492
Used to start a pointer to SigMatch context Should never be dereferenced without casting to something...
Definition: detect.h:319
uint16_t flags
Definition: detect-pcre.h:42
main detection engine ctx
Definition: detect.h:720
int DetectBufferGetActiveList(DetectEngineCtx *de_ctx, Signature *s)
int ByteExtractStringUint64(uint64_t *res, int base, uint16_t len, const char *str)
Definition: util-byte.c:239
#define DE_QUIET
Definition: detect.h:298
#define DETECT_BYTETEST_BASE_HEX
int DetectBufferTypeGetByName(const char *name)
#define DETECT_BYTETEST_STRING
uint8_t flags
Definition: detect.h:721
#define DETECT_BYTETEST_OP_OR
void(* Free)(void *)
Definition: detect.h:1151
int UTHPacketMatchSig(Packet *p, const char *sig)
#define SCLogError(err_code,...)
Macro used to log ERROR messages.
Definition: util-debug.h:294
void SigFree(Signature *)
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
void DetectSetupParseRegexes(const char *parse_str, pcre **parse_regex, pcre_extra **parse_regex_study)
#define DETECT_BYTETEST_OP_GE
#define SCEnter(...)
Definition: util-debug.h:337
#define DETECT_BYTETEST_VALUE_BE
#define DETECT_SM_LIST_NOTSET
Definition: detect.h:118
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.
int DetectBytetestDoMatch(DetectEngineThreadCtx *det_ctx, const Signature *s, const SigMatchCtx *ctx, uint8_t *payload, uint32_t payload_len, uint8_t flags, int32_t offset, uint64_t value)
Bytetest detection code.
AppProto alproto
Definition: detect.h:496
#define BYTE_BIG_ENDIAN
Definition: util-byte.h:29
int SigGroupCleanup(DetectEngineCtx *de_ctx)
struct Signature_ * next
Definition: detect.h:563
uint8_t type
Definition: detect.h:325
#define SCReturnInt(x)
Definition: util-debug.h:341
#define DETECT_BYTETEST_OP_AND
#define BYTE_LITTLE_ENDIAN
Definition: util-byte.h:30
void SigMatchAppendSMToList(Signature *s, SigMatch *new, int list)
Append a SigMatch to the list type.
Definition: detect-parse.c:282
Signature * SigAlloc(void)
#define DETECT_BYTETEST_NEGOP
SigMatch * DetectByteExtractRetrieveSMVar(const char *arg, const Signature *s)
Lookup the SigMatch for a named byte_extract variable.
SigMatchCtx * ctx
Definition: detect.h:327
#define SCMalloc(a)
Definition: util-mem.h:174
uint16_t payload_len
#define SCFree(a)
Definition: util-mem.h:236
PoolThreadReserved res
#define DETECT_BYTETEST_RELATIVE
#define DETECT_BYTETEST_OP_GT
int(* Match)(ThreadVars *, DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition: detect.h:1129
SigMatch * DetectGetLastSMFromLists(const Signature *s,...)
Returns the sm with the largest index (added latest) from the lists passed to us. ...
Definition: detect-parse.c:401
int ByteExtractUint64(uint64_t *res, int e, uint16_t len, const uint8_t *bytes)
Definition: util-byte.c:122
#define DETECT_BYTETEST_DCE
void UTHFreePacket(Packet *p)
UTHFreePacket: function to release the allocated data from UTHBuildPacket and the packet itself...
#define DETECT_BYTETEST_OFFSET_BE
#define SCStrdup(a)
Definition: util-mem.h:220
#define DETECT_PCRE_RELATIVE_NEXT
Definition: detect-pcre.h:32
#define DETECT_CONTENT_RELATIVE_NEXT
SigMatch * SigMatchAlloc(void)
Definition: detect-parse.c:226
uint8_t len
Per thread variable structure.
Definition: threadvars.h:57
Holds data related to byte_extract keyword.
int SigMatchListSMBelongsTo(const Signature *s, const SigMatch *key_sm)
Definition: detect-parse.c:555
uint16_t payload_len
Definition: decode.h:546
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
uint8_t * payload
Definition: decode.h:545
void(* RegisterTests)(void)
Definition: detect.h:1152
a single match condition for a signature
Definition: detect.h:324
#define DETECT_BYTETEST_OP_LE
DetectEngineCtx * DetectEngineCtxInit(void)