83 static void SigMatchTransferSigMatchAcrossLists(
SigMatch *sm,
114 #define CASE_CODE_STRING(E, S) case E: return S; break
125 #undef CASE_CODE_STRING
129 #define CASE_CODE(E) case E: return #E
147 Signature *s,
const char *arg,
int sm_type,
int sm_list,
153 if (arg != NULL && strcmp(arg,
"") != 0) {
162 "with a sticky buffer still set. Reset sticky buffer "
163 "with pkt_data before using the modifier.",
177 "found inside the rule without a content context. "
178 "Please use a \"content\" keyword before using the "
186 "be used with the rawbytes rule keyword",
192 "be used with the replace rule keyword",
231 bool reuse_buffer =
false;
244 SCLogError(
"failed to expand rule buffer array");
253 SCLogDebug(
"idx %u list %d set up curbuf %p s->init_data->buffer_index %u",
294 if (sm->
ctx != NULL) {
305 ptrdiff_t
offset = e - table;
319 if (st->
name != NULL) {
351 if (strcmp(
str,
"all") == 0) {
363 char *xsaveptr = NULL;
364 char *key = strtok_r(copy,
",", &xsaveptr);
365 while (key != NULL) {
371 "argument '%s' not found",
374 key = strtok_r(NULL,
",", &xsaveptr);
401 SCLogDebug(
"s:%p new:%p list:%d: %s, s->init_data->list_set %s s->init_data->list %d", s,
new,
435 SCLogDebug(
"reusing buffer %u as it isn't multi-capable", x);
445 SCLogError(
"failed to expand rule buffer array");
475 SCLogDebug(
"appended %s to list %d, rule pos %u (s->init_data->list %d)",
494 if (sm->
prev != NULL)
496 if (sm->
next != NULL)
538 if (sm_last == NULL || sm_new->
idx > sm_last->
idx)
550 if (sm_last == NULL || sm_new->
idx > sm_last->
idx)
572 SCLogDebug(
"skip x %u s->init_data->list %d (int)s->init_data->buffers[x].id %d", x,
581 for (sm_type = va_arg(ap,
int); sm_type != -1; sm_type = va_arg(ap,
int)) {
585 if (sm_last == NULL || sm_new->
idx > sm_last->
idx)
602 for (sm_type = va_arg(ap,
int); sm_type != -1; sm_type = va_arg(ap,
int))
607 if (sm_last == NULL || sm_new->
idx > sm_last->
idx)
632 va_start(ap, sm_list);
634 for (sm_type = va_arg(ap,
int); sm_type != -1; sm_type = va_arg(ap,
int))
636 sm_new = SigMatchGetLastSMByType(sm_list, sm_type);
639 if (sm_last == NULL || sm_new->
idx > sm_last->
idx)
670 va_start(ap, list_id);
672 for (sm_type = va_arg(ap,
int); sm_type != -1; sm_type = va_arg(ap,
int)) {
676 if (sm_last == NULL || sm_new->
idx > sm_last->
idx)
688 va_start(ap, list_id);
690 for (sm_type = va_arg(ap,
int); sm_type != -1; sm_type = va_arg(ap,
int)) {
691 sm_new = SigMatchGetLastSMByType(sm_list, sm_type);
694 if (sm_last == NULL || sm_new->
idx > sm_last->
idx)
717 if (sm_last == NULL || sm_new->
idx > sm_last->
idx)
725 if (sm_last == NULL || sm_new->
idx > sm_last->
idx)
732 static void SigMatchTransferSigMatchAcrossLists(
SigMatch *sm,
738 if (sm->
prev != NULL)
740 if (sm->
next != NULL)
743 if (sm == *src_sm_list)
744 *src_sm_list = sm->
next;
745 if (sm == *src_sm_list_tail)
746 *src_sm_list_tail = sm->
prev;
748 if (*dst_sm_list == NULL) {
750 *dst_sm_list_tail = sm;
758 *dst_sm_list_tail = sm;
785 SCLogError(
"Unable to find the sm in any of the "
799 static int DetectSetupDirection(
Signature *s,
char **
str,
bool only_dir)
802 if (strncmp(*
str,
"to_client", strlen(
"to_client")) == 0) {
803 *
str += strlen(
"to_client");
805 while (**
str && isblank(**
str)) {
811 SCLogError(
"unknown option: only accepts to_server or to_client");
821 while (**
str && isblank(**
str)) {
833 }
else if (strncmp(*
str,
"to_server", strlen(
"to_server")) == 0) {
834 *
str += strlen(
"to_server");
836 while (**
str && isblank(**
str)) {
842 SCLogError(
"unknown option: only accepts to_server or to_client");
852 while (**
str && isblank(**
str)) {
864 }
else if (only_dir) {
865 SCLogError(
"unknown option: only accepts to_server or to_client");
872 size_t output_size,
bool requires)
875 char *optname = NULL;
876 char *optvalue = NULL;
879 while (isblank(*optstr)) {
884 char *optend = optstr;
886 optend = strchr(optend,
';');
887 if (optend == NULL) {
891 else if (optend > optstr && *(optend -1 ) ==
'\\') {
900 char *optvalptr = strchr(optstr,
':');
902 *(optvalptr++) =
'\0';
905 for (
size_t i = strlen(optvalptr); i > 0; i--) {
906 if (isblank(optvalptr[i - 1])) {
907 optvalptr[i - 1] =
'\0';
913 optvalue = optvalptr;
917 for (
size_t i = strlen(optstr); i > 0; i--) {
918 if (isblank(optstr[i - 1])) {
919 optstr[i - 1] =
'\0';
928 bool requires_only = strcasecmp(optname,
"requires") == 0 || strcasecmp(optname,
"sid") == 0;
929 if ((requires && !requires_only) || (!requires && requires_only)) {
934 st = SigTableGet(optname);
935 if (st == NULL || st->
Setup == NULL) {
936 SCLogError(
"unknown rule keyword '%s'.", optname);
941 if (optvalue == NULL || strlen(optvalue) == 0) {
943 "invalid formatting or malformed option to %s keyword: '%s'", optname, optstr);
947 if (optvalue && strlen(optvalue)) {
948 SCLogError(
"unexpected option to %s keyword: '%s'", optname, optstr);
958 #define URL "https://suricata.io/our-story/deprecation-policy/"
961 "and will be removed soon. See %s",
965 "and will be removed soon. Use '%s' instead. "
972 SCLogError(
"keyword \'%s\' is not allowed with firewall rules", optname);
977 SCLogError(
"keyword \'%s\' is not allowed in firewall mode", optname);
984 if (optvalue != NULL && strlen(optvalue) > 0) {
985 size_t ovlen = strlen(optvalue);
986 char *ptr = optvalue;
996 SCLogError(
"invalid formatting or malformed option to %s keyword: \'%s\'", optname,
1002 SCLogWarning(
"keyword \'%s\' has not been tested for firewall rules", optname);
1019 SCLogError(
"invalid formatting or malformed option to %s keyword: \'%s\'", optname,
1025 SCLogError(
"invalid formatting to %s keyword: "
1026 "value must be double quoted \'%s\'",
1032 && ovlen && *ptr ==
'"')
1034 for (; ovlen > 0; ovlen--) {
1035 if (isblank(ptr[ovlen - 1])) {
1036 ptr[ovlen - 1] =
'\0';
1041 if (ovlen && ptr[ovlen - 1] !=
'"') {
1042 SCLogError(
"bad option value formatting (possible missing semicolon) "
1043 "for keyword %s: \'%s\'",
1051 ptr[ovlen - 1] =
'\0';
1056 "for keyword %s: \'%s\'",
1063 "quotes on %s keyword that doesn't support them: \'%s\'", optname, optstr);
1081 if (setup_ret < 0) {
1085 if (setup_ret == -2) {
1097 if (strlen(optend) > 0) {
1098 strlcpy(output, optend, output_size);
1113 Signature *s,
const char *addrstr,
char flag)
1115 SCLogDebug(
"Address Group \"%s\" to be parsed now", addrstr);
1119 if (strcasecmp(addrstr,
"any") == 0)
1127 if (strcasecmp(addrstr,
"any") == 0)
1142 static bool IsBuiltIn(
const char *n)
1144 return strcmp(n,
"request_started") == 0 || strcmp(n,
"response_started") == 0 ||
1145 strcmp(n,
"request_complete") == 0 || strcmp(n,
"response_complete") == 0;
1160 if (strcmp(alproto_name,
"http") == 0)
1161 alproto_name =
"http1";
1162 SCLogDebug(
"alproto %u/%s", a, alproto_name);
1164 const int max_progress_ts =
1166 const int max_progress_tc =
1169 char ts_tx_started[64];
1170 snprintf(ts_tx_started,
sizeof(ts_tx_started),
"%s:request_started:generic", alproto_name);
1173 SCLogDebug(
"- hook %s:%s list %s (%u)", alproto_name,
"request_name", ts_tx_started,
1174 (uint32_t)strlen(ts_tx_started));
1176 char tc_tx_started[64];
1177 snprintf(tc_tx_started,
sizeof(tc_tx_started),
"%s:response_started:generic", alproto_name);
1180 SCLogDebug(
"- hook %s:%s list %s (%u)", alproto_name,
"response_name", tc_tx_started,
1181 (uint32_t)strlen(tc_tx_started));
1183 char ts_tx_complete[64];
1184 snprintf(ts_tx_complete,
sizeof(ts_tx_complete),
"%s:request_complete:generic",
1188 SCLogDebug(
"- hook %s:%s list %s (%u)", alproto_name,
"request_name", ts_tx_complete,
1189 (uint32_t)strlen(ts_tx_complete));
1191 char tc_tx_complete[64];
1192 snprintf(tc_tx_complete,
sizeof(tc_tx_complete),
"%s:response_complete:generic",
1196 SCLogDebug(
"- hook %s:%s list %s (%u)", alproto_name,
"response_name", tc_tx_complete,
1197 (uint32_t)strlen(tc_tx_complete));
1199 for (
int p = 0;
p <= max_progress_ts;
p++) {
1201 IPPROTO_TCP , a,
p, STREAM_TOSERVER);
1202 if (
name != NULL && !IsBuiltIn(
name)) {
1204 snprintf(list_name,
sizeof(list_name),
"%s:%s:generic", alproto_name,
name);
1205 SCLogDebug(
"- hook %s:%s list %s (%u)", alproto_name,
name, list_name,
1206 (uint32_t)strlen(list_name));
1212 for (
int p = 0;
p <= max_progress_tc;
p++) {
1214 IPPROTO_TCP , a,
p, STREAM_TOCLIENT);
1215 if (
name != NULL && !IsBuiltIn(
name)) {
1217 snprintf(list_name,
sizeof(list_name),
"%s:%s:generic", alproto_name,
name);
1218 SCLogDebug(
"- hook %s:%s list %s (%u)", alproto_name,
name, list_name,
1219 (uint32_t)strlen(list_name));
1245 if (strcmp(
str,
"flow_start") == 0) {
1247 }
else if (strcmp(
str,
"pre_flow") == 0) {
1249 }
else if (strcmp(
str,
"pre_stream") == 0) {
1251 }
else if (strcmp(
str,
"all") == 0) {
1264 return "flow_start";
1268 return "pre_stream";
1280 .t.pkt.ph = HookPktFromString(hook_str),
1288 static int SigParseProtoHookPkt(
Signature *s,
const char *proto_hook,
const char *
p,
const char *h)
1301 SCLogDebug(
"protocol:%s hook:%s: type:%s parsed hook:%s",
p, h,
1311 .t.app.alproto = alproto,
1312 .t.app.app_progress = progress,
1320 static int SigParseProtoHookApp(
Signature *s,
const char *proto_hook,
const char *
p,
const char *h)
1323 if (strcmp(h,
"request_started") == 0) {
1327 }
else if (strcmp(h,
"response_started") == 0) {
1331 }
else if (strcmp(h,
"request_complete") == 0) {
1335 }
else if (strcmp(h,
"response_complete") == 0) {
1341 IPPROTO_TCP , s->
alproto, h, STREAM_TOSERVER);
1342 if (progress_ts >= 0) {
1347 IPPROTO_TCP , s->
alproto, h, STREAM_TOCLIENT);
1348 if (progress_tc < 0) {
1356 char generic_hook_name[64];
1357 snprintf(generic_hook_name,
sizeof(generic_hook_name),
"%s:%s:generic",
p, h);
1360 SCLogError(
"no list registered as %s for hook %s", generic_hook_name, proto_hook);
1365 SCLogDebug(
"protocol:%s hook:%s: type:%s alproto:%u hook:%d",
p, h,
1375 printf(
"=========Supported Rule Protocols=========\n");
1392 static int SigParseProto(
Signature *s,
const char *protostr)
1395 if (strlen(protostr) > 32)
1401 const char *h = NULL;
1403 bool has_hook = strchr(
proto,
':') != NULL;
1405 char *xsaveptr = NULL;
1406 p = strtok_r(
proto,
":", &xsaveptr);
1407 h = strtok_r(NULL,
":", &xsaveptr);
1432 if (SigParseProtoHookApp(s, protostr,
p, h) < 0) {
1433 SCLogError(
"protocol \"%s\" does not support hook \"%s\"",
p, h);
1440 "in a signature. Either detection for this protocol "
1441 "is not yet supported OR detection has been disabled for "
1442 "protocol through the yaml option "
1443 "app-layer.protocols.%s.detection-enabled",
1447 }
else if (h != NULL) {
1448 SCLogDebug(
"non-app-layer rule with %s:%s",
p, h);
1450 if (SigParseProtoHookPkt(s, protostr,
p, h) < 0) {
1451 SCLogError(
"protocol \"%s\" does not support hook \"%s\"",
p, h);
1480 Signature *s,
const char *portstr,
char flag)
1486 SCLogDebug(
"Port group \"%s\" to be parsed", portstr);
1489 if (strcasecmp(portstr,
"any") == 0)
1493 }
else if (flag == 1) {
1494 if (strcasecmp(portstr,
"any") == 0)
1509 static int SigParseActionRejectValidate(
const char *action)
1511 #ifdef HAVE_LIBNET11
1512 #if defined HAVE_LIBCAP_NG && !defined HAVE_LIBNET_CAPABILITIES
1515 "incompatible with POSIX based capabilities with privs dropping. "
1516 "For rejects to work, run as root/super user.");
1522 "required for action \"%s\" but is not compiled into Suricata",
1532 static uint8_t ActionStringToFlags(
const char *action)
1534 if (strcasecmp(action,
"alert") == 0) {
1536 }
else if (strcasecmp(action,
"drop") == 0) {
1538 }
else if (strcasecmp(action,
"pass") == 0) {
1540 }
else if (strcasecmp(action,
"reject") == 0 ||
1541 strcasecmp(action,
"rejectsrc") == 0)
1543 if (!(SigParseActionRejectValidate(action)))
1546 }
else if (strcasecmp(action,
"rejectdst") == 0) {
1547 if (!(SigParseActionRejectValidate(action)))
1550 }
else if (strcasecmp(action,
"rejectboth") == 0) {
1551 if (!(SigParseActionRejectValidate(action)))
1554 }
else if (strcasecmp(action,
"config") == 0) {
1556 }
else if (strcasecmp(action,
"accept") == 0) {
1559 SCLogError(
"An invalid action \"%s\" was given", action);
1575 static int SigParseActionDo(
const char *action_in,
const int idx,
const bool fw_rule,
1576 uint8_t *action_out, uint8_t *scope_out)
1579 strlcpy(action, action_in,
sizeof(action));
1580 const char *a = action;
1581 const char *o = NULL;
1583 bool has_scope = strchr(action,
':') != NULL;
1585 char *xsaveptr = NULL;
1586 a = strtok_r(action,
":", &xsaveptr);
1587 o = strtok_r(NULL,
":", &xsaveptr);
1591 SCLogError(
"invalid protocol specification '%s'", action_in);
1595 uint8_t
flags = ActionStringToFlags(a);
1608 SCLogError(
"only accept, config, drop and reject actions allowed as primary action "
1615 SCLogError(
"accept, config, drop and reject actions not allowed as secondary action "
1624 uint8_t scope_flags = 0;
1626 if (strcmp(o,
"packet") == 0) {
1628 }
else if (strcmp(o,
"flow") == 0) {
1631 SCLogError(
"invalid action scope '%s' in action '%s': only 'packet' and 'flow' "
1637 if (strcmp(o,
"packet") == 0) {
1639 }
else if (strcmp(o,
"hook") == 0) {
1641 }
else if (strcmp(o,
"tx") == 0) {
1643 }
else if (strcmp(o,
"flow") == 0) {
1647 "invalid action scope '%s' in action '%s': only 'packet', 'flow', 'tx' and "
1653 if (strcmp(o,
"packet") == 0) {
1656 SCLogError(
"invalid action scope '%s' in action '%s': only 'packet' allowed", o,
1661 SCLogError(
"invalid action scope '%s' in action '%s': scope only supported for actions "
1662 "'drop', 'pass' and 'reject'",
1666 if (*scope_out != 0 && *scope_out != scope_flags) {
1667 SCLogError(
"multi-action rules cannot use different action scopes");
1670 *scope_out = scope_flags;
1674 if (fw_rule && *scope_out == 0) {
1675 SCLogError(
"firewall rules require setting an explicit action scope");
1680 SCLogError(
"'accept' action only supported for firewall rules");
1683 *action_out |=
flags;
1687 static int SigParseAction(
Signature *s,
const char *action_in)
1696 FatalError(
"could not duplicate opt string");
1699 char *xsaveptr = NULL;
1700 char *a = strtok_r(copy,
",", &xsaveptr);
1706 a = strtok_r(NULL,
",", &xsaveptr);
1727 static inline int SigParseToken(
char **input,
char *output,
1728 const size_t output_size)
1730 size_t len = *input == NULL ? 0 : strlen(*input);
1736 while (
len && isblank(**input)) {
1741 char *endptr = strpbrk(*input,
" \t\n\r");
1742 if (endptr != NULL) {
1745 strlcpy(output, *input, output_size);
1762 static inline int SigParseList(
char **input,
char *output,
1763 const size_t output_size)
1766 size_t len = *input != NULL ? strlen(*input) : 0;
1772 while (
len && isblank(**input)) {
1778 for (i = 0; i <
len; i++) {
1779 char c = (*input)[i];
1782 }
else if (c ==
']') {
1784 }
else if (c ==
' ') {
1795 strlcpy(output, *input, output_size);
1796 *input = *input + i + 1;
1816 SigParseToken(&index, parser->
action,
sizeof(parser->
action));
1822 SigParseList(&index, parser->
src,
sizeof(parser->
src));
1825 SigParseList(&index, parser->
sp,
sizeof(parser->
sp));
1831 SigParseList(&index, parser->
dst,
sizeof(parser->
dst));
1834 SigParseList(&index, parser->
dp,
sizeof(parser->
dp));
1837 if (index == NULL) {
1841 while (isspace(*index) || *index ==
'(') {
1844 for (
size_t i = strlen(index); i > 0; i--) {
1845 if (isspace(index[i - 1]) || index[i - 1] ==
')') {
1846 index[i - 1] =
'\0';
1858 if (SigParseAction(s, parser->
action) < 0)
1861 if (SigParseProto(s, parser->
protocol) < 0)
1864 if (strcmp(parser->
direction,
"<>") == 0) {
1866 }
else if (strcmp(parser->
direction,
"=>") == 0) {
1868 SCLogError(
"transactional bidirectional rules not supported for firewall rules");
1873 }
else if (strcmp(parser->
direction,
"->") != 0) {
1874 SCLogError(
"\"%s\" is not a valid direction modifier, "
1875 "\"->\" and \"<>\" are supported.",
1902 static inline bool CheckAscii(
const char *
str)
1904 for (
size_t i = 0; i < strlen(
str); i++) {
1905 if (
str[i] < 0x20) {
1907 if (
str[i] == 0x0a ||
str[i] == 0x0d ||
str[i] == 0x09) {
1911 }
else if (
str[i] == 0x7f) {
1935 if (!SCCheckUtf8(sigstr)) {
1940 if (!CheckAscii(sigstr)) {
1941 SCLogError(
"rule contains invalid (control) characters");
1945 int ret = SigParseBasics(
de_ctx, s, sigstr, parser, addrs_direction, requires);
1952 if (strlen(parser->
opts) > 0) {
1953 size_t buffer_size = strlen(parser->
opts) + 1;
1955 char input[buffer_size];
1956 char output[buffer_size];
1957 memset(input, 0x00, buffer_size);
1958 memcpy(input, parser->
opts, strlen(parser->
opts) + 1);
1964 memset(output, 0x00, buffer_size);
1965 ret = SigParseOptions(
de_ctx, s, input, output, buffer_size, requires);
1967 memcpy(input, output, buffer_size);
1999 memset(b, 0,
sizeof(*b));
2047 static void SigMetadataFree(
Signature *s)
2054 if (s == NULL || s->
metadata == NULL) {
2061 next_mdata = mdata->
next;
2092 next_ref = ref->
next;
2146 while (sm != NULL) {
2155 while (sm != NULL) {
2176 if (s->
sp != NULL) {
2179 if (s->
dp != NULL) {
2228 if (s->
alproto == *alprotos) {
2271 }
else if (i == 1) {
2303 if (!AppProtoIsValid(alproto)) {
2327 alproto = AppProtoCommon(s->
alproto, alproto);
2329 SCLogError(
"can't set rule app proto to %s: already set to %s",
2356 if (addr_match4 == NULL) {
2362 addr_match4[idx].
ip =
SCNtohl(da->ip.addr_data32[0]);
2363 addr_match4[idx].
ip2 =
SCNtohl(da->ip2.addr_data32[0]);
2382 if (addr_match6 == NULL) {
2388 addr_match6[idx].
ip[0] =
SCNtohl(da->ip.addr_data32[0]);
2389 addr_match6[idx].
ip[1] =
SCNtohl(da->ip.addr_data32[1]);
2390 addr_match6[idx].
ip[2] =
SCNtohl(da->ip.addr_data32[2]);
2391 addr_match6[idx].
ip[3] =
SCNtohl(da->ip.addr_data32[3]);
2392 addr_match6[idx].
ip2[0] =
SCNtohl(da->ip2.addr_data32[0]);
2393 addr_match6[idx].
ip2[1] =
SCNtohl(da->ip2.addr_data32[1]);
2394 addr_match6[idx].
ip2[2] =
SCNtohl(da->ip2.addr_data32[2]);
2395 addr_match6[idx].
ip2[3] =
SCNtohl(da->ip2.addr_data32[3]);
2408 static void SigBuildAddressMatchArray(
Signature *s)
2425 static int SigMatchListLen(
SigMatch *sm)
2428 for (; sm != NULL; sm = sm->
next)
2439 int len = SigMatchListLen(
head);
2445 FatalError(
"initializing the detection engine failed");
2451 for (; sm != NULL; sm = sm->
next, smd++) {
2469 SCLogDebug(
"no prefilter for SIG_FLAG_FW_HOOK_LTE sig");
2496 SCLogDebug(
"s %u: no mpm; prefilter? de_ctx->prefilter_setting %u "
2497 "s->init_data->has_possible_prefilter %s",
2511 prefilter_list =
MIN(prefilter_list, sm->
type);
2521 if (sm->
type == prefilter_list) {
2538 static bool DetectRuleValidateTable(
const Signature *s)
2547 if (kw_tables_supported != 0 && (kw_tables_supported & table_as_flag) == 0) {
2548 SCLogError(
"rule %u uses hook \"%s\", but keyword \"%s\" doesn't support this hook",
2559 SCLogError(
"rule %u is loaded as a firewall rule, but does not specify an "
2569 SCLogError(
"rule %u uses action scope \"packet\" for an non-UDP app hook",
2587 SCLogError(
"rule %u: auto-accept notation (<hook) can only be used with accept:flow, "
2588 "accept:tx and accept:hook",
2597 static void DetectRuleSetTable(
Signature *s)
2630 if (!DetectFirewallRuleValidate(
de_ctx, s))
2636 static int SigValidateCheckBuffers(
2639 bool has_frame =
false;
2640 bool has_app =
false;
2641 bool has_pkt =
false;
2642 bool has_pmatch =
false;
2648 nlists += (nlists > 0);
2652 SCLogError(
"rule %u setup buffer %s but didn't add matches to it", s->
id,
2666 struct BufferVsDir {
2669 } bufdir[nlists + 1];
2670 memset(&bufdir, 0, (nlists + 1) *
sizeof(
struct BufferVsDir));
2684 if (b->
head == NULL) {
2689 has_frame |= bt->
frame;
2695 "specific matches (like dsize, flags, ttl) with stream / "
2696 "state matching by matching on app layer proto (like using "
2697 "http_* keywords).");
2702 for (; app != NULL; app = app->
next) {
2730 bufdir[b->
id].ts += (app->
dir == 0);
2731 bufdir[b->
id].tc += (app->
dir == 1);
2743 SCLogError(
"engine progress value doesn't match hook");
2761 if (has_pmatch && has_frame) {
2762 SCLogError(
"can't mix pure content and frame inspection");
2765 if (has_app && has_frame) {
2766 SCLogError(
"can't mix app-layer buffer and frame inspection");
2769 if (has_pkt && has_frame) {
2770 SCLogError(
"can't mix pkt buffer and frame inspection");
2774 for (
int x = 0; x < nlists; x++) {
2775 if (bufdir[x].
ts == 0 && bufdir[x].tc == 0)
2777 (*ts_excl) += (bufdir[x].ts > 0 && bufdir[x].tc == 0);
2778 (*tc_excl) += (bufdir[x].ts == 0 && bufdir[x].tc > 0);
2779 (*dir_amb) += (bufdir[x].ts > 0 && bufdir[x].tc > 0);
2788 static int SigValidatePacketStream(
const Signature *s)
2792 "tcp-stream or flow:only_stream. Invalidating signature.");
2798 static int SigConsolidateDirection(
2799 Signature *s,
const int ts_excl,
const int tc_excl,
const int dir_amb)
2802 if (!ts_excl || !tc_excl) {
2803 SCLogError(
"rule %u should use both directions, but does not", s->
id);
2807 SCLogError(
"rule %u means to use both directions, cannot have keywords ambiguous about "
2812 }
else if (ts_excl && tc_excl) {
2814 "rule %u mixes keywords with conflicting directions, a transactional rule with => "
2818 }
else if (ts_excl) {
2819 SCLogDebug(
"%u: implied rule direction is toserver", s->
id);
2821 SCLogError(
"rule %u mixes keywords with conflicting directions", s->
id);
2824 }
else if (tc_excl) {
2825 SCLogDebug(
"%u: implied rule direction is toclient", s->
id);
2827 SCLogError(
"rule %u mixes keywords with conflicting directions", s->
id);
2830 }
else if (dir_amb) {
2831 SCLogDebug(
"%u: rule direction cannot be deduced from keywords", s->
id);
2836 static void SigConsolidateTcpBuffer(
Signature *s)
2868 static bool SigInspectsFiles(
const Signature *s)
2879 static int SigValidateFileHandling(
const Signature *s)
2881 if (!SigInspectsFiles(s)) {
2888 "support file matching",
2905 SCLogError(
"No protocol support file matching");
2910 SCLogError(
"protocol HTTP2 doesn't support file name matching");
2916 static bool SigValidateEthernet(
const Signature *s)
2921 SCLogError(
"can't use ports with ether or arp rule");
2929 static bool SigValidateProtoPkthdr(
const Signature *s)
2932 SCLogError(
"protocol 'pkthdr' is for decoder-events only");
2948 static int SigValidateConsolidate(
2953 if (SigValidateFirewall(
de_ctx, s) == 0)
2956 if (SigValidatePacketStream(s) == 0) {
2960 if (!SigValidateEthernet(s)) {
2968 if (SigValidateCheckBuffers(
de_ctx, s, &ts_excl, &tc_excl, &dir_amb) == 0) {
2972 if (SigConsolidateDirection(s, ts_excl, tc_excl, dir_amb) == 0) {
2976 SigConsolidateTcpBuffer(s);
2979 DetectRuleSetTable(s);
2981 if (!SigValidateProtoPkthdr(s)) {
2988 int r = SigValidateFileHandling(s);
2992 if (SigInspectsFiles(s)) {
2997 if (DetectRuleValidateTable(s) ==
false) {
3020 memset(&parser, 0x00,
sizeof(parser));
3025 if (firewall_rule) {
3042 int ret = SigParse(
de_ctx, sig, sigstr, dir, &parser,
true);
3049 }
else if (ret < 0) {
3055 SCLogError(
"Signature missing required value \"sid\".");
3060 ret = SigParse(
de_ctx, sig, sigstr, dir, &parser,
false);
3066 }
else if (ret == -2) {
3069 }
else if (ret < 0) {
3074 if (sig->
prio == -1)
3081 int override_needed = 0;
3085 override_needed = 1;
3087 override_needed = 1;
3091 override_needed = 0;
3100 if (override_needed)
3110 for ( ; sm != NULL; sm = sm->
next) {
3134 SCLogDebug(
"sig %"PRIu32
" SIG_FLAG_APPLAYER: %s, SIG_FLAG_PACKET: %s",
3138 SigBuildAddressMatchArray(sig);
3149 SigSetupPrefilter(
de_ctx, sig);
3152 if (SigValidateConsolidate(
de_ctx, sig, &parser, dir) == 0) {
3171 static bool SigHasSameSourceAndDestination(
const Signature *s)
3213 if (SigHasSameSourceAndDestination(sig)) {
3214 SCLogInfo(
"Rule with ID %u is bidirectional, but source and destination are the same, "
3215 "treating the rule as unidirectional", sig->
id);
3220 if (sig->
next == NULL) {
3250 return SigInitDo(
de_ctx, sigstr,
false);
3255 return SigInitDo(
de_ctx, sigstr,
true);
3264 static void DetectParseDupSigFreeFunc(
void *data)
3280 static uint32_t DetectParseDupSigHashFunc(
HashListTable *ht,
void *data, uint16_t datalen)
3299 static char DetectParseDupSigCompareFunc(
void *data1, uint16_t len1,
void *data2,
3305 if (sw1 == NULL || sw2 == NULL ||
3306 sw1->
s == NULL || sw2->
s == NULL)
3310 if (sw1->
s->
id == sw2->
s->
id && sw1->
s->
gid == sw2->
s->
gid)
return 1;
3326 DetectParseDupSigHashFunc,
3327 DetectParseDupSigCompareFunc,
3328 DetectParseDupSigFreeFunc);
3389 if (sw_dup == NULL) {
3402 (
void *)&sw_tmp, 0);
3416 if (sw->
s->
rev <= sw_dup->
s->
rev) {
3425 if (sw_dup->
s_prev == NULL) {
3433 sw_temp.
s = sw_dup->
s->
next;
3437 if (sw_temp.
s != NULL) {
3439 (
void *)&sw_temp, 0);
3460 sw_temp.
s = sw_dup->
s->
next;
3468 if (sw_temp.
s != NULL) {
3470 (
void *)&sw_temp, 0);
3486 (
void *)&sw_tmp, 0);
3488 if (sw_old->
s != sw_dup->
s) {
3531 int dup_sig = DetectEngineSignatureIsDuplicate(
de_ctx, sig);
3535 SCLogError(
"Duplicate signature \"%s\"", sigstr);
3537 }
else if (dup_sig == 2) {
3539 " so the older sig replaced by this new signature \"%s\"",
3544 if (sig->
next != NULL) {
3561 return (dup_sig == 0 || dup_sig == 2) ? sig : NULL;
3565 if (sig != NULL && sig->
next != NULL) {
3603 int dup_sig = DetectEngineSignatureIsDuplicate(
de_ctx, sig);
3607 SCLogError(
"Duplicate signature \"%s\"", sigstr);
3609 }
else if (dup_sig == 2) {
3611 " so the older sig replaced by this new signature \"%s\"",
3616 if (sig->
next != NULL) {
3633 return (dup_sig == 0 || dup_sig == 2) ? sig : NULL;
3637 if (sig != NULL && sig->
next != NULL) {
3650 int start_offset,
int options)
3652 *match = pcre2_match_data_create_from_pattern(parse_regex->
regex, NULL);
3654 return pcre2_match(parse_regex->
regex, (PCRE2_SPTR8)
str, strlen(
str), options, start_offset,
3655 *match, parse_regex->
context);
3662 pcre2_code_free(r->
regex);
3665 pcre2_match_context_free(r->
context);
3680 g_detect_parse_regex_list = NULL;
3689 FatalError(
"failed to alloc memory for pcre free list");
3692 r->
next = g_detect_parse_regex_list;
3693 g_detect_parse_regex_list = r;
3701 detect_parse->
regex =
3702 pcre2_compile((PCRE2_SPTR8)parse_str, PCRE2_ZERO_TERMINATED, opts, &en, &eo, NULL);
3703 if (detect_parse->
regex == NULL) {
3704 PCRE2_UCHAR errbuffer[256];
3705 pcre2_get_error_message(en, errbuffer,
sizeof(errbuffer));
3706 SCLogError(
"pcre compile of \"%s\" failed at "
3708 parse_str, en, errbuffer);
3711 detect_parse->
context = pcre2_match_context_create(NULL);
3712 if (detect_parse->
context == NULL) {
3713 SCLogError(
"pcre2 could not create match context");
3714 pcre2_code_free(detect_parse->
regex);
3715 detect_parse->
regex = NULL;
3730 if (detect_parse == NULL) {
3734 detect_parse->
regex =
3735 pcre2_compile((PCRE2_SPTR8)parse_str, PCRE2_ZERO_TERMINATED, opts, &en, &eo, NULL);
3736 if (detect_parse->
regex == NULL) {
3737 PCRE2_UCHAR errbuffer[256];
3738 pcre2_get_error_message(en, errbuffer,
sizeof(errbuffer));
3739 SCLogError(
"pcre2 compile of \"%s\" failed at "
3741 parse_str, (
int)eo, errbuffer);
3746 detect_parse->
next = g_detect_parse_regex_list;
3747 g_detect_parse_regex_list = detect_parse;
3748 return detect_parse;
3752 pcre2_match_data *match_data, uint32_t number, PCRE2_UCHAR *buffer, PCRE2_SIZE *bufflen)
3754 int r = pcre2_substring_copy_bynumber(match_data, number, buffer, bufflen);
3755 if (r == PCRE2_ERROR_UNSET) {
3764 pcre2_match_data *match_data, uint32_t number, PCRE2_UCHAR **bufferptr, PCRE2_SIZE *bufflen)
3766 int r = pcre2_substring_get_bynumber(match_data, number, bufferptr, bufflen);
3767 if (r == PCRE2_ERROR_UNSET) {
3782 static uint32_t PolicySignatureHashFunc(
HashTable *ht,
void *data, uint16_t datalen)
3791 static char PolicySignatureCompareFunc(
3792 void *data1, uint16_t datalen1,
void *data2, uint16_t datalen2)
3797 if (s1 == NULL || s2 == NULL)
3804 static void PolicySignatureHashFree(
void *data)
3837 snprintf(out, out_size,
"rejectdst:%s", as);
3839 snprintf(out, out_size,
"rejectboth:%s", as);
3841 snprintf(out, out_size,
"rejectsrc:%s", as);
3844 snprintf(out, out_size,
"drop:%s", as);
3846 snprintf(out, out_size,
"accept:%s", as);
3852 strlcat(out,
",pass:flow", out_size);
3858 strlcat(out,
",alert", out_size);
3880 snprintf(msg,
sizeof(msg),
"SURICATA FW default packet policy");
3882 if (s->
msg == NULL) {
3900 static int AddAppPolicySignature(
HashTable *ht,
const int direction,
const AppProto alproto,
3901 const char *app_name,
const uint8_t hook,
const char *hookname,
3908 snprintf(msg,
sizeof(msg),
"SURICATA FW default app policy");
3910 if (s->
msg == NULL) {
3939 if (policy_actions == NULL) {
3940 SCLogDebug(
"fw: no policy at %s", policy_name);
3945 uint8_t action_scope = 0;
3950 if (SigParseActionDo(paction->
val, idx,
true, &action, &action_scope) < 0)
3959 static int DoParseAppPolicy(
const char *prefix,
const AppProto app_proto,
const char *hookname,
3960 const uint8_t state,
const uint8_t complete_state,
const int direction,
3963 char policy_name[256];
3964 const char *in_name = hookname;
3965 if (hookname == NULL) {
3967 if (direction == STREAM_TOSERVER)
3968 hookname =
"request-started";
3970 hookname =
"response-started";
3971 }
else if (state == complete_state) {
3972 if (direction == STREAM_TOSERVER)
3973 hookname =
"request-complete";
3975 hookname =
"response-complete";
3977 if (hookname == NULL)
3983 for (
int i = 0; nname[i] !=
'\0'; i++) {
3984 if (nname[i] ==
'_')
3989 int r = snprintf(policy_name,
sizeof(policy_name),
"%s.%s.%s", prefix, app_name, nname);
3991 if (r < 0 || (
size_t)r >=
sizeof(policy_name)) {
3992 FatalError(
"internal error: failed to assemble firewall policy config string");
3996 if (direction == STREAM_TOSERVER)
3997 pol = &app_fw_policies[app_proto].
ts[state];
3999 pol = &app_fw_policies[app_proto].
tc[state];
4000 r = DoParsePolicy(policy_name, pol);
4001 if (r == 0 && in_name != NULL) {
4003 if (direction == STREAM_TOSERVER)
4004 hookname =
"request-started";
4006 hookname =
"response-started";
4007 }
else if (state == complete_state) {
4008 if (direction == STREAM_TOSERVER)
4009 hookname =
"request-complete";
4011 hookname =
"response-complete";
4013 if (hookname == NULL)
4015 r = snprintf(policy_name,
sizeof(policy_name),
"%s.%s.%s", prefix, app_name, hookname);
4016 if (r < 0 || (
size_t)r >=
sizeof(policy_name)) {
4017 FatalError(
"internal error: failed to assemble firewall policy config string");
4020 r = DoParsePolicy(policy_name, pol);
4026 return AddAppPolicySignature(fw_policies->
policy_signatures, direction, app_proto, app_name,
4027 state, hookname, pol);
4037 if (fw_policies == NULL)
4040 if (app_fw_policies == NULL)
4043 512, PolicySignatureHashFunc, PolicySignatureCompareFunc, PolicySignatureHashFree);
4057 for (
int i = 0; i < 48; i++) {
4075 char policy_name[256];
4076 char prefix[96] =
"firewall.policies";
4082 if (fw_policies == NULL)
4085 if (app_fw_policies == NULL)
4088 r = snprintf(policy_name,
sizeof(policy_name),
"%s.packet-filter", prefix);
4089 if (r < 0 || (
size_t)r >=
sizeof(policy_name)) {
4090 FatalError(
"internal error: failed to assemble firewall policy config string");
4096 if (AddPktPolicySignature(fw_policies,
4101 r = snprintf(policy_name,
sizeof(policy_name),
"%s.packet-pre-flow", prefix);
4102 if (r < 0 || (
size_t)r >=
sizeof(policy_name)) {
4103 FatalError(
"internal error: failed to assemble firewall policy config string");
4113 r = snprintf(policy_name,
sizeof(policy_name),
"%s.packet-pre-stream", prefix);
4114 if (r < 0 || (
size_t)r >=
sizeof(policy_name)) {
4115 FatalError(
"internal error: failed to assemble firewall policy config string");
4126 if (!AppProtoIsValid(a))
4129 const uint8_t complete_state_ts =
4131 for (uint8_t state = 0; state <= complete_state_ts; state++) {
4134 if (DoParseAppPolicy(prefix, a,
name, state, complete_state_ts, STREAM_TOSERVER,
4135 fw_policies, app_fw_policies) < 0)
4139 const uint8_t complete_state_tc =
4141 for (uint8_t state = 0; state <= complete_state_tc; state++) {
4144 if (DoParseAppPolicy(prefix, a,
name, state, complete_state_tc, STREAM_TOCLIENT,
4145 fw_policies, app_fw_policies) < 0)
4154 const AppProto alproto,
const int direction,
const uint8_t hook)
4177 static int SigParseTest01 (
void)
4186 sig =
SigInit(
de_ctx,
"alert tcp 1.2.3.4 any -> !1.2.3.4 any (msg:\"SigParseTest01\"; sid:1;)");
4196 static int SigParseTest02 (
void)
4211 sig =
SigInit(
de_ctx,
"alert tcp any !21:902 -> any any (msg:\"ET MALWARE Suspicious 220 Banner on Local Port\"; content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; sid:2003055; rev:4;)");
4239 static int SigParseTest03 (
void)
4248 sig =
SigInit(
de_ctx,
"alert tcp 1.2.3.4 any <- !1.2.3.4 any (msg:\"SigParseTest03\"; sid:1;)");
4251 printf(
"expected NULL got sig ptr %p: ",sig);
4260 static int SigParseTest04 (
void)
4269 sig =
SigInit(
de_ctx,
"alert tcp 1.2.3.4 1024: -> !1.2.3.4 1024: (msg:\"SigParseTest04\"; sid:1;)");
4280 static int SigParseTest05 (
void)
4289 sig =
SigInit(
de_ctx,
"alert tcp 1.2.3.4 1024:65536 -> !1.2.3.4 any (msg:\"SigParseTest05\"; sid:1;)");
4293 printf(
"signature didn't fail to parse as we expected: ");
4303 static int SigParseTest06 (
void)
4312 sig =
SigInit(
de_ctx,
"alert tcp any any -> any any (flow:to_server; content:\"GET\"; nocase; http_method; uricontent:\"/uri/\"; nocase; content:\"Host|3A| abc\"; nocase; sid:1; rev:1;)");
4316 printf(
"signature failed to parse: ");
4330 static int SigParseTest07(
void)
4352 static int SigParseTest08(
void)
4375 static int SigParseTest09(
void)
4426 static int SigParseTest10(
void)
4458 static int SigParseTest11(
void)
4469 "drop tcp any any -> any 80 (msg:\"Snort_Inline is blocking the http link\"; sid:1;) ");
4471 printf(
"sig 1 didn't parse: ");
4476 "the http link\"; sid:2;) ");
4478 printf(
"sig 2 didn't parse: ");
4492 static int SigParseTest12(
void)
4504 printf(
"sig 1 should have given an error: ");
4518 static int SigParseTest13(
void)
4530 printf(
"sig 1 invalidated: failure");
4535 printf(
"sig doesn't have stream flag set\n");
4540 printf(
"sig has packet flag set\n");
4555 static int SigParseTest14(
void)
4567 printf(
"sig 1 invalidated: failure");
4572 printf(
"sig doesn't have packet flag set\n");
4577 printf(
"sig has stream flag set\n");
4592 static int SigParseTest15(
void)
4604 printf(
"sig 1 invalidated: failure");
4609 printf(
"sig doesn't have packet flag set\n");
4614 printf(
"sig doesn't have stream flag set\n");
4629 static int SigParseTest16(
void)
4641 printf(
"sig 1 invalidated: failure");
4646 printf(
"sig doesn't have packet flag set\n");
4651 printf(
"sig doesn't have stream flag set\n");
4666 static int SigParseTest17(
void)
4678 printf(
"sig 1 invalidated: failure");
4683 printf(
"sig doesn't have packet flag set\n");
4688 printf(
"sig doesn't have stream flag set\n");
4701 static int SigParseTest18 (
void)
4709 if (
DetectEngineAppendSig(
de_ctx,
"alert tcp 1.2.3.4 any -> !1.2.3.4 any (msg:\"SigParseTest01\"; sid:99999999999999999999;)") != NULL)
4720 static int SigParseTest19 (
void)
4728 if (
DetectEngineAppendSig(
de_ctx,
"alert tcp 1.2.3.4 any -> !1.2.3.4 any (msg:\"SigParseTest01\"; sid:1; gid:99999999999999999999;)") != NULL)
4739 static int SigParseTest20 (
void)
4747 if (
DetectEngineAppendSig(
de_ctx,
"alert tcp 1.2.3.4 any -> !1.2.3.4 any (msg:\"SigParseTest01\"; sid:1; rev:99999999999999999999;)") != NULL)
4758 static int SigParseTest21 (
void)
4777 static int SigParseTest22 (
void)
4785 if (
DetectEngineAppendSig(
de_ctx,
"alert tcp [10.10.10.0/24, !10.10.10.247] any -> [10.10.10.0/24, !10.10.10.247] any (sid:1;)") == NULL)
4798 static int SigParseTest23(
void)
4813 static int SigParseBidirecTest06 (
void)
4833 static int SigParseBidirecTest07 (
void)
4853 static int SigParseBidirecTest08 (
void)
4873 static int SigParseBidirecTest09 (
void)
4893 static int SigParseBidirecTest10 (
void)
4913 static int SigParseBidirecTest11 (
void)
4933 static int SigParseBidirecTest12 (
void)
4953 static int SigParseBidirecTest13 (
void)
4972 static int SigParseBidirecTest14 (
void)
4993 static int SigTestBidirec01 (
void)
5005 if (sig->
next != NULL)
5024 static int SigTestBidirec02 (
void)
5043 if (sig->
next == NULL)
5048 if (copy->
next != NULL)
5069 static int SigTestBidirec03 (
void)
5081 const char *sigs[3];
5082 sigs[0] =
"alert tcp any any -> 192.168.1.1 any (msg:\"SigTestBidirec03 sid 1\"; sid:1;)";
5083 sigs[1] =
"alert tcp any any <> 192.168.1.1 any (msg:\"SigTestBidirec03 sid 2 bidirectional\"; sid:2;)";
5084 sigs[2] =
"alert tcp any any -> 192.168.1.1 any (msg:\"SigTestBidirec03 sid 3\"; sid:3;)";
5091 if (sig->
next == NULL)
5102 uint8_t rawpkt1_ether[] = {
5103 0x00,0x50,0x56,0xea,0x00,0xbd,0x00,0x0c,
5104 0x29,0x40,0xc8,0xb5,0x08,0x00,0x45,0x00,
5105 0x01,0xa8,0xb9,0xbb,0x40,0x00,0x40,0x06,
5106 0xe0,0xbf,0xc0,0xa8,0x1c,0x83,0xc0,0xa8,
5107 0x01,0x01,0xb9,0x0a,0x00,0x50,0x6f,0xa2,
5108 0x92,0xed,0x7b,0xc1,0xd3,0x4d,0x50,0x18,
5109 0x16,0xd0,0xa0,0x6f,0x00,0x00,0x47,0x45,
5110 0x54,0x20,0x2f,0x20,0x48,0x54,0x54,0x50,
5111 0x2f,0x31,0x2e,0x31,0x0d,0x0a,0x48,0x6f,
5112 0x73,0x74,0x3a,0x20,0x31,0x39,0x32,0x2e,
5113 0x31,0x36,0x38,0x2e,0x31,0x2e,0x31,0x0d,
5114 0x0a,0x55,0x73,0x65,0x72,0x2d,0x41,0x67,
5115 0x65,0x6e,0x74,0x3a,0x20,0x4d,0x6f,0x7a,
5116 0x69,0x6c,0x6c,0x61,0x2f,0x35,0x2e,0x30,
5117 0x20,0x28,0x58,0x31,0x31,0x3b,0x20,0x55,
5118 0x3b,0x20,0x4c,0x69,0x6e,0x75,0x78,0x20,
5119 0x78,0x38,0x36,0x5f,0x36,0x34,0x3b,0x20,
5120 0x65,0x6e,0x2d,0x55,0x53,0x3b,0x20,0x72,
5121 0x76,0x3a,0x31,0x2e,0x39,0x2e,0x30,0x2e,
5122 0x31,0x34,0x29,0x20,0x47,0x65,0x63,0x6b,
5123 0x6f,0x2f,0x32,0x30,0x30,0x39,0x30,0x39,
5124 0x30,0x32,0x31,0x37,0x20,0x55,0x62,0x75,
5125 0x6e,0x74,0x75,0x2f,0x39,0x2e,0x30,0x34,
5126 0x20,0x28,0x6a,0x61,0x75,0x6e,0x74,0x79,
5127 0x29,0x20,0x46,0x69,0x72,0x65,0x66,0x6f,
5128 0x78,0x2f,0x33,0x2e,0x30,0x2e,0x31,0x34,
5129 0x0d,0x0a,0x41,0x63,0x63,0x65,0x70,0x74,
5130 0x3a,0x20,0x74,0x65,0x78,0x74,0x2f,0x68,
5131 0x74,0x6d,0x6c,0x2c,0x61,0x70,0x70,0x6c,
5132 0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,0x2f,
5133 0x78,0x68,0x74,0x6d,0x6c,0x2b,0x78,0x6d,
5134 0x6c,0x2c,0x61,0x70,0x70,0x6c,0x69,0x63,
5135 0x61,0x74,0x69,0x6f,0x6e,0x2f,0x78,0x6d,
5136 0x6c,0x3b,0x71,0x3d,0x30,0x2e,0x39,0x2c,
5137 0x2a,0x2f,0x2a,0x3b,0x71,0x3d,0x30,0x2e,
5138 0x38,0x0d,0x0a,0x41,0x63,0x63,0x65,0x70,
5139 0x74,0x2d,0x4c,0x61,0x6e,0x67,0x75,0x61,
5140 0x67,0x65,0x3a,0x20,0x65,0x6e,0x2d,0x75,
5141 0x73,0x2c,0x65,0x6e,0x3b,0x71,0x3d,0x30,
5142 0x2e,0x35,0x0d,0x0a,0x41,0x63,0x63,0x65,
5143 0x70,0x74,0x2d,0x45,0x6e,0x63,0x6f,0x64,
5144 0x69,0x6e,0x67,0x3a,0x20,0x67,0x7a,0x69,
5145 0x70,0x2c,0x64,0x65,0x66,0x6c,0x61,0x74,
5146 0x65,0x0d,0x0a,0x41,0x63,0x63,0x65,0x70,
5147 0x74,0x2d,0x43,0x68,0x61,0x72,0x73,0x65,
5148 0x74,0x3a,0x20,0x49,0x53,0x4f,0x2d,0x38,
5149 0x38,0x35,0x39,0x2d,0x31,0x2c,0x75,0x74,
5150 0x66,0x2d,0x38,0x3b,0x71,0x3d,0x30,0x2e,
5151 0x37,0x2c,0x2a,0x3b,0x71,0x3d,0x30,0x2e,
5152 0x37,0x0d,0x0a,0x4b,0x65,0x65,0x70,0x2d,
5153 0x41,0x6c,0x69,0x76,0x65,0x3a,0x20,0x33,
5154 0x30,0x30,0x0d,0x0a,0x43,0x6f,0x6e,0x6e,
5155 0x65,0x63,0x74,0x69,0x6f,0x6e,0x3a,0x20,
5156 0x6b,0x65,0x65,0x70,0x2d,0x61,0x6c,0x69,
5157 0x76,0x65,0x0d,0x0a,0x0d,0x0a };
5167 uint32_t sids[3] = {1, 2, 3};
5168 uint32_t results[3] = {1, 1, 1};
5184 static int SigTestBidirec04 (
void)
5199 sig =
DetectEngineAppendSig(
de_ctx,
"alert tcp 192.168.1.1 any <> any any (msg:\"SigTestBidirec03 sid 2 bidirectional\"; sid:2;)");
5204 if (sig->
next == NULL)
5216 if (sig->
next == NULL)
5227 uint8_t rawpkt1_ether[] = {
5228 0x00,0x50,0x56,0xea,0x00,0xbd,0x00,0x0c,
5229 0x29,0x40,0xc8,0xb5,0x08,0x00,0x45,0x00,
5230 0x01,0xa8,0xb9,0xbb,0x40,0x00,0x40,0x06,
5231 0xe0,0xbf,0xc0,0xa8,0x1c,0x83,0xc0,0xa8,
5232 0x01,0x01,0xb9,0x0a,0x00,0x50,0x6f,0xa2,
5233 0x92,0xed,0x7b,0xc1,0xd3,0x4d,0x50,0x18,
5234 0x16,0xd0,0xa0,0x6f,0x00,0x00,0x47,0x45,
5235 0x54,0x20,0x2f,0x20,0x48,0x54,0x54,0x50,
5236 0x2f,0x31,0x2e,0x31,0x0d,0x0a,0x48,0x6f,
5237 0x73,0x74,0x3a,0x20,0x31,0x39,0x32,0x2e,
5238 0x31,0x36,0x38,0x2e,0x31,0x2e,0x31,0x0d,
5239 0x0a,0x55,0x73,0x65,0x72,0x2d,0x41,0x67,
5240 0x65,0x6e,0x74,0x3a,0x20,0x4d,0x6f,0x7a,
5241 0x69,0x6c,0x6c,0x61,0x2f,0x35,0x2e,0x30,
5242 0x20,0x28,0x58,0x31,0x31,0x3b,0x20,0x55,
5243 0x3b,0x20,0x4c,0x69,0x6e,0x75,0x78,0x20,
5244 0x78,0x38,0x36,0x5f,0x36,0x34,0x3b,0x20,
5245 0x65,0x6e,0x2d,0x55,0x53,0x3b,0x20,0x72,
5246 0x76,0x3a,0x31,0x2e,0x39,0x2e,0x30,0x2e,
5247 0x31,0x34,0x29,0x20,0x47,0x65,0x63,0x6b,
5248 0x6f,0x2f,0x32,0x30,0x30,0x39,0x30,0x39,
5249 0x30,0x32,0x31,0x37,0x20,0x55,0x62,0x75,
5250 0x6e,0x74,0x75,0x2f,0x39,0x2e,0x30,0x34,
5251 0x20,0x28,0x6a,0x61,0x75,0x6e,0x74,0x79,
5252 0x29,0x20,0x46,0x69,0x72,0x65,0x66,0x6f,
5253 0x78,0x2f,0x33,0x2e,0x30,0x2e,0x31,0x34,
5254 0x0d,0x0a,0x41,0x63,0x63,0x65,0x70,0x74,
5255 0x3a,0x20,0x74,0x65,0x78,0x74,0x2f,0x68,
5256 0x74,0x6d,0x6c,0x2c,0x61,0x70,0x70,0x6c,
5257 0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,0x2f,
5258 0x78,0x68,0x74,0x6d,0x6c,0x2b,0x78,0x6d,
5259 0x6c,0x2c,0x61,0x70,0x70,0x6c,0x69,0x63,
5260 0x61,0x74,0x69,0x6f,0x6e,0x2f,0x78,0x6d,
5261 0x6c,0x3b,0x71,0x3d,0x30,0x2e,0x39,0x2c,
5262 0x2a,0x2f,0x2a,0x3b,0x71,0x3d,0x30,0x2e,
5263 0x38,0x0d,0x0a,0x41,0x63,0x63,0x65,0x70,
5264 0x74,0x2d,0x4c,0x61,0x6e,0x67,0x75,0x61,
5265 0x67,0x65,0x3a,0x20,0x65,0x6e,0x2d,0x75,
5266 0x73,0x2c,0x65,0x6e,0x3b,0x71,0x3d,0x30,
5267 0x2e,0x35,0x0d,0x0a,0x41,0x63,0x63,0x65,
5268 0x70,0x74,0x2d,0x45,0x6e,0x63,0x6f,0x64,
5269 0x69,0x6e,0x67,0x3a,0x20,0x67,0x7a,0x69,
5270 0x70,0x2c,0x64,0x65,0x66,0x6c,0x61,0x74,
5271 0x65,0x0d,0x0a,0x41,0x63,0x63,0x65,0x70,
5272 0x74,0x2d,0x43,0x68,0x61,0x72,0x73,0x65,
5273 0x74,0x3a,0x20,0x49,0x53,0x4f,0x2d,0x38,
5274 0x38,0x35,0x39,0x2d,0x31,0x2c,0x75,0x74,
5275 0x66,0x2d,0x38,0x3b,0x71,0x3d,0x30,0x2e,
5276 0x37,0x2c,0x2a,0x3b,0x71,0x3d,0x30,0x2e,
5277 0x37,0x0d,0x0a,0x4b,0x65,0x65,0x70,0x2d,
5278 0x41,0x6c,0x69,0x76,0x65,0x3a,0x20,0x33,
5279 0x30,0x30,0x0d,0x0a,0x43,0x6f,0x6e,0x6e,
5280 0x65,0x63,0x74,0x69,0x6f,0x6e,0x3a,0x20,
5281 0x6b,0x65,0x65,0x70,0x2d,0x61,0x6c,0x69,
5282 0x76,0x65,0x0d,0x0a,0x0d,0x0a };
5331 static int SigParseTestNegation01 (
void)
5345 static int SigParseTestNegation02 (
void)
5351 "alert tcp any !any -> any any (msg:\"SigTest41-02 src ip is !any \"; "
5352 "classtype:misc-activity; sid:410002; rev:1;)");
5360 static int SigParseTestNegation03 (
void)
5366 "alert tcp any any -> any [80:!80] (msg:\"SigTest41-03 dst port [80:!80] \"; "
5367 "classtype:misc-activity; sid:410003; rev:1;)");
5375 static int SigParseTestNegation04 (
void)
5386 s =
SigInit(
de_ctx,
"alert tcp any any -> any [80,!80] (msg:\"SigTest41-03 dst port [80:!80] \"; classtype:misc-activity; sid:410003; rev:1;)");
5401 static int SigParseTestNegation05 (
void)
5412 s =
SigInit(
de_ctx,
"alert tcp any any -> [192.168.0.2,!192.168.0.2] any (msg:\"SigTest41-04 dst ip [192.168.0.2,!192.168.0.2] \"; classtype:misc-activity; sid:410004; rev:1;)");
5427 static int SigParseTestNegation06 (
void)
5438 s =
SigInit(
de_ctx,
"alert tcp any any -> any [100:1000,!1:20000] (msg:\"SigTest41-05 dst port [100:1000,!1:20000] \"; classtype:misc-activity; sid:410005; rev:1;)");
5454 static int SigParseTestNegation07 (
void)
5460 de_ctx,
"alert tcp any any -> [192.168.0.2,!192.168.0.0/24] any (sid:410006;)");
5469 static int SigParseTestNegation08 (
void)
5481 "alert tcp any any -> [192.168.0.0/16,!192.168.0.0/24] any (sid:410006; rev:1;)");
5496 static int SigParseTestMpm01 (
void)
5505 sig =
SigInit(
de_ctx,
"alert tcp any any -> any any (msg:\"mpm test\"; content:\"abcd\"; sid:1;)");
5507 printf(
"sig failed to init: ");
5512 printf(
"sig doesn't have content list: ");
5527 static int SigParseTestMpm02 (
void)
5536 sig =
SigInit(
de_ctx,
"alert tcp any any -> any any (msg:\"mpm test\"; content:\"abcd\"; content:\"abcdef\"; sid:1;)");
5538 printf(
"sig failed to init: ");
5543 printf(
"sig doesn't have content list: ");
5558 static int SigParseTestAppLayerTLS01(
void)
5569 s =
SigInit(
de_ctx,
"alert tls any any -> any any (msg:\"SigParseTestAppLayerTLS01 \"; sid:410006; rev:1;)");
5571 printf(
"parsing sig failed: ");
5576 printf(
"alproto not set: ");
5593 static int SigParseTestAppLayerTLS02(
void)
5604 s =
SigInit(
de_ctx,
"alert tls any any -> any any (msg:\"SigParseTestAppLayerTLS02 \"; tls.version:1.0; sid:410006; rev:1;)");
5606 printf(
"parsing sig failed: ");
5611 printf(
"alproto not set: ");
5627 static int SigParseTestAppLayerTLS03(
void)
5634 "alert tls any any -> any any (msg:\"SigParseTestAppLayerTLS03 \"; "
5635 "tls.version:2.5; sid:410006; rev:1;)");
5641 static int SigParseTestUnbalancedQuotes01(
void)
5647 "alert http any any -> any any (msg:\"SigParseTestUnbalancedQuotes01\"; "
5648 "pcre:\"/\\/[a-z]+\\.php\\?[a-z]+?=\\d{7}&[a-z]+?=\\d{7,8}$/U\" "
5649 "flowbits:set,et.exploitkitlanding; classtype:trojan-activity; sid:2017078; rev:5;)");
5655 static int SigParseTestContentGtDsize01(
void)
5662 "dsize:21; content:\"0123456789001234567890|00 00|\"; "
5669 static int SigParseTestContentGtDsize02(
void)
5676 "dsize:21; content:\"0123456789|00 00|\"; offset:10; "
5693 static int SigParseBidirWithSameSrcAndDest01(
void)
5710 "alert tcp [1.2.3.4, 5.6.7.8] [80, 81] <> [5.6.7.8, 1.2.3.4] [81, 80] (sid:3;)");
5719 static int SigParseBidirWithSameSrcAndDest02(
void)
5727 de_ctx,
"alert tcp 1.2.3.4 any <> [1.2.3.4, 5.6.7.8, ::1] any (sid:1;)");
5734 de_ctx,
"alert tcp [1.2.3.4, ::1] [80, 81, 82] <> [1.2.3.4, ::1] [80, 81] (sid:2;)");
5741 "alert tcp [1.2.3.4, ::1, ABCD:AAAA::1] [80] <> [1.2.3.4, ::1] [80, 81] (sid:3;)");
5748 de_ctx,
"alert tcp [!1.2.3.4, 1.2.3.0/24] any <> [1.2.3.0/24, !1.2.3.4] any (sid:4;)");
5755 de_ctx,
"alert tcp [1.2.3.4, 1.2.3.0/24] any <> [1.2.3.0/24, !1.2.3.4] any (sid:5;)");
5764 static int SigParseTestActionReject(
void)
5770 de_ctx,
"reject tcp 1.2.3.4 any -> !1.2.3.4 any (msg:\"SigParseTest01\"; sid:1;)");
5771 #ifdef HAVE_LIBNET11
5782 static int SigParseTestActionDrop(
void)
5788 de_ctx,
"drop tcp 1.2.3.4 any -> !1.2.3.4 any (msg:\"SigParseTest01\"; sid:1;)");
5796 static int SigSetMultiAppProto(
void)
5871 static int DetectSetupDirection01(
void)
5876 char *
str = (
char *)
"to_client";
5877 FAIL_IF(DetectSetupDirection(s, &
str,
true) < 0);
5882 static int DetectSetupDirection02(
void)
5886 char *
str = (
char *)
"to_server";
5887 FAIL_IF(DetectSetupDirection(s, &
str,
true) < 0);
5889 str = (
char *)
"to_client";
5890 FAIL_IF(DetectSetupDirection(s, &
str,
true) >= 0);
5896 static int DetectSetupDirection03(
void)
5900 char *
str = (
char *)
"to_client , something";
5901 FAIL_IF(DetectSetupDirection(s, &
str,
false) < 0);
5903 str = (
char *)
"to_client,something";
5904 FAIL_IF(DetectSetupDirection(s, &
str,
false) < 0);
5910 static int DetectSetupDirection04(
void)
5915 char *
str = (
char *)
"to_client_toto";
5916 FAIL_IF(DetectSetupDirection(s, &
str,
true) >= 0);
5918 str = (
char *)
"to_client_toto";
5919 FAIL_IF(DetectSetupDirection(s, &
str,
false) < 0);
5921 str = (
char *)
"to_client,something";
5923 FAIL_IF(DetectSetupDirection(s, &
str,
true) >= 0);
5960 UtRegisterTest(
"SigParseTest21 -- address with space", SigParseTest21);
5961 UtRegisterTest(
"SigParseTest22 -- address with space", SigParseTest22);
5962 UtRegisterTest(
"SigParseTest23 -- carriage return", SigParseTest23);
5977 UtRegisterTest(
"SigParseTestNegation01", SigParseTestNegation01);
5978 UtRegisterTest(
"SigParseTestNegation02", SigParseTestNegation02);
5979 UtRegisterTest(
"SigParseTestNegation03", SigParseTestNegation03);
5980 UtRegisterTest(
"SigParseTestNegation04", SigParseTestNegation04);
5981 UtRegisterTest(
"SigParseTestNegation05", SigParseTestNegation05);
5982 UtRegisterTest(
"SigParseTestNegation06", SigParseTestNegation06);
5983 UtRegisterTest(
"SigParseTestNegation07", SigParseTestNegation07);
5984 UtRegisterTest(
"SigParseTestNegation08", SigParseTestNegation08);
5987 UtRegisterTest(
"SigParseTestAppLayerTLS01", SigParseTestAppLayerTLS01);
5988 UtRegisterTest(
"SigParseTestAppLayerTLS02", SigParseTestAppLayerTLS02);
5989 UtRegisterTest(
"SigParseTestAppLayerTLS03", SigParseTestAppLayerTLS03);
5990 UtRegisterTest(
"SigParseTestUnbalancedQuotes01", SigParseTestUnbalancedQuotes01);
5993 SigParseTestContentGtDsize01);
5995 SigParseTestContentGtDsize02);
5998 SigParseBidirWithSameSrcAndDest01);
6000 SigParseBidirWithSameSrcAndDest02);
6001 UtRegisterTest(
"SigParseTestActionReject", SigParseTestActionReject);
6002 UtRegisterTest(
"SigParseTestActionDrop", SigParseTestActionDrop);
6006 UtRegisterTest(
"DetectSetupDirection01", DetectSetupDirection01);
6007 UtRegisterTest(
"DetectSetupDirection02", DetectSetupDirection02);
6008 UtRegisterTest(
"DetectSetupDirection03", DetectSetupDirection03);
6009 UtRegisterTest(
"DetectSetupDirection04", DetectSetupDirection04);