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");
323 (
const char *)arg_substr) < 0) {
330 pcre2len =
sizeof(arg_substr);
331 res = pcre2_substring_copy_bynumber(match, 3, (PCRE2_UCHAR8 *)arg_substr, &pcre2len);
333 SCLogError(
"pcre2_substring_copy_bynumber failed "
334 "for fast_pattern offset");
339 (
const char *)arg_substr) < 0) {
347 if (
offset > (65535 - length)) {
349 "exceeds limit pattern length limit");
355 "offset (%u)) exceeds pattern length (%u)",
365 SCLogError(
"parse error, ret %" PRId32
", string %s", ret, arg);
371 pcre2_match_data_free(match);
376 pcre2_match_data_free(match);
395 static int DetectFastPatternStickySingle(
const char *sticky,
const int list)
400 snprintf(
string,
sizeof(
string),
401 "alert tcp any any -> any any "
402 "(%s%scontent:\"one\"; fast_pattern; sid:1;)",
403 sticky ? sticky :
"", sticky ?
"; " :
" ");
416 static int DetectFastPatternModifierSingle(
const char *sticky,
const int list)
421 snprintf(
string,
sizeof(
string),
422 "alert tcp any any -> any any "
423 "(content:\"one\"; %s%sfast_pattern; sid:1;)",
424 sticky ? sticky :
"", sticky ?
"; " :
" ");
437 static int DetectFastPatternStickySingleNoFP(
const char *sticky,
const int list)
442 snprintf(
string,
sizeof(
string),
443 "alert tcp any any -> any any "
444 "(%s%scontent:\"one\"; sid:1;)",
445 sticky ? sticky :
"", sticky ?
"; " :
" ");
458 static int DetectFastPatternModifierSingleNoFP(
const char *sticky,
const int list)
463 snprintf(
string,
sizeof(
string),
464 "alert tcp any any -> any any "
465 "(content:\"one\"; %s%ssid:1;)",
466 sticky ? sticky :
"", sticky ?
"; " :
" ");
479 static int DetectFastPatternStickySingleBadArg(
const char *sticky)
485 snprintf(
string,
sizeof(
string),
486 "alert tcp any any -> any any "
487 "(%s%scontent:\"one\"; fast_pattern:boo; sid:1;)",
488 sticky ? sticky :
"", sticky ?
"; " :
" ");
492 snprintf(
string,
sizeof(
string),
493 "alert tcp any any -> any any "
494 "(%s%scontent:\"one\"; fast_pattern:only; content:\"two\"; distance:10; sid:1;)",
495 sticky ? sticky :
"", sticky ?
"; " :
" ");
499 snprintf(
string,
sizeof(
string),
500 "alert tcp any any -> any any "
501 "(%s%scontent:\"one\"; content:\"two\"; fast_pattern:only; distance:10; sid:1;)",
502 sticky ? sticky :
"", sticky ?
"; " :
" ");
506 snprintf(
string,
sizeof(
string),
507 "alert tcp any any -> any any "
508 "(%s%scontent:\"one\"; content:\"two\"; distance:10; fast_pattern:only; sid:1;)",
509 sticky ? sticky :
"", sticky ?
"; " :
" ");
513 snprintf(
string,
sizeof(
string),
514 "alert tcp any any -> any any "
515 "(%s%scontent:\"one\"; fast_pattern:5,6; sid:1;)",
516 sticky ? sticky :
"", sticky ?
"; " :
" ");
523 static int DetectFastPatternModifierBadRules(
const char *sticky)
529 snprintf(
string,
sizeof(
string),
530 "alert tcp any any -> any any "
531 "(content:\"one\"; %s%sfast_pattern:boo; sid:1;)",
532 sticky ? sticky :
"", sticky ?
"; " :
" ");
536 snprintf(
string,
sizeof(
string),
537 "alert tcp any any -> any any "
538 "(content:\"one\"; %s%sfast_pattern:only; content:\"two\"; %s%sdistance:10; sid:1;)",
539 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ");
544 snprintf(
string,
sizeof(
string),
"alert tcp any any -> any any "
545 "(content:\"one\"; %s%s content:\"two\"; %s%sdistance:10; fast_pattern:only; sid:1;)",
546 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ");
551 snprintf(
string,
sizeof(
string),
552 "alert tcp any any -> any any "
553 "(content:\"one\"; %s%sfast_pattern:only; content:\"two\"; %s%swithin:10; sid:1;)",
554 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ");
558 snprintf(
string,
sizeof(
string),
559 "alert tcp any any -> any any "
560 "(content:\"one\"; %s%s content:\"two\"; %s%swithin:10; fast_pattern:only; sid:1;)",
561 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ");
565 snprintf(
string,
sizeof(
string),
566 "alert tcp any any -> any any "
567 "(content:\"one\"; %s%sfast_pattern:only; offset:10; sid:1;)",
568 sticky ? sticky :
"", sticky ?
"; " :
" ");
572 snprintf(
string,
sizeof(
string),
573 "alert tcp any any -> any any "
574 "(content:\"one\"; %s%s offset:10; fast_pattern:only; sid:1;)",
575 sticky ? sticky :
"", sticky ?
"; " :
" ");
579 snprintf(
string,
sizeof(
string),
580 "alert tcp any any -> any any "
581 "(content:\"one\"; %s%sfast_pattern:only; depth:10; sid:1;)",
582 sticky ? sticky :
"", sticky ?
"; " :
" ");
586 snprintf(
string,
sizeof(
string),
587 "alert tcp any any -> any any "
588 "(content:\"one\"; %s%s depth:10; fast_pattern:only; sid:1;)",
589 sticky ? sticky :
"", sticky ?
"; " :
" ");
593 snprintf(
string,
sizeof(
string),
594 "alert tcp any any -> any any "
595 "(content:\"one\"; %s%s content:!\"two\"; %s%sfast_pattern:only; sid:1;)",
596 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ");
600 snprintf(
string,
sizeof(
string),
601 "alert tcp any any -> any any "
602 "(content:\"one\"; %s%sfast_pattern:5,6; sid:1;)",
603 sticky ? sticky :
"", sticky ?
"; " :
" ");
607 snprintf(
string,
sizeof(
string),
608 "alert tcp any any -> any any "
609 "(content:\"one\"; %s%sfast_pattern:65977,2; sid:1;)",
610 sticky ? sticky :
"", sticky ?
"; " :
" ");
614 snprintf(
string,
sizeof(
string),
615 "alert tcp any any -> any any "
616 "(content:\"one\"; %s%sfast_pattern:2,65977; sid:1;)",
617 sticky ? sticky :
"", sticky ?
"; " :
" ");
621 snprintf(
string,
sizeof(
string),
622 "alert tcp any any -> any any "
623 "(content:\"one\"; %s%sfast_pattern:2,65534; sid:1;)",
624 sticky ? sticky :
"", sticky ?
"; " :
" ");
628 snprintf(
string,
sizeof(
string),
629 "alert tcp any any -> any any "
630 "(content:\"one\"; %s%sfast_pattern:65534,2; sid:1;)",
631 sticky ? sticky :
"", sticky ?
"; " :
" ");
635 snprintf(
string,
sizeof(
string),
636 "alert tcp any any -> any any "
637 "(content:\"one\"; %s%scontent:!\"two\"; fast_pattern:1,2; %s%sdistance:10; sid:1;)",
638 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ");
642 snprintf(
string,
sizeof(
string),
643 "alert tcp any any -> any any "
644 "(content:\"one\"; %s%scontent:!\"two\"; fast_pattern:1,2; %s%swithin:10; sid:1;)",
645 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ");
649 snprintf(
string,
sizeof(
string),
650 "alert tcp any any -> any any "
651 "(content:\"one\"; %s%scontent:!\"two\"; fast_pattern:1,2; %s%sdepth:10; sid:1;)",
652 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ");
656 snprintf(
string,
sizeof(
string),
657 "alert tcp any any -> any any "
658 "(content:\"one\"; %s%scontent:!\"two\"; fast_pattern:1,2; %s%soffset:10; sid:1;)",
659 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ");
666 static int DetectFastPatternStickySingleFPOnly(
const char *sticky,
const int list)
671 snprintf(
string,
sizeof(
string),
672 "alert tcp any any -> any any "
673 "(%s%scontent:\"one\"; fast_pattern:only; sid:1;)",
674 sticky ? sticky :
"", sticky ?
"; " :
" ");
688 static int DetectFastPatternModifierFPOnly(
const char *sticky,
const int list)
693 snprintf(
string,
sizeof(
string),
694 "alert tcp any any -> any any "
695 "(content:\"one\"; %s%sfast_pattern:only; sid:1;)",
696 sticky ? sticky :
"", sticky ?
"; " :
" ");
707 snprintf(
string,
sizeof(
string),
708 "alert tcp any any -> any any "
709 "(content:\"one\"; %s%scontent:\"two\"; %s%sfast_pattern:only; sid:2;)",
710 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ");
713 sm = GetMatches(s, list);
728 snprintf(
string,
sizeof(
string),
729 "alert tcp any any -> any any "
730 "(content:\"one\"; %s%scontent:\"two\"; distance:10; %s%scontent:\"three\"; "
731 "%s%sfast_pattern:only; sid:3;)",
732 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ",
733 sticky ? sticky :
"", sticky ?
"; " :
" ");
736 sm = GetMatches(s, list);
759 snprintf(
string,
sizeof(
string),
760 "alert tcp any any -> any any "
761 "(content:\"one\"; %s%scontent:\"two\"; within:10; %s%scontent:\"three\"; "
762 "%s%sfast_pattern:only; sid:4;)",
763 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ",
764 sticky ? sticky :
"", sticky ?
"; " :
" ");
767 sm = GetMatches(s, list);
790 snprintf(
string,
sizeof(
string),
791 "alert tcp any any -> any any "
792 "(content:\"one\"; %s%scontent:\"two\"; offset:10; %s%scontent:\"three\"; "
793 "%s%sfast_pattern:only; sid:5;)",
794 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ",
795 sticky ? sticky :
"", sticky ?
"; " :
" ");
798 sm = GetMatches(s, list);
821 snprintf(
string,
sizeof(
string),
822 "alert tcp any any -> any any "
823 "(content:\"one\"; %s%scontent:\"two\"; depth:10; %s%scontent:\"three\"; "
824 "%s%sfast_pattern:only; sid:6;)",
825 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ",
826 sticky ? sticky :
"", sticky ?
"; " :
" ");
829 sm = GetMatches(s, list);
852 snprintf(
string,
sizeof(
string),
853 "alert tcp any any -> any any "
854 "(content:!\"one\"; %s%sfast_pattern; content:\"two\"; depth:10; %s%ssid:7;)",
855 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ");
858 sm = GetMatches(s, list);
879 static int DetectFastPatternStickyFPChop(
const char *sticky,
const int list)
884 snprintf(
string,
sizeof(
string),
885 "alert tcp any any -> any any "
886 "(%s%scontent:\"onetwothree\"; fast_pattern:3,4; sid:1;)",
887 sticky ? sticky :
"", sticky ?
"; " :
" ");
901 snprintf(
string,
sizeof(
string),
902 "alert tcp any any -> any any "
903 "(%s%scontent:\"onetwothree\"; fast_pattern:3,4; content:\"xyz\"; distance:10; sid:2;)",
904 sticky ? sticky :
"", sticky ?
"; " :
" ");
907 sm = GetMatches(s, list);
922 static int DetectFastPatternModifierFPChop(
const char *sticky,
const int list)
927 snprintf(
string,
sizeof(
string),
928 "alert tcp any any -> any any "
929 "(content:\"onetwothree\"; %s%sfast_pattern:3,4; sid:1;)",
930 sticky ? sticky :
"", sticky ?
"; " :
" ");
944 snprintf(
string,
sizeof(
string),
945 "alert tcp any any -> any any "
946 "(content:!\"onetwothree\"; %s%sfast_pattern:3,4; sid:2;)",
947 sticky ? sticky :
"", sticky ?
"; " :
" ");
950 sm = GetMatches(s, list);
970 static int DetectFastPatternTest01(
void)
976 FAIL_IF_NOT(DetectFastPatternStickySingleBadArg(NULL));
977 FAIL_IF_NOT(DetectFastPatternModifierBadRules(NULL));
984 const char *buffer_name;
986 const char *mod_name;
988 {
"file_data",
"file.data", NULL },
989 {
"http_uri",
"http.uri",
"http_uri" },
990 {
"http_raw_uri",
"http.uri.raw",
"http_raw_uri" },
991 {
"http_user_agent",
"http.user_agent",
"http_user_agent" },
992 {
"http_header",
"http.header",
"http_header" },
995 {
"http_method",
"http.method",
"http_method" },
996 {
"http_cookie",
"http.cookie",
"http_cookie" },
997 {
"http_host",
"http.host",
"http_host" },
998 {
"http_raw_host",
"http.host.raw",
"http_raw_host" },
999 {
"http_stat_code",
"http.stat_code",
"http_stat_code" },
1000 {
"http_stat_msg",
"http.stat_msg",
"http_stat_msg" },
1001 {
"http_client_body",
"http.request_body",
"http_client_body" },
1002 { NULL, NULL, NULL },
1005 for (
int i = 0; keywords[i].buffer_name != NULL; i++) {
1009 const char *k = keywords[i].sb_name;
1011 FAIL_IF_NOT(DetectFastPatternStickySingle(k, list_id));
1012 FAIL_IF_NOT(DetectFastPatternStickySingleNoFP(k, list_id));
1013 FAIL_IF_NOT(DetectFastPatternStickySingleBadArg(k));
1014 FAIL_IF_NOT(DetectFastPatternStickySingleFPOnly(k, list_id));
1015 FAIL_IF_NOT(DetectFastPatternStickyFPChop(k, list_id));
1017 k = keywords[i].mod_name;
1019 FAIL_IF_NOT(DetectFastPatternModifierSingle(k, list_id));
1020 FAIL_IF_NOT(DetectFastPatternModifierSingleNoFP(k, list_id));
1021 FAIL_IF_NOT(DetectFastPatternModifierBadRules(k));
1022 FAIL_IF_NOT(DetectFastPatternModifierFPOnly(k, list_id));
1023 FAIL_IF_NOT(DetectFastPatternModifierFPChop(k, list_id));
1035 static int DetectFastPatternTest14(
void)
1037 uint8_t *buf = (uint8_t *)
"Dummy is our name. Oh yes. From right here "
1038 "right now, all the way to hangover. right. strings5_imp now here "
1039 "comes our dark knight strings_string5. Yes here is our dark knight";
1040 uint16_t buflen = strlen((
char *)buf);
1044 memset(&th_v, 0,
sizeof(th_v));
1055 "alert tcp any any -> any any "
1056 "(msg:\"fast_pattern test\"; content:\"strings_string5\"; content:\"knight\"; "
1057 "fast_pattern; sid:1;)");
1061 "alert tcp any any -> any any "
1062 "(msg:\"test different content\"; content:\"Dummy is our name\"; sid:2;)");
1086 static int DetectFastPatternTest671(
void)
1094 de_ctx,
"alert tcp any any -> any any (content:\"onetwothreefour\"; sid:1;)");
1097 de_ctx,
"alert tcp any any -> any any (content:\"onetwothreefour\"; sid:2;)");
1100 de_ctx,
"alert tcp any any -> any any (content:\"uniquepattern\"; sid:3;)");
1103 "alert tcp any any -> any any (content:\"onetwothreefour\"; fast_pattern:3,5; sid:4;)");
1106 de_ctx,
"alert tcp any any -> any any (content:\"twoth\"; sid:5;)");
1109 "alert tcp any any -> any any (content:\"onetwothreefour\"; fast_pattern:0,15; "
1143 static int DetectFastPatternPrefilter(
void)
1147 const char *
string =
"alert tcp any any -> any any "
1148 "(content:\"one\"; prefilter; sid:1;)";
1161 static void DetectFastPatternRegisterTests(
void)
1163 UtRegisterTest(
"DetectFastPatternTest01", DetectFastPatternTest01);
1164 UtRegisterTest(
"DetectFastPatternTest14", DetectFastPatternTest14);
1171 UtRegisterTest(
"DetectFastPatternTest671", DetectFastPatternTest671);
1173 UtRegisterTest(
"DetectFastPatternPrefilter", DetectFastPatternPrefilter);