42 #define PARSE_REGEX "^(\\s*only\\s*)|\\s*([0-9]+)\\s*,\\s*([0-9]+)\\s*$"
48 static void DetectFastPatternRegisterTests(
void);
82 if (list_id == tmp->list_id) {
91 if (priority < tmp->priority)
101 new->list_id = list_id;
102 new->priority = priority;
111 new->list_id = list_id;
112 new->priority = priority;
131 Add(&g_fp_support_smlist_list, list_id, priority);
155 FatalError(
"out of memory: %s", strerror(errno));
215 char arg_substr[128] =
"";
217 pcre2_match_data *match = NULL;
221 if (pm1 == NULL && pm2 == NULL) {
223 "the rule, without a content context. Please use a "
224 "content based keyword before using fast_pattern");
234 }
else if (pm1 && !pm2) {
243 SCLogError(
"fast_pattern cannot be used on to_client keyword for "
244 "transactional rule with a streaming buffer to server %u",
261 "used with negated content, along with relative modifiers");
265 if (arg == NULL|| strcmp(arg,
"") == 0) {
268 "options for the same content");
279 "can be used on only one content in a rule");
287 SCLogError(
"fast_pattern cannot be used with base64_data");
306 "used with negated content or with any of the relative "
307 "modifiers like distance, within, offset, depth");
313 }
else if (ret == 4) {
314 pcre2len =
sizeof(arg_substr);
315 res = pcre2_substring_copy_bynumber(match, 2, (PCRE2_UCHAR8 *)arg_substr, &pcre2len);
317 SCLogError(
"pcre2_substring_copy_bynumber failed "
318 "for fast_pattern offset");
329 pcre2len =
sizeof(arg_substr);
330 res = pcre2_substring_copy_bynumber(match, 3, (PCRE2_UCHAR8 *)arg_substr, &pcre2len);
332 SCLogError(
"pcre2_substring_copy_bynumber failed "
333 "for fast_pattern offset");
345 if (
offset > (65535 - length)) {
347 "exceeds limit pattern length limit");
353 "offset (%u)) exceeds pattern length (%u)",
363 SCLogError(
"parse error, ret %" PRId32
", string %s", ret, arg);
369 pcre2_match_data_free(match);
374 pcre2_match_data_free(match);
393 static int DetectFastPatternStickySingle(
const char *sticky,
const int list)
398 snprintf(
string,
sizeof(
string),
399 "alert tcp any any -> any any "
400 "(%s%scontent:\"one\"; fast_pattern; sid:1;)",
401 sticky ? sticky :
"", sticky ?
"; " :
" ");
414 static int DetectFastPatternModifierSingle(
const char *sticky,
const int list)
419 snprintf(
string,
sizeof(
string),
420 "alert tcp any any -> any any "
421 "(content:\"one\"; %s%sfast_pattern; sid:1;)",
422 sticky ? sticky :
"", sticky ?
"; " :
" ");
435 static int DetectFastPatternStickySingleNoFP(
const char *sticky,
const int list)
440 snprintf(
string,
sizeof(
string),
441 "alert tcp any any -> any any "
442 "(%s%scontent:\"one\"; sid:1;)",
443 sticky ? sticky :
"", sticky ?
"; " :
" ");
456 static int DetectFastPatternModifierSingleNoFP(
const char *sticky,
const int list)
461 snprintf(
string,
sizeof(
string),
462 "alert tcp any any -> any any "
463 "(content:\"one\"; %s%ssid:1;)",
464 sticky ? sticky :
"", sticky ?
"; " :
" ");
477 static int DetectFastPatternStickySingleBadArg(
const char *sticky)
483 snprintf(
string,
sizeof(
string),
484 "alert tcp any any -> any any "
485 "(%s%scontent:\"one\"; fast_pattern:boo; sid:1;)",
486 sticky ? sticky :
"", sticky ?
"; " :
" ");
490 snprintf(
string,
sizeof(
string),
491 "alert tcp any any -> any any "
492 "(%s%scontent:\"one\"; fast_pattern:only; content:\"two\"; distance:10; sid:1;)",
493 sticky ? sticky :
"", sticky ?
"; " :
" ");
497 snprintf(
string,
sizeof(
string),
498 "alert tcp any any -> any any "
499 "(%s%scontent:\"one\"; content:\"two\"; fast_pattern:only; distance:10; sid:1;)",
500 sticky ? sticky :
"", sticky ?
"; " :
" ");
504 snprintf(
string,
sizeof(
string),
505 "alert tcp any any -> any any "
506 "(%s%scontent:\"one\"; content:\"two\"; distance:10; fast_pattern:only; sid:1;)",
507 sticky ? sticky :
"", sticky ?
"; " :
" ");
511 snprintf(
string,
sizeof(
string),
512 "alert tcp any any -> any any "
513 "(%s%scontent:\"one\"; fast_pattern:5,6; sid:1;)",
514 sticky ? sticky :
"", sticky ?
"; " :
" ");
521 static int DetectFastPatternModifierBadRules(
const char *sticky)
527 snprintf(
string,
sizeof(
string),
528 "alert tcp any any -> any any "
529 "(content:\"one\"; %s%sfast_pattern:boo; sid:1;)",
530 sticky ? sticky :
"", sticky ?
"; " :
" ");
534 snprintf(
string,
sizeof(
string),
535 "alert tcp any any -> any any "
536 "(content:\"one\"; %s%sfast_pattern:only; content:\"two\"; %s%sdistance:10; sid:1;)",
537 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ");
542 snprintf(
string,
sizeof(
string),
"alert tcp any any -> any any "
543 "(content:\"one\"; %s%s content:\"two\"; %s%sdistance:10; fast_pattern:only; sid:1;)",
544 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ");
549 snprintf(
string,
sizeof(
string),
550 "alert tcp any any -> any any "
551 "(content:\"one\"; %s%sfast_pattern:only; content:\"two\"; %s%swithin:10; sid:1;)",
552 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ");
556 snprintf(
string,
sizeof(
string),
557 "alert tcp any any -> any any "
558 "(content:\"one\"; %s%s content:\"two\"; %s%swithin:10; fast_pattern:only; sid:1;)",
559 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ");
563 snprintf(
string,
sizeof(
string),
564 "alert tcp any any -> any any "
565 "(content:\"one\"; %s%sfast_pattern:only; offset:10; sid:1;)",
566 sticky ? sticky :
"", sticky ?
"; " :
" ");
570 snprintf(
string,
sizeof(
string),
571 "alert tcp any any -> any any "
572 "(content:\"one\"; %s%s offset:10; fast_pattern:only; sid:1;)",
573 sticky ? sticky :
"", sticky ?
"; " :
" ");
577 snprintf(
string,
sizeof(
string),
578 "alert tcp any any -> any any "
579 "(content:\"one\"; %s%sfast_pattern:only; depth:10; sid:1;)",
580 sticky ? sticky :
"", sticky ?
"; " :
" ");
584 snprintf(
string,
sizeof(
string),
585 "alert tcp any any -> any any "
586 "(content:\"one\"; %s%s depth:10; fast_pattern:only; sid:1;)",
587 sticky ? sticky :
"", sticky ?
"; " :
" ");
591 snprintf(
string,
sizeof(
string),
592 "alert tcp any any -> any any "
593 "(content:\"one\"; %s%s content:!\"two\"; %s%sfast_pattern:only; sid:1;)",
594 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ");
598 snprintf(
string,
sizeof(
string),
599 "alert tcp any any -> any any "
600 "(content:\"one\"; %s%sfast_pattern:5,6; sid:1;)",
601 sticky ? sticky :
"", sticky ?
"; " :
" ");
605 snprintf(
string,
sizeof(
string),
606 "alert tcp any any -> any any "
607 "(content:\"one\"; %s%sfast_pattern:65977,2; sid:1;)",
608 sticky ? sticky :
"", sticky ?
"; " :
" ");
612 snprintf(
string,
sizeof(
string),
613 "alert tcp any any -> any any "
614 "(content:\"one\"; %s%sfast_pattern:2,65977; sid:1;)",
615 sticky ? sticky :
"", sticky ?
"; " :
" ");
619 snprintf(
string,
sizeof(
string),
620 "alert tcp any any -> any any "
621 "(content:\"one\"; %s%sfast_pattern:2,65534; sid:1;)",
622 sticky ? sticky :
"", sticky ?
"; " :
" ");
626 snprintf(
string,
sizeof(
string),
627 "alert tcp any any -> any any "
628 "(content:\"one\"; %s%sfast_pattern:65534,2; sid:1;)",
629 sticky ? sticky :
"", sticky ?
"; " :
" ");
633 snprintf(
string,
sizeof(
string),
634 "alert tcp any any -> any any "
635 "(content:\"one\"; %s%scontent:!\"two\"; fast_pattern:1,2; %s%sdistance:10; sid:1;)",
636 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ");
640 snprintf(
string,
sizeof(
string),
641 "alert tcp any any -> any any "
642 "(content:\"one\"; %s%scontent:!\"two\"; fast_pattern:1,2; %s%swithin:10; sid:1;)",
643 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ");
647 snprintf(
string,
sizeof(
string),
648 "alert tcp any any -> any any "
649 "(content:\"one\"; %s%scontent:!\"two\"; fast_pattern:1,2; %s%sdepth:10; sid:1;)",
650 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ");
654 snprintf(
string,
sizeof(
string),
655 "alert tcp any any -> any any "
656 "(content:\"one\"; %s%scontent:!\"two\"; fast_pattern:1,2; %s%soffset:10; sid:1;)",
657 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ");
664 static int DetectFastPatternStickySingleFPOnly(
const char *sticky,
const int list)
669 snprintf(
string,
sizeof(
string),
670 "alert tcp any any -> any any "
671 "(%s%scontent:\"one\"; fast_pattern:only; sid:1;)",
672 sticky ? sticky :
"", sticky ?
"; " :
" ");
686 static int DetectFastPatternModifierFPOnly(
const char *sticky,
const int list)
691 snprintf(
string,
sizeof(
string),
692 "alert tcp any any -> any any "
693 "(content:\"one\"; %s%sfast_pattern:only; sid:1;)",
694 sticky ? sticky :
"", sticky ?
"; " :
" ");
705 snprintf(
string,
sizeof(
string),
706 "alert tcp any any -> any any "
707 "(content:\"one\"; %s%scontent:\"two\"; %s%sfast_pattern:only; sid:2;)",
708 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ");
711 sm = GetMatches(s, list);
726 snprintf(
string,
sizeof(
string),
727 "alert tcp any any -> any any "
728 "(content:\"one\"; %s%scontent:\"two\"; distance:10; %s%scontent:\"three\"; "
729 "%s%sfast_pattern:only; sid:3;)",
730 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ",
731 sticky ? sticky :
"", sticky ?
"; " :
" ");
734 sm = GetMatches(s, list);
757 snprintf(
string,
sizeof(
string),
758 "alert tcp any any -> any any "
759 "(content:\"one\"; %s%scontent:\"two\"; within:10; %s%scontent:\"three\"; "
760 "%s%sfast_pattern:only; sid:4;)",
761 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ",
762 sticky ? sticky :
"", sticky ?
"; " :
" ");
765 sm = GetMatches(s, list);
788 snprintf(
string,
sizeof(
string),
789 "alert tcp any any -> any any "
790 "(content:\"one\"; %s%scontent:\"two\"; offset:10; %s%scontent:\"three\"; "
791 "%s%sfast_pattern:only; sid:5;)",
792 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ",
793 sticky ? sticky :
"", sticky ?
"; " :
" ");
796 sm = GetMatches(s, list);
819 snprintf(
string,
sizeof(
string),
820 "alert tcp any any -> any any "
821 "(content:\"one\"; %s%scontent:\"two\"; depth:10; %s%scontent:\"three\"; "
822 "%s%sfast_pattern:only; sid:6;)",
823 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ",
824 sticky ? sticky :
"", sticky ?
"; " :
" ");
827 sm = GetMatches(s, list);
850 snprintf(
string,
sizeof(
string),
851 "alert tcp any any -> any any "
852 "(content:!\"one\"; %s%sfast_pattern; content:\"two\"; depth:10; %s%ssid:7;)",
853 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ");
856 sm = GetMatches(s, list);
877 static int DetectFastPatternStickyFPChop(
const char *sticky,
const int list)
882 snprintf(
string,
sizeof(
string),
883 "alert tcp any any -> any any "
884 "(%s%scontent:\"onetwothree\"; fast_pattern:3,4; sid:1;)",
885 sticky ? sticky :
"", sticky ?
"; " :
" ");
899 snprintf(
string,
sizeof(
string),
900 "alert tcp any any -> any any "
901 "(%s%scontent:\"onetwothree\"; fast_pattern:3,4; content:\"xyz\"; distance:10; sid:2;)",
902 sticky ? sticky :
"", sticky ?
"; " :
" ");
905 sm = GetMatches(s, list);
920 static int DetectFastPatternModifierFPChop(
const char *sticky,
const int list)
925 snprintf(
string,
sizeof(
string),
926 "alert tcp any any -> any any "
927 "(content:\"onetwothree\"; %s%sfast_pattern:3,4; sid:1;)",
928 sticky ? sticky :
"", sticky ?
"; " :
" ");
942 snprintf(
string,
sizeof(
string),
943 "alert tcp any any -> any any "
944 "(content:!\"onetwothree\"; %s%sfast_pattern:3,4; sid:2;)",
945 sticky ? sticky :
"", sticky ?
"; " :
" ");
948 sm = GetMatches(s, list);
968 static int DetectFastPatternTest01(
void)
974 FAIL_IF_NOT(DetectFastPatternStickySingleBadArg(NULL));
975 FAIL_IF_NOT(DetectFastPatternModifierBadRules(NULL));
982 const char *buffer_name;
984 const char *mod_name;
986 {
"file_data",
"file.data", NULL },
987 {
"http_uri",
"http.uri",
"http_uri" },
988 {
"http_raw_uri",
"http.uri.raw",
"http_raw_uri" },
989 {
"http_user_agent",
"http.user_agent",
"http_user_agent" },
990 {
"http_header",
"http.header",
"http_header" },
993 {
"http_method",
"http.method",
"http_method" },
994 {
"http_cookie",
"http.cookie",
"http_cookie" },
995 {
"http_host",
"http.host",
"http_host" },
996 {
"http_raw_host",
"http.host.raw",
"http_raw_host" },
997 {
"http_stat_code",
"http.stat_code",
"http_stat_code" },
998 {
"http_stat_msg",
"http.stat_msg",
"http_stat_msg" },
999 {
"http_client_body",
"http.request_body",
"http_client_body" },
1000 { NULL, NULL, NULL },
1003 for (
int i = 0; keywords[i].buffer_name != NULL; i++) {
1007 const char *k = keywords[i].sb_name;
1009 FAIL_IF_NOT(DetectFastPatternStickySingle(k, list_id));
1010 FAIL_IF_NOT(DetectFastPatternStickySingleNoFP(k, list_id));
1011 FAIL_IF_NOT(DetectFastPatternStickySingleBadArg(k));
1012 FAIL_IF_NOT(DetectFastPatternStickySingleFPOnly(k, list_id));
1013 FAIL_IF_NOT(DetectFastPatternStickyFPChop(k, list_id));
1015 k = keywords[i].mod_name;
1017 FAIL_IF_NOT(DetectFastPatternModifierSingle(k, list_id));
1018 FAIL_IF_NOT(DetectFastPatternModifierSingleNoFP(k, list_id));
1019 FAIL_IF_NOT(DetectFastPatternModifierBadRules(k));
1020 FAIL_IF_NOT(DetectFastPatternModifierFPOnly(k, list_id));
1021 FAIL_IF_NOT(DetectFastPatternModifierFPChop(k, list_id));
1033 static int DetectFastPatternTest14(
void)
1035 uint8_t *buf = (uint8_t *)
"Dummy is our name. Oh yes. From right here "
1036 "right now, all the way to hangover. right. strings5_imp now here "
1037 "comes our dark knight strings_string5. Yes here is our dark knight";
1038 uint16_t buflen = strlen((
char *)buf);
1042 memset(&th_v, 0,
sizeof(th_v));
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;)");
1084 static int DetectFastPatternTest671(
void)
1092 de_ctx,
"alert tcp any any -> any any (content:\"onetwothreefour\"; sid:1;)");
1095 de_ctx,
"alert tcp any any -> any any (content:\"onetwothreefour\"; sid:2;)");
1098 de_ctx,
"alert tcp any any -> any any (content:\"uniquepattern\"; sid:3;)");
1101 "alert tcp any any -> any any (content:\"onetwothreefour\"; fast_pattern:3,5; sid:4;)");
1104 de_ctx,
"alert tcp any any -> any any (content:\"twoth\"; sid:5;)");
1107 "alert tcp any any -> any any (content:\"onetwothreefour\"; fast_pattern:0,15; "
1141 static int DetectFastPatternPrefilter(
void)
1145 const char *
string =
"alert tcp any any -> any any "
1146 "(content:\"one\"; prefilter; sid:1;)";
1159 static void DetectFastPatternRegisterTests(
void)
1161 UtRegisterTest(
"DetectFastPatternTest01", DetectFastPatternTest01);
1162 UtRegisterTest(
"DetectFastPatternTest14", DetectFastPatternTest14);
1169 UtRegisterTest(
"DetectFastPatternTest671", DetectFastPatternTest671);
1171 UtRegisterTest(
"DetectFastPatternPrefilter", DetectFastPatternPrefilter);