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) {
249 "used with negated content, along with relative modifiers");
253 if (arg == NULL|| strcmp(arg,
"") == 0) {
256 "options for the same content");
267 "can be used on only one content in a rule");
275 SCLogError(
"fast_pattern cannot be used with base64_data");
294 "used with negated content or with any of the relative "
295 "modifiers like distance, within, offset, depth");
301 }
else if (ret == 4) {
302 pcre2len =
sizeof(arg_substr);
303 res = pcre2_substring_copy_bynumber(match, 2, (PCRE2_UCHAR8 *)arg_substr, &pcre2len);
305 SCLogError(
"pcre2_substring_copy_bynumber failed "
306 "for fast_pattern offset");
311 (
const char *)arg_substr) < 0) {
318 pcre2len =
sizeof(arg_substr);
319 res = pcre2_substring_copy_bynumber(match, 3, (PCRE2_UCHAR8 *)arg_substr, &pcre2len);
321 SCLogError(
"pcre2_substring_copy_bynumber failed "
322 "for fast_pattern offset");
327 (
const char *)arg_substr) < 0) {
335 if (
offset > (65535 - length)) {
337 "exceeds limit pattern length limit");
343 "offset (%u)) exceeds pattern length (%u)",
353 SCLogError(
"parse error, ret %" PRId32
", string %s", ret, arg);
359 pcre2_match_data_free(match);
364 pcre2_match_data_free(match);
382 static int DetectFastPatternStickySingle(
const char *sticky,
const int list)
387 snprintf(
string,
sizeof(
string),
388 "alert tcp any any -> any any "
389 "(%s%scontent:\"one\"; fast_pattern; sid:1;)",
390 sticky ? sticky :
"", sticky ?
"; " :
" ");
403 static int DetectFastPatternModifierSingle(
const char *sticky,
const int list)
408 snprintf(
string,
sizeof(
string),
409 "alert tcp any any -> any any "
410 "(content:\"one\"; %s%sfast_pattern; sid:1;)",
411 sticky ? sticky :
"", sticky ?
"; " :
" ");
424 static int DetectFastPatternStickySingleNoFP(
const char *sticky,
const int list)
429 snprintf(
string,
sizeof(
string),
430 "alert tcp any any -> any any "
431 "(%s%scontent:\"one\"; sid:1;)",
432 sticky ? sticky :
"", sticky ?
"; " :
" ");
445 static int DetectFastPatternModifierSingleNoFP(
const char *sticky,
const int list)
450 snprintf(
string,
sizeof(
string),
451 "alert tcp any any -> any any "
452 "(content:\"one\"; %s%ssid:1;)",
453 sticky ? sticky :
"", sticky ?
"; " :
" ");
466 static int DetectFastPatternStickySingleBadArg(
const char *sticky)
472 snprintf(
string,
sizeof(
string),
473 "alert tcp any any -> any any "
474 "(%s%scontent:\"one\"; fast_pattern:boo; sid:1;)",
475 sticky ? sticky :
"", sticky ?
"; " :
" ");
479 snprintf(
string,
sizeof(
string),
480 "alert tcp any any -> any any "
481 "(%s%scontent:\"one\"; fast_pattern:only; content:\"two\"; distance:10; sid:1;)",
482 sticky ? sticky :
"", sticky ?
"; " :
" ");
486 snprintf(
string,
sizeof(
string),
487 "alert tcp any any -> any any "
488 "(%s%scontent:\"one\"; content:\"two\"; fast_pattern:only; distance:10; sid:1;)",
489 sticky ? sticky :
"", sticky ?
"; " :
" ");
493 snprintf(
string,
sizeof(
string),
494 "alert tcp any any -> any any "
495 "(%s%scontent:\"one\"; content:\"two\"; distance:10; fast_pattern:only; sid:1;)",
496 sticky ? sticky :
"", sticky ?
"; " :
" ");
500 snprintf(
string,
sizeof(
string),
501 "alert tcp any any -> any any "
502 "(%s%scontent:\"one\"; fast_pattern:5,6; sid:1;)",
503 sticky ? sticky :
"", sticky ?
"; " :
" ");
510 static int DetectFastPatternModifierBadRules(
const char *sticky)
516 snprintf(
string,
sizeof(
string),
517 "alert tcp any any -> any any "
518 "(content:\"one\"; %s%sfast_pattern:boo; sid:1;)",
519 sticky ? sticky :
"", sticky ?
"; " :
" ");
523 snprintf(
string,
sizeof(
string),
524 "alert tcp any any -> any any "
525 "(content:\"one\"; %s%sfast_pattern:only; content:\"two\"; %s%sdistance:10; sid:1;)",
526 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ");
531 snprintf(
string,
sizeof(
string),
"alert tcp any any -> any any "
532 "(content:\"one\"; %s%s content:\"two\"; %s%sdistance:10; fast_pattern:only; sid:1;)",
533 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ");
538 snprintf(
string,
sizeof(
string),
539 "alert tcp any any -> any any "
540 "(content:\"one\"; %s%sfast_pattern:only; content:\"two\"; %s%swithin:10; sid:1;)",
541 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ");
545 snprintf(
string,
sizeof(
string),
546 "alert tcp any any -> any any "
547 "(content:\"one\"; %s%s content:\"two\"; %s%swithin:10; fast_pattern:only; sid:1;)",
548 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ");
552 snprintf(
string,
sizeof(
string),
553 "alert tcp any any -> any any "
554 "(content:\"one\"; %s%sfast_pattern:only; offset:10; sid:1;)",
555 sticky ? sticky :
"", sticky ?
"; " :
" ");
559 snprintf(
string,
sizeof(
string),
560 "alert tcp any any -> any any "
561 "(content:\"one\"; %s%s offset:10; fast_pattern:only; sid:1;)",
562 sticky ? sticky :
"", sticky ?
"; " :
" ");
566 snprintf(
string,
sizeof(
string),
567 "alert tcp any any -> any any "
568 "(content:\"one\"; %s%sfast_pattern:only; depth:10; sid:1;)",
569 sticky ? sticky :
"", sticky ?
"; " :
" ");
573 snprintf(
string,
sizeof(
string),
574 "alert tcp any any -> any any "
575 "(content:\"one\"; %s%s depth:10; fast_pattern:only; sid:1;)",
576 sticky ? sticky :
"", sticky ?
"; " :
" ");
580 snprintf(
string,
sizeof(
string),
581 "alert tcp any any -> any any "
582 "(content:\"one\"; %s%s content:!\"two\"; %s%sfast_pattern:only; sid:1;)",
583 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ");
587 snprintf(
string,
sizeof(
string),
588 "alert tcp any any -> any any "
589 "(content:\"one\"; %s%sfast_pattern:5,6; sid:1;)",
590 sticky ? sticky :
"", sticky ?
"; " :
" ");
594 snprintf(
string,
sizeof(
string),
595 "alert tcp any any -> any any "
596 "(content:\"one\"; %s%sfast_pattern:65977,2; sid:1;)",
597 sticky ? sticky :
"", sticky ?
"; " :
" ");
601 snprintf(
string,
sizeof(
string),
602 "alert tcp any any -> any any "
603 "(content:\"one\"; %s%sfast_pattern:2,65977; sid:1;)",
604 sticky ? sticky :
"", sticky ?
"; " :
" ");
608 snprintf(
string,
sizeof(
string),
609 "alert tcp any any -> any any "
610 "(content:\"one\"; %s%sfast_pattern:2,65534; sid:1;)",
611 sticky ? sticky :
"", sticky ?
"; " :
" ");
615 snprintf(
string,
sizeof(
string),
616 "alert tcp any any -> any any "
617 "(content:\"one\"; %s%sfast_pattern:65534,2; sid:1;)",
618 sticky ? sticky :
"", sticky ?
"; " :
" ");
622 snprintf(
string,
sizeof(
string),
623 "alert tcp any any -> any any "
624 "(content:\"one\"; %s%scontent:!\"two\"; fast_pattern:1,2; %s%sdistance:10; sid:1;)",
625 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ");
629 snprintf(
string,
sizeof(
string),
630 "alert tcp any any -> any any "
631 "(content:\"one\"; %s%scontent:!\"two\"; fast_pattern:1,2; %s%swithin:10; sid:1;)",
632 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ");
636 snprintf(
string,
sizeof(
string),
637 "alert tcp any any -> any any "
638 "(content:\"one\"; %s%scontent:!\"two\"; fast_pattern:1,2; %s%sdepth:10; sid:1;)",
639 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ");
643 snprintf(
string,
sizeof(
string),
644 "alert tcp any any -> any any "
645 "(content:\"one\"; %s%scontent:!\"two\"; fast_pattern:1,2; %s%soffset:10; sid:1;)",
646 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ");
653 static int DetectFastPatternStickySingleFPOnly(
const char *sticky,
const int list)
658 snprintf(
string,
sizeof(
string),
659 "alert tcp any any -> any any "
660 "(%s%scontent:\"one\"; fast_pattern:only; sid:1;)",
661 sticky ? sticky :
"", sticky ?
"; " :
" ");
675 static int DetectFastPatternModifierFPOnly(
const char *sticky,
const int list)
680 snprintf(
string,
sizeof(
string),
681 "alert tcp any any -> any any "
682 "(content:\"one\"; %s%sfast_pattern:only; sid:1;)",
683 sticky ? sticky :
"", sticky ?
"; " :
" ");
694 snprintf(
string,
sizeof(
string),
695 "alert tcp any any -> any any "
696 "(content:\"one\"; %s%scontent:\"two\"; %s%sfast_pattern:only; sid:2;)",
697 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ");
700 sm = GetMatches(s, list);
715 snprintf(
string,
sizeof(
string),
716 "alert tcp any any -> any any "
717 "(content:\"one\"; %s%scontent:\"two\"; distance:10; %s%scontent:\"three\"; "
718 "%s%sfast_pattern:only; sid:3;)",
719 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ",
720 sticky ? sticky :
"", sticky ?
"; " :
" ");
723 sm = GetMatches(s, list);
746 snprintf(
string,
sizeof(
string),
747 "alert tcp any any -> any any "
748 "(content:\"one\"; %s%scontent:\"two\"; within:10; %s%scontent:\"three\"; "
749 "%s%sfast_pattern:only; sid:4;)",
750 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ",
751 sticky ? sticky :
"", sticky ?
"; " :
" ");
754 sm = GetMatches(s, list);
777 snprintf(
string,
sizeof(
string),
778 "alert tcp any any -> any any "
779 "(content:\"one\"; %s%scontent:\"two\"; offset:10; %s%scontent:\"three\"; "
780 "%s%sfast_pattern:only; sid:5;)",
781 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ",
782 sticky ? sticky :
"", sticky ?
"; " :
" ");
785 sm = GetMatches(s, list);
808 snprintf(
string,
sizeof(
string),
809 "alert tcp any any -> any any "
810 "(content:\"one\"; %s%scontent:\"two\"; depth:10; %s%scontent:\"three\"; "
811 "%s%sfast_pattern:only; sid:6;)",
812 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ",
813 sticky ? sticky :
"", sticky ?
"; " :
" ");
816 sm = GetMatches(s, list);
839 snprintf(
string,
sizeof(
string),
840 "alert tcp any any -> any any "
841 "(content:!\"one\"; %s%sfast_pattern; content:\"two\"; depth:10; %s%ssid:7;)",
842 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ");
845 sm = GetMatches(s, list);
866 static int DetectFastPatternStickyFPChop(
const char *sticky,
const int list)
871 snprintf(
string,
sizeof(
string),
872 "alert tcp any any -> any any "
873 "(%s%scontent:\"onetwothree\"; fast_pattern:3,4; sid:1;)",
874 sticky ? sticky :
"", sticky ?
"; " :
" ");
888 snprintf(
string,
sizeof(
string),
889 "alert tcp any any -> any any "
890 "(%s%scontent:\"onetwothree\"; fast_pattern:3,4; content:\"xyz\"; distance:10; sid:2;)",
891 sticky ? sticky :
"", sticky ?
"; " :
" ");
894 sm = GetMatches(s, list);
909 static int DetectFastPatternModifierFPChop(
const char *sticky,
const int list)
914 snprintf(
string,
sizeof(
string),
915 "alert tcp any any -> any any "
916 "(content:\"onetwothree\"; %s%sfast_pattern:3,4; sid:1;)",
917 sticky ? sticky :
"", sticky ?
"; " :
" ");
931 snprintf(
string,
sizeof(
string),
932 "alert tcp any any -> any any "
933 "(content:!\"onetwothree\"; %s%sfast_pattern:3,4; sid:2;)",
934 sticky ? sticky :
"", sticky ?
"; " :
" ");
937 sm = GetMatches(s, list);
957 static int DetectFastPatternTest01(
void)
963 FAIL_IF_NOT(DetectFastPatternStickySingleBadArg(NULL));
964 FAIL_IF_NOT(DetectFastPatternModifierBadRules(NULL));
971 const char *buffer_name;
973 const char *mod_name;
975 {
"file_data",
"file.data", NULL },
976 {
"http_uri",
"http.uri",
"http_uri" },
977 {
"http_raw_uri",
"http.uri.raw",
"http_raw_uri" },
978 {
"http_user_agent",
"http.user_agent",
"http_user_agent" },
979 {
"http_header",
"http.header",
"http_header" },
982 {
"http_method",
"http.method",
"http_method" },
983 {
"http_cookie",
"http.cookie",
"http_cookie" },
984 {
"http_host",
"http.host",
"http_host" },
985 {
"http_raw_host",
"http.host.raw",
"http_raw_host" },
986 {
"http_stat_code",
"http.stat_code",
"http_stat_code" },
987 {
"http_stat_msg",
"http.stat_msg",
"http_stat_msg" },
988 {
"http_client_body",
"http.request_body",
"http_client_body" },
989 { NULL, NULL, NULL },
992 for (
int i = 0; keywords[i].buffer_name != NULL; i++) {
996 const char *k = keywords[i].sb_name;
998 FAIL_IF_NOT(DetectFastPatternStickySingle(k, list_id));
999 FAIL_IF_NOT(DetectFastPatternStickySingleNoFP(k, list_id));
1000 FAIL_IF_NOT(DetectFastPatternStickySingleBadArg(k));
1001 FAIL_IF_NOT(DetectFastPatternStickySingleFPOnly(k, list_id));
1002 FAIL_IF_NOT(DetectFastPatternStickyFPChop(k, list_id));
1004 k = keywords[i].mod_name;
1006 FAIL_IF_NOT(DetectFastPatternModifierSingle(k, list_id));
1007 FAIL_IF_NOT(DetectFastPatternModifierSingleNoFP(k, list_id));
1008 FAIL_IF_NOT(DetectFastPatternModifierBadRules(k));
1009 FAIL_IF_NOT(DetectFastPatternModifierFPOnly(k, list_id));
1010 FAIL_IF_NOT(DetectFastPatternModifierFPChop(k, list_id));
1022 static int DetectFastPatternTest14(
void)
1024 uint8_t *buf = (uint8_t *)
"Dummy is our name. Oh yes. From right here "
1025 "right now, all the way to hangover. right. strings5_imp now here "
1026 "comes our dark knight strings_string5. Yes here is our dark knight";
1027 uint16_t buflen = strlen((
char *)buf);
1031 memset(&th_v, 0,
sizeof(th_v));
1042 "alert tcp any any -> any any "
1043 "(msg:\"fast_pattern test\"; content:\"strings_string5\"; content:\"knight\"; "
1044 "fast_pattern; sid:1;)");
1048 "alert tcp any any -> any any "
1049 "(msg:\"test different content\"; content:\"Dummy is our name\"; sid:2;)");
1073 static int DetectFastPatternTest671(
void)
1081 de_ctx,
"alert tcp any any -> any any (content:\"onetwothreefour\"; sid:1;)");
1084 de_ctx,
"alert tcp any any -> any any (content:\"onetwothreefour\"; sid:2;)");
1087 de_ctx,
"alert tcp any any -> any any (content:\"uniquepattern\"; sid:3;)");
1090 "alert tcp any any -> any any (content:\"onetwothreefour\"; fast_pattern:3,5; sid:4;)");
1093 de_ctx,
"alert tcp any any -> any any (content:\"twoth\"; sid:5;)");
1096 "alert tcp any any -> any any (content:\"onetwothreefour\"; fast_pattern:0,15; "
1130 static int DetectFastPatternPrefilter(
void)
1134 const char *
string =
"alert tcp any any -> any any "
1135 "(content:\"one\"; prefilter; sid:1;)";
1148 static void DetectFastPatternRegisterTests(
void)
1150 UtRegisterTest(
"DetectFastPatternTest01", DetectFastPatternTest01);
1151 UtRegisterTest(
"DetectFastPatternTest14", DetectFastPatternTest14);
1158 UtRegisterTest(
"DetectFastPatternTest671", DetectFastPatternTest671);
1160 UtRegisterTest(
"DetectFastPatternPrefilter", DetectFastPatternPrefilter);