41 #define PARSE_REGEX "^(\\s*only\\s*)|\\s*([0-9]+)\\s*,\\s*([0-9]+)\\s*$"
47 static void DetectFastPatternRegisterTests(
void);
81 if (list_id == tmp->list_id) {
90 if (priority < tmp->priority)
100 new->list_id = list_id;
101 new->priority = priority;
110 new->list_id = list_id;
111 new->priority = priority;
130 Add(&g_fp_support_smlist_list, list_id, priority);
154 FatalError(
"out of memory: %s", strerror(errno));
214 char arg_substr[128] =
"";
216 pcre2_match_data *match = NULL;
220 if (pm1 == NULL && pm2 == NULL) {
222 "the rule, without a content context. Please use a "
223 "content based keyword before using fast_pattern");
233 }
else if (pm1 && !pm2) {
242 SCLogError(
"fast_pattern cannot be used on to_client keyword for "
243 "transactional rule with a streaming buffer to server %u",
260 "used with negated content, along with relative modifiers");
264 if (arg == NULL|| strcmp(arg,
"") == 0) {
267 "options for the same content");
278 "can be used on only one content in a rule");
286 SCLogError(
"fast_pattern cannot be used with base64_data");
305 "used with negated content or with any of the relative "
306 "modifiers like distance, within, offset, depth");
312 }
else if (ret == 4) {
313 pcre2len =
sizeof(arg_substr);
314 res = pcre2_substring_copy_bynumber(match, 2, (PCRE2_UCHAR8 *)arg_substr, &pcre2len);
316 SCLogError(
"pcre2_substring_copy_bynumber failed "
317 "for fast_pattern offset");
328 pcre2len =
sizeof(arg_substr);
329 res = pcre2_substring_copy_bynumber(match, 3, (PCRE2_UCHAR8 *)arg_substr, &pcre2len);
331 SCLogError(
"pcre2_substring_copy_bynumber failed "
332 "for fast_pattern offset");
346 "exceeds limit pattern length limit");
352 "offset (%u)) exceeds pattern length (%u)",
362 SCLogError(
"parse error, ret %" PRId32
", string %s", ret, arg);
368 pcre2_match_data_free(match);
373 pcre2_match_data_free(match);
392 static int DetectFastPatternStickySingle(
const char *sticky,
const int list)
397 snprintf(
string,
sizeof(
string),
398 "alert tcp any any -> any any "
399 "(%s%scontent:\"one\"; fast_pattern; sid:1;)",
400 sticky ? sticky :
"", sticky ?
"; " :
" ");
413 static int DetectFastPatternModifierSingle(
const char *sticky,
const int list)
418 snprintf(
string,
sizeof(
string),
419 "alert tcp any any -> any any "
420 "(content:\"one\"; %s%sfast_pattern; sid:1;)",
421 sticky ? sticky :
"", sticky ?
"; " :
" ");
434 static int DetectFastPatternStickySingleNoFP(
const char *sticky,
const int list)
439 snprintf(
string,
sizeof(
string),
440 "alert tcp any any -> any any "
441 "(%s%scontent:\"one\"; sid:1;)",
442 sticky ? sticky :
"", sticky ?
"; " :
" ");
455 static int DetectFastPatternModifierSingleNoFP(
const char *sticky,
const int list)
460 snprintf(
string,
sizeof(
string),
461 "alert tcp any any -> any any "
462 "(content:\"one\"; %s%ssid:1;)",
463 sticky ? sticky :
"", sticky ?
"; " :
" ");
476 static int DetectFastPatternStickySingleBadArg(
const char *sticky)
482 snprintf(
string,
sizeof(
string),
483 "alert tcp any any -> any any "
484 "(%s%scontent:\"one\"; fast_pattern:boo; sid:1;)",
485 sticky ? sticky :
"", sticky ?
"; " :
" ");
489 snprintf(
string,
sizeof(
string),
490 "alert tcp any any -> any any "
491 "(%s%scontent:\"one\"; fast_pattern:only; content:\"two\"; distance:10; sid:1;)",
492 sticky ? sticky :
"", sticky ?
"; " :
" ");
496 snprintf(
string,
sizeof(
string),
497 "alert tcp any any -> any any "
498 "(%s%scontent:\"one\"; content:\"two\"; fast_pattern:only; distance:10; sid:1;)",
499 sticky ? sticky :
"", sticky ?
"; " :
" ");
503 snprintf(
string,
sizeof(
string),
504 "alert tcp any any -> any any "
505 "(%s%scontent:\"one\"; content:\"two\"; distance:10; fast_pattern:only; sid:1;)",
506 sticky ? sticky :
"", sticky ?
"; " :
" ");
510 snprintf(
string,
sizeof(
string),
511 "alert tcp any any -> any any "
512 "(%s%scontent:\"one\"; fast_pattern:5,6; sid:1;)",
513 sticky ? sticky :
"", sticky ?
"; " :
" ");
520 static int DetectFastPatternModifierBadRules(
const char *sticky)
526 snprintf(
string,
sizeof(
string),
527 "alert tcp any any -> any any "
528 "(content:\"one\"; %s%sfast_pattern:boo; sid:1;)",
529 sticky ? sticky :
"", sticky ?
"; " :
" ");
533 snprintf(
string,
sizeof(
string),
534 "alert tcp any any -> any any "
535 "(content:\"one\"; %s%sfast_pattern:only; content:\"two\"; %s%sdistance:10; sid:1;)",
536 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ");
541 snprintf(
string,
sizeof(
string),
"alert tcp any any -> any any "
542 "(content:\"one\"; %s%s content:\"two\"; %s%sdistance:10; fast_pattern:only; sid:1;)",
543 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ");
548 snprintf(
string,
sizeof(
string),
549 "alert tcp any any -> any any "
550 "(content:\"one\"; %s%sfast_pattern:only; content:\"two\"; %s%swithin:10; sid:1;)",
551 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ");
555 snprintf(
string,
sizeof(
string),
556 "alert tcp any any -> any any "
557 "(content:\"one\"; %s%s content:\"two\"; %s%swithin:10; fast_pattern:only; sid:1;)",
558 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ");
562 snprintf(
string,
sizeof(
string),
563 "alert tcp any any -> any any "
564 "(content:\"one\"; %s%sfast_pattern:only; offset:10; sid:1;)",
565 sticky ? sticky :
"", sticky ?
"; " :
" ");
569 snprintf(
string,
sizeof(
string),
570 "alert tcp any any -> any any "
571 "(content:\"one\"; %s%s offset:10; fast_pattern:only; sid:1;)",
572 sticky ? sticky :
"", sticky ?
"; " :
" ");
576 snprintf(
string,
sizeof(
string),
577 "alert tcp any any -> any any "
578 "(content:\"one\"; %s%sfast_pattern:only; depth:10; sid:1;)",
579 sticky ? sticky :
"", sticky ?
"; " :
" ");
583 snprintf(
string,
sizeof(
string),
584 "alert tcp any any -> any any "
585 "(content:\"one\"; %s%s depth:10; fast_pattern:only; sid:1;)",
586 sticky ? sticky :
"", sticky ?
"; " :
" ");
590 snprintf(
string,
sizeof(
string),
591 "alert tcp any any -> any any "
592 "(content:\"one\"; %s%s content:!\"two\"; %s%sfast_pattern:only; sid:1;)",
593 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ");
597 snprintf(
string,
sizeof(
string),
598 "alert tcp any any -> any any "
599 "(content:\"one\"; %s%sfast_pattern:5,6; sid:1;)",
600 sticky ? sticky :
"", sticky ?
"; " :
" ");
604 snprintf(
string,
sizeof(
string),
605 "alert tcp any any -> any any "
606 "(content:\"one\"; %s%sfast_pattern:65977,2; sid:1;)",
607 sticky ? sticky :
"", sticky ?
"; " :
" ");
611 snprintf(
string,
sizeof(
string),
612 "alert tcp any any -> any any "
613 "(content:\"one\"; %s%sfast_pattern:2,65977; sid:1;)",
614 sticky ? sticky :
"", sticky ?
"; " :
" ");
618 snprintf(
string,
sizeof(
string),
619 "alert tcp any any -> any any "
620 "(content:\"one\"; %s%sfast_pattern:2,65534; sid:1;)",
621 sticky ? sticky :
"", sticky ?
"; " :
" ");
625 snprintf(
string,
sizeof(
string),
626 "alert tcp any any -> any any "
627 "(content:\"one\"; %s%sfast_pattern:65534,2; sid:1;)",
628 sticky ? sticky :
"", sticky ?
"; " :
" ");
632 snprintf(
string,
sizeof(
string),
633 "alert tcp any any -> any any "
634 "(content:\"one\"; %s%scontent:!\"two\"; fast_pattern:1,2; %s%sdistance:10; sid:1;)",
635 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ");
639 snprintf(
string,
sizeof(
string),
640 "alert tcp any any -> any any "
641 "(content:\"one\"; %s%scontent:!\"two\"; fast_pattern:1,2; %s%swithin:10; sid:1;)",
642 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ");
646 snprintf(
string,
sizeof(
string),
647 "alert tcp any any -> any any "
648 "(content:\"one\"; %s%scontent:!\"two\"; fast_pattern:1,2; %s%sdepth:10; sid:1;)",
649 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ");
653 snprintf(
string,
sizeof(
string),
654 "alert tcp any any -> any any "
655 "(content:\"one\"; %s%scontent:!\"two\"; fast_pattern:1,2; %s%soffset:10; sid:1;)",
656 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ");
663 static int DetectFastPatternStickySingleFPOnly(
const char *sticky,
const int list)
668 snprintf(
string,
sizeof(
string),
669 "alert tcp any any -> any any "
670 "(%s%scontent:\"one\"; fast_pattern:only; sid:1;)",
671 sticky ? sticky :
"", sticky ?
"; " :
" ");
685 static int DetectFastPatternModifierFPOnly(
const char *sticky,
const int list)
690 snprintf(
string,
sizeof(
string),
691 "alert tcp any any -> any any "
692 "(content:\"one\"; %s%sfast_pattern:only; sid:1;)",
693 sticky ? sticky :
"", sticky ?
"; " :
" ");
704 snprintf(
string,
sizeof(
string),
705 "alert tcp any any -> any any "
706 "(content:\"one\"; %s%scontent:\"two\"; %s%sfast_pattern:only; sid:2;)",
707 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ");
710 sm = GetMatches(s, list);
725 snprintf(
string,
sizeof(
string),
726 "alert tcp any any -> any any "
727 "(content:\"one\"; %s%scontent:\"two\"; distance:10; %s%scontent:\"three\"; "
728 "%s%sfast_pattern:only; sid:3;)",
729 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ",
730 sticky ? sticky :
"", sticky ?
"; " :
" ");
733 sm = GetMatches(s, list);
756 snprintf(
string,
sizeof(
string),
757 "alert tcp any any -> any any "
758 "(content:\"one\"; %s%scontent:\"two\"; within:10; %s%scontent:\"three\"; "
759 "%s%sfast_pattern:only; sid:4;)",
760 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ",
761 sticky ? sticky :
"", sticky ?
"; " :
" ");
764 sm = GetMatches(s, list);
787 snprintf(
string,
sizeof(
string),
788 "alert tcp any any -> any any "
789 "(content:\"one\"; %s%scontent:\"two\"; offset:10; %s%scontent:\"three\"; "
790 "%s%sfast_pattern:only; sid:5;)",
791 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ",
792 sticky ? sticky :
"", sticky ?
"; " :
" ");
795 sm = GetMatches(s, list);
818 snprintf(
string,
sizeof(
string),
819 "alert tcp any any -> any any "
820 "(content:\"one\"; %s%scontent:\"two\"; depth:10; %s%scontent:\"three\"; "
821 "%s%sfast_pattern:only; sid:6;)",
822 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ",
823 sticky ? sticky :
"", sticky ?
"; " :
" ");
826 sm = GetMatches(s, list);
849 snprintf(
string,
sizeof(
string),
850 "alert tcp any any -> any any "
851 "(content:!\"one\"; %s%sfast_pattern; content:\"two\"; depth:10; %s%ssid:7;)",
852 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ");
855 sm = GetMatches(s, list);
876 static int DetectFastPatternStickyFPChop(
const char *sticky,
const int list)
881 snprintf(
string,
sizeof(
string),
882 "alert tcp any any -> any any "
883 "(%s%scontent:\"onetwothree\"; fast_pattern:3,4; sid:1;)",
884 sticky ? sticky :
"", sticky ?
"; " :
" ");
898 snprintf(
string,
sizeof(
string),
899 "alert tcp any any -> any any "
900 "(%s%scontent:\"onetwothree\"; fast_pattern:3,4; content:\"xyz\"; distance:10; sid:2;)",
901 sticky ? sticky :
"", sticky ?
"; " :
" ");
904 sm = GetMatches(s, list);
919 static int DetectFastPatternModifierFPChop(
const char *sticky,
const int list)
924 snprintf(
string,
sizeof(
string),
925 "alert tcp any any -> any any "
926 "(content:\"onetwothree\"; %s%sfast_pattern:3,4; sid:1;)",
927 sticky ? sticky :
"", sticky ?
"; " :
" ");
941 snprintf(
string,
sizeof(
string),
942 "alert tcp any any -> any any "
943 "(content:!\"onetwothree\"; %s%sfast_pattern:3,4; sid:2;)",
944 sticky ? sticky :
"", sticky ?
"; " :
" ");
947 sm = GetMatches(s, list);
967 static int DetectFastPatternTest01(
void)
973 FAIL_IF_NOT(DetectFastPatternStickySingleBadArg(NULL));
974 FAIL_IF_NOT(DetectFastPatternModifierBadRules(NULL));
981 const char *buffer_name;
983 const char *mod_name;
985 {
"file_data",
"file.data", NULL },
986 {
"http_uri",
"http.uri",
"http_uri" },
987 {
"http_raw_uri",
"http.uri.raw",
"http_raw_uri" },
988 {
"http_user_agent",
"http.user_agent",
"http_user_agent" },
989 {
"http_header",
"http.header",
"http_header" },
992 {
"http_method",
"http.method",
"http_method" },
993 {
"http_cookie",
"http.cookie",
"http_cookie" },
994 {
"http_host",
"http.host",
"http_host" },
995 {
"http_raw_host",
"http.host.raw",
"http_raw_host" },
996 {
"http_stat_code",
"http.stat_code",
"http_stat_code" },
997 {
"http_stat_msg",
"http.stat_msg",
"http_stat_msg" },
998 {
"http_client_body",
"http.request_body",
"http_client_body" },
999 { NULL, NULL, NULL },
1002 for (
int i = 0; keywords[i].buffer_name != NULL; i++) {
1006 const char *k = keywords[i].sb_name;
1008 FAIL_IF_NOT(DetectFastPatternStickySingle(k, list_id));
1009 FAIL_IF_NOT(DetectFastPatternStickySingleNoFP(k, list_id));
1010 FAIL_IF_NOT(DetectFastPatternStickySingleBadArg(k));
1011 FAIL_IF_NOT(DetectFastPatternStickySingleFPOnly(k, list_id));
1012 FAIL_IF_NOT(DetectFastPatternStickyFPChop(k, list_id));
1014 k = keywords[i].mod_name;
1016 FAIL_IF_NOT(DetectFastPatternModifierSingle(k, list_id));
1017 FAIL_IF_NOT(DetectFastPatternModifierSingleNoFP(k, list_id));
1018 FAIL_IF_NOT(DetectFastPatternModifierBadRules(k));
1019 FAIL_IF_NOT(DetectFastPatternModifierFPOnly(k, list_id));
1020 FAIL_IF_NOT(DetectFastPatternModifierFPChop(k, list_id));
1032 static int DetectFastPatternTest14(
void)
1034 uint8_t *buf = (uint8_t *)
"Dummy is our name. Oh yes. From right here "
1035 "right now, all the way to hangover. right. strings5_imp now here "
1036 "comes our dark knight strings_string5. Yes here is our dark knight";
1037 uint16_t buflen = strlen((
char *)buf);
1053 "alert tcp any any -> any any "
1054 "(msg:\"fast_pattern test\"; content:\"strings_string5\"; content:\"knight\"; "
1055 "fast_pattern; sid:1;)");
1059 "alert tcp any any -> any any "
1060 "(msg:\"test different content\"; content:\"Dummy is our name\"; sid:2;)");
1085 static int DetectFastPatternTest671(
void)
1093 de_ctx,
"alert tcp any any -> any any (content:\"onetwothreefour\"; sid:1;)");
1096 de_ctx,
"alert tcp any any -> any any (content:\"onetwothreefour\"; sid:2;)");
1099 de_ctx,
"alert tcp any any -> any any (content:\"uniquepattern\"; sid:3;)");
1102 "alert tcp any any -> any any (content:\"onetwothreefour\"; fast_pattern:3,5; sid:4;)");
1105 de_ctx,
"alert tcp any any -> any any (content:\"twoth\"; sid:5;)");
1108 "alert tcp any any -> any any (content:\"onetwothreefour\"; fast_pattern:0,15; "
1142 static int DetectFastPatternPrefilter(
void)
1146 const char *
string =
"alert tcp any any -> any any "
1147 "(content:\"one\"; prefilter; sid:1;)";
1160 static void DetectFastPatternRegisterTests(
void)
1162 UtRegisterTest(
"DetectFastPatternTest01", DetectFastPatternTest01);
1163 UtRegisterTest(
"DetectFastPatternTest14", DetectFastPatternTest14);
1170 UtRegisterTest(
"DetectFastPatternTest671", DetectFastPatternTest671);
1172 UtRegisterTest(
"DetectFastPatternPrefilter", DetectFastPatternPrefilter);