Go to the documentation of this file.
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)
102 new->list_id = list_id;
103 new->priority = priority;
113 new->list_id = list_id;
114 new->priority = priority;
134 Add(&g_fp_support_smlist_list, list_id, priority);
158 FatalError(
"out of memory: %s", strerror(errno));
216 int ret = 0, res = 0;
218 char arg_substr[128] =
"";
223 if (pm1 == NULL && pm2 == NULL) {
225 "the rule, without a content context. Please use a "
226 "content based keyword before using fast_pattern");
236 }
else if (pm1 && !pm2) {
251 "used with negated content, along with relative modifiers");
255 if (arg == NULL|| strcmp(arg,
"") == 0) {
258 "options for the same content");
262 uint32_t list_id = 0;
270 "can be used on only one content in a rule");
293 "used with negated content or with any of the relative "
294 "modifiers like distance, within, offset, depth");
300 }
else if (ret == 4) {
301 pcre2len =
sizeof(arg_substr);
302 res = pcre2_substring_copy_bynumber(
303 parse_regex.
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(
320 parse_regex.
match, 3, (PCRE2_UCHAR8 *)arg_substr, &pcre2len);
322 SCLogError(
"pcre2_substring_copy_bynumber failed "
323 "for fast_pattern offset");
328 (
const char *)arg_substr) < 0) {
336 if (
offset > (65535 - length)) {
338 "exceeds limit pattern length limit");
344 "offset (%u)) exceeds pattern length (%u)",
354 SCLogError(
"parse error, ret %" PRId32
", string %s", ret, arg);
370 static int DetectFastPatternStickySingle(
const char *sticky,
const int list)
375 snprintf(
string,
sizeof(
string),
376 "alert tcp any any -> any any "
377 "(%s%scontent:\"one\"; fast_pattern; sid:1;)",
378 sticky ? sticky :
"", sticky ?
"; " :
" ");
391 static int DetectFastPatternModifierSingle(
const char *sticky,
const int list)
396 snprintf(
string,
sizeof(
string),
397 "alert tcp any any -> any any "
398 "(content:\"one\"; %s%sfast_pattern; sid:1;)",
399 sticky ? sticky :
"", sticky ?
"; " :
" ");
412 static int DetectFastPatternStickySingleNoFP(
const char *sticky,
const int list)
417 snprintf(
string,
sizeof(
string),
418 "alert tcp any any -> any any "
419 "(%s%scontent:\"one\"; sid:1;)",
420 sticky ? sticky :
"", sticky ?
"; " :
" ");
433 static int DetectFastPatternModifierSingleNoFP(
const char *sticky,
const int list)
438 snprintf(
string,
sizeof(
string),
439 "alert tcp any any -> any any "
440 "(content:\"one\"; %s%ssid:1;)",
441 sticky ? sticky :
"", sticky ?
"; " :
" ");
454 static int DetectFastPatternStickySingleBadArg(
const char *sticky)
460 snprintf(
string,
sizeof(
string),
461 "alert tcp any any -> any any "
462 "(%s%scontent:\"one\"; fast_pattern:boo; sid:1;)",
463 sticky ? sticky :
"", sticky ?
"; " :
" ");
467 snprintf(
string,
sizeof(
string),
468 "alert tcp any any -> any any "
469 "(%s%scontent:\"one\"; fast_pattern:only; content:\"two\"; distance:10; sid:1;)",
470 sticky ? sticky :
"", sticky ?
"; " :
" ");
474 snprintf(
string,
sizeof(
string),
475 "alert tcp any any -> any any "
476 "(%s%scontent:\"one\"; content:\"two\"; fast_pattern:only; distance:10; sid:1;)",
477 sticky ? sticky :
"", sticky ?
"; " :
" ");
481 snprintf(
string,
sizeof(
string),
482 "alert tcp any any -> any any "
483 "(%s%scontent:\"one\"; content:\"two\"; distance:10; fast_pattern:only; sid:1;)",
484 sticky ? sticky :
"", sticky ?
"; " :
" ");
488 snprintf(
string,
sizeof(
string),
489 "alert tcp any any -> any any "
490 "(%s%scontent:\"one\"; fast_pattern:5,6; sid:1;)",
491 sticky ? sticky :
"", sticky ?
"; " :
" ");
498 static int DetectFastPatternModifierBadRules(
const char *sticky)
504 snprintf(
string,
sizeof(
string),
505 "alert tcp any any -> any any "
506 "(content:\"one\"; %s%sfast_pattern:boo; sid:1;)",
507 sticky ? sticky :
"", sticky ?
"; " :
" ");
511 snprintf(
string,
sizeof(
string),
512 "alert tcp any any -> any any "
513 "(content:\"one\"; %s%sfast_pattern:only; content:\"two\"; %s%sdistance:10; sid:1;)",
514 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ");
519 snprintf(
string,
sizeof(
string),
"alert tcp any any -> any any "
520 "(content:\"one\"; %s%s content:\"two\"; %s%sdistance:10; fast_pattern:only; sid:1;)",
521 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ");
526 snprintf(
string,
sizeof(
string),
527 "alert tcp any any -> any any "
528 "(content:\"one\"; %s%sfast_pattern:only; content:\"two\"; %s%swithin:10; sid:1;)",
529 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ");
533 snprintf(
string,
sizeof(
string),
534 "alert tcp any any -> any any "
535 "(content:\"one\"; %s%s content:\"two\"; %s%swithin:10; fast_pattern:only; sid:1;)",
536 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ");
540 snprintf(
string,
sizeof(
string),
541 "alert tcp any any -> any any "
542 "(content:\"one\"; %s%sfast_pattern:only; offset:10; sid:1;)",
543 sticky ? sticky :
"", sticky ?
"; " :
" ");
547 snprintf(
string,
sizeof(
string),
548 "alert tcp any any -> any any "
549 "(content:\"one\"; %s%s offset:10; fast_pattern:only; sid:1;)",
550 sticky ? sticky :
"", sticky ?
"; " :
" ");
554 snprintf(
string,
sizeof(
string),
555 "alert tcp any any -> any any "
556 "(content:\"one\"; %s%sfast_pattern:only; depth:10; sid:1;)",
557 sticky ? sticky :
"", sticky ?
"; " :
" ");
561 snprintf(
string,
sizeof(
string),
562 "alert tcp any any -> any any "
563 "(content:\"one\"; %s%s depth:10; fast_pattern:only; sid:1;)",
564 sticky ? sticky :
"", sticky ?
"; " :
" ");
568 snprintf(
string,
sizeof(
string),
569 "alert tcp any any -> any any "
570 "(content:\"one\"; %s%s content:!\"two\"; %s%sfast_pattern:only; sid:1;)",
571 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ");
575 snprintf(
string,
sizeof(
string),
576 "alert tcp any any -> any any "
577 "(content:\"one\"; %s%sfast_pattern:5,6; sid:1;)",
578 sticky ? sticky :
"", sticky ?
"; " :
" ");
582 snprintf(
string,
sizeof(
string),
583 "alert tcp any any -> any any "
584 "(content:\"one\"; %s%sfast_pattern:65977,2; sid:1;)",
585 sticky ? sticky :
"", sticky ?
"; " :
" ");
589 snprintf(
string,
sizeof(
string),
590 "alert tcp any any -> any any "
591 "(content:\"one\"; %s%sfast_pattern:2,65977; sid:1;)",
592 sticky ? sticky :
"", sticky ?
"; " :
" ");
596 snprintf(
string,
sizeof(
string),
597 "alert tcp any any -> any any "
598 "(content:\"one\"; %s%sfast_pattern:2,65534; sid:1;)",
599 sticky ? sticky :
"", sticky ?
"; " :
" ");
603 snprintf(
string,
sizeof(
string),
604 "alert tcp any any -> any any "
605 "(content:\"one\"; %s%sfast_pattern:65534,2; sid:1;)",
606 sticky ? sticky :
"", sticky ?
"; " :
" ");
610 snprintf(
string,
sizeof(
string),
611 "alert tcp any any -> any any "
612 "(content:\"one\"; %s%scontent:!\"two\"; fast_pattern:1,2; %s%sdistance:10; sid:1;)",
613 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ");
617 snprintf(
string,
sizeof(
string),
618 "alert tcp any any -> any any "
619 "(content:\"one\"; %s%scontent:!\"two\"; fast_pattern:1,2; %s%swithin:10; sid:1;)",
620 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ");
624 snprintf(
string,
sizeof(
string),
625 "alert tcp any any -> any any "
626 "(content:\"one\"; %s%scontent:!\"two\"; fast_pattern:1,2; %s%sdepth:10; sid:1;)",
627 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ");
631 snprintf(
string,
sizeof(
string),
632 "alert tcp any any -> any any "
633 "(content:\"one\"; %s%scontent:!\"two\"; fast_pattern:1,2; %s%soffset:10; sid:1;)",
634 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ");
641 static int DetectFastPatternStickySingleFPOnly(
const char *sticky,
const int list)
646 snprintf(
string,
sizeof(
string),
647 "alert tcp any any -> any any "
648 "(%s%scontent:\"one\"; fast_pattern:only; sid:1;)",
649 sticky ? sticky :
"", sticky ?
"; " :
" ");
663 static int DetectFastPatternModifierFPOnly(
const char *sticky,
const int list)
668 snprintf(
string,
sizeof(
string),
669 "alert tcp any any -> any any "
670 "(content:\"one\"; %s%sfast_pattern:only; sid:1;)",
671 sticky ? sticky :
"", sticky ?
"; " :
" ");
682 snprintf(
string,
sizeof(
string),
683 "alert tcp any any -> any any "
684 "(content:\"one\"; %s%scontent:\"two\"; %s%sfast_pattern:only; sid:2;)",
685 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ");
703 snprintf(
string,
sizeof(
string),
704 "alert tcp any any -> any any "
705 "(content:\"one\"; %s%scontent:\"two\"; distance:10; %s%scontent:\"three\"; "
706 "%s%sfast_pattern:only; sid:3;)",
707 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ",
708 sticky ? sticky :
"", sticky ?
"; " :
" ");
734 snprintf(
string,
sizeof(
string),
735 "alert tcp any any -> any any "
736 "(content:\"one\"; %s%scontent:\"two\"; within:10; %s%scontent:\"three\"; "
737 "%s%sfast_pattern:only; sid:4;)",
738 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ",
739 sticky ? sticky :
"", sticky ?
"; " :
" ");
765 snprintf(
string,
sizeof(
string),
766 "alert tcp any any -> any any "
767 "(content:\"one\"; %s%scontent:\"two\"; offset:10; %s%scontent:\"three\"; "
768 "%s%sfast_pattern:only; sid:5;)",
769 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ",
770 sticky ? sticky :
"", sticky ?
"; " :
" ");
796 snprintf(
string,
sizeof(
string),
797 "alert tcp any any -> any any "
798 "(content:\"one\"; %s%scontent:\"two\"; depth:10; %s%scontent:\"three\"; "
799 "%s%sfast_pattern:only; sid:6;)",
800 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ",
801 sticky ? sticky :
"", sticky ?
"; " :
" ");
827 snprintf(
string,
sizeof(
string),
828 "alert tcp any any -> any any "
829 "(content:!\"one\"; %s%sfast_pattern; content:\"two\"; depth:10; %s%ssid:7;)",
830 sticky ? sticky :
"", sticky ?
"; " :
" ", sticky ? sticky :
"", sticky ?
"; " :
" ");
854 static int DetectFastPatternStickyFPChop(
const char *sticky,
const int list)
859 snprintf(
string,
sizeof(
string),
860 "alert tcp any any -> any any "
861 "(%s%scontent:\"onetwothree\"; fast_pattern:3,4; sid:1;)",
862 sticky ? sticky :
"", sticky ?
"; " :
" ");
876 snprintf(
string,
sizeof(
string),
877 "alert tcp any any -> any any "
878 "(%s%scontent:\"onetwothree\"; fast_pattern:3,4; content:\"xyz\"; distance:10; sid:2;)",
879 sticky ? sticky :
"", sticky ?
"; " :
" ");
897 static int DetectFastPatternModifierFPChop(
const char *sticky,
const int list)
902 snprintf(
string,
sizeof(
string),
903 "alert tcp any any -> any any "
904 "(content:\"onetwothree\"; %s%sfast_pattern:3,4; sid:1;)",
905 sticky ? sticky :
"", sticky ?
"; " :
" ");
919 snprintf(
string,
sizeof(
string),
920 "alert tcp any any -> any any "
921 "(content:!\"onetwothree\"; %s%sfast_pattern:3,4; sid:2;)",
922 sticky ? sticky :
"", sticky ?
"; " :
" ");
945 static int DetectFastPatternTest01(
void)
951 FAIL_IF_NOT(DetectFastPatternStickySingleBadArg(NULL));
952 FAIL_IF_NOT(DetectFastPatternModifierBadRules(NULL));
959 const char *buffer_name;
961 const char *mod_name;
963 {
"file_data",
"file.data", NULL },
964 {
"http_uri",
"http.uri",
"http_uri" },
965 {
"http_raw_uri",
"http.uri.raw",
"http_raw_uri" },
966 {
"http_user_agent",
"http.user_agent",
"http_user_agent" },
967 {
"http_header",
"http.header",
"http_header" },
970 {
"http_method",
"http.method",
"http_method" },
971 {
"http_cookie",
"http.cookie",
"http_cookie" },
972 {
"http_host",
"http.host",
"http_host" },
973 {
"http_raw_host",
"http.host.raw",
"http_raw_host" },
974 {
"http_stat_code",
"http.stat_code",
"http_stat_code" },
975 {
"http_stat_msg",
"http.stat_msg",
"http_stat_msg" },
976 {
"http_client_body",
"http.request_body",
"http_client_body" },
977 { NULL, NULL, NULL },
980 for (
int i = 0; keywords[i].buffer_name != NULL; i++) {
984 const char *k = keywords[i].sb_name;
986 FAIL_IF_NOT(DetectFastPatternStickySingle(k, list_id));
987 FAIL_IF_NOT(DetectFastPatternStickySingleNoFP(k, list_id));
988 FAIL_IF_NOT(DetectFastPatternStickySingleBadArg(k));
989 FAIL_IF_NOT(DetectFastPatternStickySingleFPOnly(k, list_id));
990 FAIL_IF_NOT(DetectFastPatternStickyFPChop(k, list_id));
992 k = keywords[i].mod_name;
994 FAIL_IF_NOT(DetectFastPatternModifierSingle(k, list_id));
995 FAIL_IF_NOT(DetectFastPatternModifierSingleNoFP(k, list_id));
997 FAIL_IF_NOT(DetectFastPatternModifierFPOnly(k, list_id));
998 FAIL_IF_NOT(DetectFastPatternModifierFPChop(k, list_id));
1010 static int DetectFastPatternTest14(
void)
1012 uint8_t *buf = (uint8_t *)
"Dummy is our name. Oh yes. From right here "
1013 "right now, all the way to hangover. right. strings5_imp now here "
1014 "comes our dark knight strings_string5. Yes here is our dark knight";
1015 uint16_t buflen = strlen((
char *)buf);
1019 memset(&th_v, 0,
sizeof(th_v));
1030 "alert tcp any any -> any any "
1031 "(msg:\"fast_pattern test\"; content:\"strings_string5\"; content:\"knight\"; "
1032 "fast_pattern; sid:1;)");
1036 "alert tcp any any -> any any "
1037 "(msg:\"test different content\"; content:\"Dummy is our name\"; sid:2;)");
1061 static int DetectFastPatternTest671(
void)
1069 de_ctx,
"alert tcp any any -> any any (content:\"onetwothreefour\"; sid:1;)");
1072 de_ctx,
"alert tcp any any -> any any (content:\"onetwothreefour\"; sid:2;)");
1075 de_ctx,
"alert tcp any any -> any any (content:\"uniquepattern\"; sid:3;)");
1078 "alert tcp any any -> any any (content:\"onetwothreefour\"; fast_pattern:3,5; sid:4;)");
1081 de_ctx,
"alert tcp any any -> any any (content:\"twoth\"; sid:5;)");
1084 "alert tcp any any -> any any (content:\"onetwothreefour\"; fast_pattern:0,15; "
1118 static int DetectFastPatternPrefilter(
void)
1122 const char *
string =
"alert tcp any any -> any any "
1123 "(content:\"one\"; prefilter; sid:1;)";
1136 static void DetectFastPatternRegisterTests(
void)
1138 UtRegisterTest(
"DetectFastPatternTest01", DetectFastPatternTest01);
1139 UtRegisterTest(
"DetectFastPatternTest14", DetectFastPatternTest14);
1146 UtRegisterTest(
"DetectFastPatternTest671", DetectFastPatternTest671);
1148 UtRegisterTest(
"DetectFastPatternPrefilter", DetectFastPatternPrefilter);
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
#define DETECT_CONTENT_FAST_PATTERN_CHOP
int DetectParsePcreExec(DetectParseRegex *parse_regex, const char *str, int start_offset, int options)
void(* Free)(DetectEngineCtx *, void *)
struct SCFPSupportSMList_ * next
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
struct HtpBodyChunk_ * next
int PacketAlertCheck(Packet *p, uint32_t sid)
Check if a certain sid alerted, this is used in the test functions.
main detection engine ctx
int StringParseUint16(uint16_t *res, int base, size_t len, const char *str)
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
void SupportFastPatternForSigMatchTypes(void)
Registers the keywords(SMs) that should be given fp support.
Packet * UTHBuildPacket(uint8_t *payload, uint16_t payload_len, uint8_t ipproto)
UTHBuildPacket is a wrapper that build packets with default ip and port fields.
void SigMatchSignatures(ThreadVars *tv, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
wrapper for old tests
SigMatchData * sm_arrays[DETECT_SM_LIST_MAX]
Signature * DetectEngineAppendSig(DetectEngineCtx *, const char *)
Parse and append a Signature into the Detection Engine Context signature list.
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
void DetectEngineRegisterFastPatternForId(DetectEngineCtx *de_ctx, int list_id, int priority)
#define FAIL_IF_NOT(expr)
Fail a test if expression evaluates to false.
int DetectBufferTypeGetByName(const char *name)
void FlowInitConfig(bool quiet)
initialize the configuration
#define FAIL_IF_NOT_NULL(expr)
Fail a test if expression evaluates to non-NULL.
#define PASS
Pass the test.
#define DETECT_CONTENT_DISTANCE
SigMatch * DetectGetLastSMFromMpmLists(const DetectEngineCtx *de_ctx, const Signature *s)
get the last SigMatch from lists that support MPM.
void DetectSetupParseRegexes(const char *parse_str, DetectParseRegex *detect_parse)
#define DETECT_CONTENT_DEPTH
Per thread variable structure.
#define DETECT_CONTENT_IS_SINGLE(c)
#define DETECT_CONTENT_NEGATED
void DetectEngineInitializeFastPatternList(DetectEngineCtx *de_ctx)
SignatureInitData * init_data
int FastPatternSupportEnabledForSigMatchList(const DetectEngineCtx *de_ctx, const int list_id)
Checks if a particular list(Signature->sm_lists[]) is in the list of lists that need to be searched f...
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
struct SigMatch_ ** smlists
int SigGroupBuild(DetectEngineCtx *de_ctx)
Convert the signature list into the runtime match structure.
bool DetectEngineBufferTypeSupportsMpmGetById(const DetectEngineCtx *de_ctx, const int id)
TmEcode DetectEngineThreadCtxInit(ThreadVars *, void *, void **)
initialize thread specific detection engine context
#define FAIL_IF(expr)
Fail a test if expression evaluates to true.
TmEcode DetectEngineThreadCtxDeinit(ThreadVars *, void *)
void FlowShutdown(void)
shutdown the flow engine
void SupportFastPatternForSigMatchList(int list_id, int priority)
Lets one add a sm list id to be searched for potential fp supported keywords later.
SigTableElmt sigmatch_table[DETECT_TBLSIZE]
#define SIGMATCH_OPTIONAL_OPT
void DetectEngineFreeFastPatternList(DetectEngineCtx *de_ctx)
struct HtpBodyChunk_ * next
#define SCLogError(...)
Macro used to log ERROR messages.
#define DETECT_CONTENT_OFFSET
#define DETECT_CONTENT_FAST_PATTERN_ONLY
a single match condition for a signature
DetectEngineCtx * DetectEngineCtxInit(void)
void DetectFastPatternRegister(void)
Registration function for fast_pattern keyword.
SigMatch * DetectGetLastSMFromLists(const Signature *s,...)
Returns the sm with the largest index (added latest) from the lists passed to us.
#define DETECT_CONTENT_FAST_PATTERN
SCFPSupportSMList * fp_support_smlist_list
#define DETECT_CONTENT_WITHIN
void(* RegisterTests)(void)
uint32_t smlists_array_size
void UTHFreePackets(Packet **p, int numpkts)
UTHFreePackets: function to release the allocated data from UTHBuildPacket and the packet itself.