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);
394 static int DetectFastPatternStickySingle(
const char *sticky,
const int list)
399 snprintf(
string,
sizeof(
string),
400 "alert tcp any any -> any any "
401 "(%s%scontent:\"one\"; fast_pattern; sid:1;)",
402 sticky ? sticky :
"", sticky ?
"; " :
" ");
415 static int DetectFastPatternModifierSingle(
const char *sticky,
const int list)
420 snprintf(
string,
sizeof(
string),
421 "alert tcp any any -> any any "
422 "(content:\"one\"; %s%sfast_pattern; sid:1;)",
423 sticky ? sticky :
"", sticky ?
"; " :
" ");
436 static int DetectFastPatternStickySingleNoFP(
const char *sticky,
const int list)
441 snprintf(
string,
sizeof(
string),
442 "alert tcp any any -> any any "
443 "(%s%scontent:\"one\"; sid:1;)",
444 sticky ? sticky :
"", sticky ?
"; " :
" ");
457 static int DetectFastPatternModifierSingleNoFP(
const char *sticky,
const int list)
462 snprintf(
string,
sizeof(
string),
463 "alert tcp any any -> any any "
464 "(content:\"one\"; %s%ssid:1;)",
465 sticky ? sticky :
"", sticky ?
"; " :
" ");
478 static int DetectFastPatternStickySingleBadArg(
const char *sticky)
484 snprintf(
string,
sizeof(
string),
485 "alert tcp any any -> any any "
486 "(%s%scontent:\"one\"; fast_pattern:boo; sid:1;)",
487 sticky ? sticky :
"", sticky ?
"; " :
" ");
491 snprintf(
string,
sizeof(
string),
492 "alert tcp any any -> any any "
493 "(%s%scontent:\"one\"; fast_pattern:only; content:\"two\"; distance:10; sid:1;)",
494 sticky ? sticky :
"", sticky ?
"; " :
" ");
498 snprintf(
string,
sizeof(
string),
499 "alert tcp any any -> any any "
500 "(%s%scontent:\"one\"; content:\"two\"; fast_pattern:only; distance:10; sid:1;)",
501 sticky ? sticky :
"", sticky ?
"; " :
" ");
505 snprintf(
string,
sizeof(
string),
506 "alert tcp any any -> any any "
507 "(%s%scontent:\"one\"; content:\"two\"; distance:10; fast_pattern:only; sid:1;)",
508 sticky ? sticky :
"", sticky ?
"; " :
" ");
512 snprintf(
string,
sizeof(
string),
513 "alert tcp any any -> any any "
514 "(%s%scontent:\"one\"; fast_pattern:5,6; sid:1;)",
515 sticky ? sticky :
"", sticky ?
"; " :
" ");
522 static int DetectFastPatternModifierBadRules(
const char *sticky)
528 snprintf(
string,
sizeof(
string),
529 "alert tcp any any -> any any "
530 "(content:\"one\"; %s%sfast_pattern:boo; sid:1;)",
531 sticky ? sticky :
"", sticky ?
"; " :
" ");
535 snprintf(
string,
sizeof(
string),
536 "alert tcp any any -> any any "
537 "(content:\"one\"; %s%sfast_pattern:only; content:\"two\"; %s%sdistance:10; sid:1;)",
538 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ");
543 snprintf(
string,
sizeof(
string),
"alert tcp any any -> any any "
544 "(content:\"one\"; %s%s content:\"two\"; %s%sdistance:10; fast_pattern:only; sid:1;)",
545 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ");
550 snprintf(
string,
sizeof(
string),
551 "alert tcp any any -> any any "
552 "(content:\"one\"; %s%sfast_pattern:only; content:\"two\"; %s%swithin:10; sid:1;)",
553 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ");
557 snprintf(
string,
sizeof(
string),
558 "alert tcp any any -> any any "
559 "(content:\"one\"; %s%s content:\"two\"; %s%swithin:10; fast_pattern:only; sid:1;)",
560 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ");
564 snprintf(
string,
sizeof(
string),
565 "alert tcp any any -> any any "
566 "(content:\"one\"; %s%sfast_pattern:only; offset:10; sid:1;)",
567 sticky ? sticky :
"", sticky ?
"; " :
" ");
571 snprintf(
string,
sizeof(
string),
572 "alert tcp any any -> any any "
573 "(content:\"one\"; %s%s offset:10; fast_pattern:only; sid:1;)",
574 sticky ? sticky :
"", sticky ?
"; " :
" ");
578 snprintf(
string,
sizeof(
string),
579 "alert tcp any any -> any any "
580 "(content:\"one\"; %s%sfast_pattern:only; depth:10; sid:1;)",
581 sticky ? sticky :
"", sticky ?
"; " :
" ");
585 snprintf(
string,
sizeof(
string),
586 "alert tcp any any -> any any "
587 "(content:\"one\"; %s%s depth:10; fast_pattern:only; sid:1;)",
588 sticky ? sticky :
"", sticky ?
"; " :
" ");
592 snprintf(
string,
sizeof(
string),
593 "alert tcp any any -> any any "
594 "(content:\"one\"; %s%s content:!\"two\"; %s%sfast_pattern:only; sid:1;)",
595 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ");
599 snprintf(
string,
sizeof(
string),
600 "alert tcp any any -> any any "
601 "(content:\"one\"; %s%sfast_pattern:5,6; sid:1;)",
602 sticky ? sticky :
"", sticky ?
"; " :
" ");
606 snprintf(
string,
sizeof(
string),
607 "alert tcp any any -> any any "
608 "(content:\"one\"; %s%sfast_pattern:65977,2; sid:1;)",
609 sticky ? sticky :
"", sticky ?
"; " :
" ");
613 snprintf(
string,
sizeof(
string),
614 "alert tcp any any -> any any "
615 "(content:\"one\"; %s%sfast_pattern:2,65977; sid:1;)",
616 sticky ? sticky :
"", sticky ?
"; " :
" ");
620 snprintf(
string,
sizeof(
string),
621 "alert tcp any any -> any any "
622 "(content:\"one\"; %s%sfast_pattern:2,65534; sid:1;)",
623 sticky ? sticky :
"", sticky ?
"; " :
" ");
627 snprintf(
string,
sizeof(
string),
628 "alert tcp any any -> any any "
629 "(content:\"one\"; %s%sfast_pattern:65534,2; sid:1;)",
630 sticky ? sticky :
"", sticky ?
"; " :
" ");
634 snprintf(
string,
sizeof(
string),
635 "alert tcp any any -> any any "
636 "(content:\"one\"; %s%scontent:!\"two\"; fast_pattern:1,2; %s%sdistance:10; sid:1;)",
637 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ");
641 snprintf(
string,
sizeof(
string),
642 "alert tcp any any -> any any "
643 "(content:\"one\"; %s%scontent:!\"two\"; fast_pattern:1,2; %s%swithin:10; sid:1;)",
644 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ");
648 snprintf(
string,
sizeof(
string),
649 "alert tcp any any -> any any "
650 "(content:\"one\"; %s%scontent:!\"two\"; fast_pattern:1,2; %s%sdepth:10; sid:1;)",
651 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ");
655 snprintf(
string,
sizeof(
string),
656 "alert tcp any any -> any any "
657 "(content:\"one\"; %s%scontent:!\"two\"; fast_pattern:1,2; %s%soffset:10; sid:1;)",
658 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ");
665 static int DetectFastPatternStickySingleFPOnly(
const char *sticky,
const int list)
670 snprintf(
string,
sizeof(
string),
671 "alert tcp any any -> any any "
672 "(%s%scontent:\"one\"; fast_pattern:only; sid:1;)",
673 sticky ? sticky :
"", sticky ?
"; " :
" ");
687 static int DetectFastPatternModifierFPOnly(
const char *sticky,
const int list)
692 snprintf(
string,
sizeof(
string),
693 "alert tcp any any -> any any "
694 "(content:\"one\"; %s%sfast_pattern:only; sid:1;)",
695 sticky ? sticky :
"", sticky ?
"; " :
" ");
706 snprintf(
string,
sizeof(
string),
707 "alert tcp any any -> any any "
708 "(content:\"one\"; %s%scontent:\"two\"; %s%sfast_pattern:only; sid:2;)",
709 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ");
712 sm = GetMatches(s, list);
727 snprintf(
string,
sizeof(
string),
728 "alert tcp any any -> any any "
729 "(content:\"one\"; %s%scontent:\"two\"; distance:10; %s%scontent:\"three\"; "
730 "%s%sfast_pattern:only; sid:3;)",
731 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ",
732 sticky ? sticky :
"", sticky ?
"; " :
" ");
735 sm = GetMatches(s, list);
758 snprintf(
string,
sizeof(
string),
759 "alert tcp any any -> any any "
760 "(content:\"one\"; %s%scontent:\"two\"; within:10; %s%scontent:\"three\"; "
761 "%s%sfast_pattern:only; sid:4;)",
762 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ",
763 sticky ? sticky :
"", sticky ?
"; " :
" ");
766 sm = GetMatches(s, list);
789 snprintf(
string,
sizeof(
string),
790 "alert tcp any any -> any any "
791 "(content:\"one\"; %s%scontent:\"two\"; offset:10; %s%scontent:\"three\"; "
792 "%s%sfast_pattern:only; sid:5;)",
793 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ",
794 sticky ? sticky :
"", sticky ?
"; " :
" ");
797 sm = GetMatches(s, list);
820 snprintf(
string,
sizeof(
string),
821 "alert tcp any any -> any any "
822 "(content:\"one\"; %s%scontent:\"two\"; depth:10; %s%scontent:\"three\"; "
823 "%s%sfast_pattern:only; sid:6;)",
824 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ",
825 sticky ? sticky :
"", sticky ?
"; " :
" ");
828 sm = GetMatches(s, list);
851 snprintf(
string,
sizeof(
string),
852 "alert tcp any any -> any any "
853 "(content:!\"one\"; %s%sfast_pattern; content:\"two\"; depth:10; %s%ssid:7;)",
854 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ");
857 sm = GetMatches(s, list);
878 static int DetectFastPatternStickyFPChop(
const char *sticky,
const int list)
883 snprintf(
string,
sizeof(
string),
884 "alert tcp any any -> any any "
885 "(%s%scontent:\"onetwothree\"; fast_pattern:3,4; sid:1;)",
886 sticky ? sticky :
"", sticky ?
"; " :
" ");
900 snprintf(
string,
sizeof(
string),
901 "alert tcp any any -> any any "
902 "(%s%scontent:\"onetwothree\"; fast_pattern:3,4; content:\"xyz\"; distance:10; sid:2;)",
903 sticky ? sticky :
"", sticky ?
"; " :
" ");
906 sm = GetMatches(s, list);
921 static int DetectFastPatternModifierFPChop(
const char *sticky,
const int list)
926 snprintf(
string,
sizeof(
string),
927 "alert tcp any any -> any any "
928 "(content:\"onetwothree\"; %s%sfast_pattern:3,4; sid:1;)",
929 sticky ? sticky :
"", sticky ?
"; " :
" ");
943 snprintf(
string,
sizeof(
string),
944 "alert tcp any any -> any any "
945 "(content:!\"onetwothree\"; %s%sfast_pattern:3,4; sid:2;)",
946 sticky ? sticky :
"", sticky ?
"; " :
" ");
949 sm = GetMatches(s, list);
969 static int DetectFastPatternTest01(
void)
975 FAIL_IF_NOT(DetectFastPatternStickySingleBadArg(NULL));
976 FAIL_IF_NOT(DetectFastPatternModifierBadRules(NULL));
983 const char *buffer_name;
985 const char *mod_name;
987 {
"file_data",
"file.data", NULL },
988 {
"http_uri",
"http.uri",
"http_uri" },
989 {
"http_raw_uri",
"http.uri.raw",
"http_raw_uri" },
990 {
"http_user_agent",
"http.user_agent",
"http_user_agent" },
991 {
"http_header",
"http.header",
"http_header" },
994 {
"http_method",
"http.method",
"http_method" },
995 {
"http_cookie",
"http.cookie",
"http_cookie" },
996 {
"http_host",
"http.host",
"http_host" },
997 {
"http_raw_host",
"http.host.raw",
"http_raw_host" },
998 {
"http_stat_code",
"http.stat_code",
"http_stat_code" },
999 {
"http_stat_msg",
"http.stat_msg",
"http_stat_msg" },
1000 {
"http_client_body",
"http.request_body",
"http_client_body" },
1001 { NULL, NULL, NULL },
1004 for (
int i = 0; keywords[i].buffer_name != NULL; i++) {
1008 const char *k = keywords[i].sb_name;
1010 FAIL_IF_NOT(DetectFastPatternStickySingle(k, list_id));
1011 FAIL_IF_NOT(DetectFastPatternStickySingleNoFP(k, list_id));
1012 FAIL_IF_NOT(DetectFastPatternStickySingleBadArg(k));
1013 FAIL_IF_NOT(DetectFastPatternStickySingleFPOnly(k, list_id));
1014 FAIL_IF_NOT(DetectFastPatternStickyFPChop(k, list_id));
1016 k = keywords[i].mod_name;
1018 FAIL_IF_NOT(DetectFastPatternModifierSingle(k, list_id));
1019 FAIL_IF_NOT(DetectFastPatternModifierSingleNoFP(k, list_id));
1020 FAIL_IF_NOT(DetectFastPatternModifierBadRules(k));
1021 FAIL_IF_NOT(DetectFastPatternModifierFPOnly(k, list_id));
1022 FAIL_IF_NOT(DetectFastPatternModifierFPChop(k, list_id));
1034 static int DetectFastPatternTest14(
void)
1036 uint8_t *buf = (uint8_t *)
"Dummy is our name. Oh yes. From right here "
1037 "right now, all the way to hangover. right. strings5_imp now here "
1038 "comes our dark knight strings_string5. Yes here is our dark knight";
1039 uint16_t buflen = strlen((
char *)buf);
1043 memset(&th_v, 0,
sizeof(th_v));
1054 "alert tcp any any -> any any "
1055 "(msg:\"fast_pattern test\"; content:\"strings_string5\"; content:\"knight\"; "
1056 "fast_pattern; sid:1;)");
1060 "alert tcp any any -> any any "
1061 "(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);