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);
1167 for (uint8_t s = 1; s <= max_sub_state; s++) {
1171 if (sub_state_name == NULL)
1174 char ts_tx_started[64];
1175 snprintf(ts_tx_started,
sizeof(ts_tx_started),
"%s:%s:request_started:generic",
1176 alproto_name, sub_state_name);
1180 char tc_tx_started[64];
1181 snprintf(tc_tx_started,
sizeof(tc_tx_started),
"%s:%s:response_started:generic",
1182 alproto_name, sub_state_name);
1186 char ts_tx_complete[64];
1187 snprintf(ts_tx_complete,
sizeof(ts_tx_complete),
"%s:%s:request_complete:generic",
1188 alproto_name, sub_state_name);
1192 char tc_tx_complete[64];
1193 snprintf(tc_tx_complete,
sizeof(tc_tx_complete),
"%s:%s:response_complete:generic",
1194 alproto_name, sub_state_name);
1199 for (uint8_t state = 0; state <= max_state; state++) {
1200 const char *state_name =
1202 BUG_ON(state_name == NULL);
1204 if (state_name != NULL && !IsBuiltIn(state_name)) {
1206 snprintf(list_name,
sizeof(list_name),
"%s:%s:%s:generic", alproto_name,
1207 sub_state_name, state_name);
1213 for (uint8_t state = 0; state <= max_state; state++) {
1214 const char *state_name =
1216 BUG_ON(state_name == NULL);
1217 if (state_name != NULL && !IsBuiltIn(state_name)) {
1219 snprintf(list_name,
sizeof(list_name),
"%s:%s:%s:generic", alproto_name,
1220 sub_state_name, state_name);
1227 const uint8_t max_progress_ts =
1229 const uint8_t max_progress_tc =
1232 char ts_tx_started[64];
1233 snprintf(ts_tx_started,
sizeof(ts_tx_started),
"%s:request_started:generic",
1237 SCLogDebug(
"- hook %s:%s list %s (%u)", alproto_name,
"request_name", ts_tx_started,
1238 (uint32_t)strlen(ts_tx_started));
1240 char tc_tx_started[64];
1241 snprintf(tc_tx_started,
sizeof(tc_tx_started),
"%s:response_started:generic",
1245 SCLogDebug(
"- hook %s:%s list %s (%u)", alproto_name,
"response_name", tc_tx_started,
1246 (uint32_t)strlen(tc_tx_started));
1248 char ts_tx_complete[64];
1249 snprintf(ts_tx_complete,
sizeof(ts_tx_complete),
"%s:request_complete:generic",
1253 SCLogDebug(
"- hook %s:%s list %s (%u)", alproto_name,
"request_name", ts_tx_complete,
1254 (uint32_t)strlen(ts_tx_complete));
1256 char tc_tx_complete[64];
1257 snprintf(tc_tx_complete,
sizeof(tc_tx_complete),
"%s:response_complete:generic",
1261 SCLogDebug(
"- hook %s:%s list %s (%u)", alproto_name,
"response_name", tc_tx_complete,
1262 (uint32_t)strlen(tc_tx_complete));
1264 for (uint8_t
p = 0;
p <= max_progress_ts;
p++) {
1266 IPPROTO_TCP , a,
p, STREAM_TOSERVER);
1267 if (
name != NULL && !IsBuiltIn(
name)) {
1269 snprintf(list_name,
sizeof(list_name),
"%s:%s:generic", alproto_name,
name);
1270 SCLogDebug(
"- hook %s:%s list %s (%u)", alproto_name,
name, list_name,
1271 (uint32_t)strlen(list_name));
1277 for (uint8_t
p = 0;
p <= max_progress_tc;
p++) {
1279 IPPROTO_TCP , a,
p, STREAM_TOCLIENT);
1280 if (
name != NULL && !IsBuiltIn(
name)) {
1282 snprintf(list_name,
sizeof(list_name),
"%s:%s:generic", alproto_name,
name);
1283 SCLogDebug(
"- hook %s:%s list %s (%u)", alproto_name,
name, list_name,
1284 (uint32_t)strlen(list_name));
1311 if (strcmp(
str,
"flow_start") == 0) {
1313 }
else if (strcmp(
str,
"pre_flow") == 0) {
1315 }
else if (strcmp(
str,
"pre_stream") == 0) {
1317 }
else if (strcmp(
str,
"all") == 0) {
1330 return "flow_start";
1334 return "pre_stream";
1346 .t.pkt.ph = HookPktFromString(hook_str),
1354 static int SigParseProtoHookPkt(
Signature *s,
const char *proto_hook,
const char *
p,
const char *h)
1367 SCLogDebug(
"protocol:%s hook:%s: type:%s parsed hook:%s",
p, h,
1377 .t.app.alproto = alproto,
1378 .t.app.sub_state = sub_state,
1379 .t.app.app_progress = progress,
1387 static int SigParseProtoHookApp(
1388 Signature *s,
const char *proto_hook,
const char *
p,
const char *in_h)
1391 char generic_hook_name[256];
1392 strlcpy(hook, in_h,
sizeof(hook));
1393 const char *h = hook;
1394 const char *t = NULL;
1395 uint8_t sub_state = 0;
1397 bool has_type = strchr(hook,
':') != NULL;
1400 t = strtok_r(hook,
":", &rem);
1404 if (h == NULL || strlen(h) == 0) {
1405 SCLogError(
"invalid hook specification '%s'", hook);
1410 if (strlen(t) == 0) {
1411 SCLogError(
"invalid tx type specification '%s'", hook);
1414 if (strcmp(
p,
"http2") == 0 || strcmp(
p,
"doh2") == 0) {
1415 if (strcmp(t,
"stream") == 0) {
1416 sub_state = HTTP2TxTypeStream;
1417 }
else if (strcmp(t,
"global") == 0) {
1418 sub_state = HTTP2TxTypeGlobal;
1420 SCLogError(
"unknown %s tx type specification '%s': valid values are 'stream' "
1426 SCLogError(
"sub states currently only supported for http2 and doh2");
1437 if (strcmp(h,
"request_started") == 0) {
1441 }
else if (strcmp(h,
"response_started") == 0) {
1445 }
else if (strcmp(h,
"request_complete") == 0) {
1448 }
else if (strcmp(h,
"response_complete") == 0) {
1452 const int8_t progress_ts =
1454 if (progress_ts >= 0) {
1459 s->
alproto, sub_state, h, STREAM_TOCLIENT);
1460 if (progress_tc < 0) {
1467 snprintf(generic_hook_name,
sizeof(generic_hook_name),
"%s:%s:%s:generic",
p, t, h);
1471 "protocol %s requires a substate specification: %s:<sub_state>:%s",
p,
p, hook);
1482 if (strcmp(h,
"request_started") == 0) {
1486 }
else if (strcmp(h,
"response_started") == 0) {
1490 }
else if (strcmp(h,
"request_complete") == 0) {
1494 }
else if (strcmp(h,
"response_complete") == 0) {
1500 IPPROTO_TCP , s->
alproto, h, STREAM_TOSERVER);
1501 if (progress_ts >= 0) {
1509 IPPROTO_TCP , s->
alproto, h, STREAM_TOCLIENT);
1517 snprintf(generic_hook_name,
sizeof(generic_hook_name),
"%s:%s:generic",
p, h);
1519 SCLogDebug(
"generic_hook_name %s", generic_hook_name);
1523 SCLogError(
"no list registered as %s for hook %s", generic_hook_name, proto_hook);
1528 SCLogDebug(
"protocol:%s hook:%s: type:%s alproto:%u hook:%d",
p, h,
1538 printf(
"=========Supported Rule Protocols=========\n");
1555 static int SigParseProto(
Signature *s,
const char *protostr)
1558 if (strlen(protostr) >= 64)
1564 const char *h = NULL;
1566 bool has_hook = strchr(
proto,
':') != NULL;
1569 p = strtok_r(
proto,
":", &rem);
1573 if (
p == NULL || strlen(
p) == 0) {
1588 if (strlen(h) == 0) {
1592 if (SigParseProtoHookApp(s, protostr,
p, h) < 0) {
1593 SCLogError(
"protocol \"%s\" does not support hook \"%s\"",
p, h);
1600 "in a signature. Either detection for this protocol "
1601 "is not yet supported OR detection has been disabled for "
1602 "protocol through the yaml option "
1603 "app-layer.protocols.%s.detection-enabled",
1607 }
else if (h != NULL) {
1608 SCLogDebug(
"non-app-layer rule with %s:%s",
p, h);
1610 if (SigParseProtoHookPkt(s, protostr,
p, h) < 0) {
1611 SCLogError(
"protocol \"%s\" does not support hook \"%s\"",
p, h);
1640 Signature *s,
const char *portstr,
char flag)
1646 SCLogDebug(
"Port group \"%s\" to be parsed", portstr);
1649 if (strcasecmp(portstr,
"any") == 0)
1653 }
else if (flag == 1) {
1654 if (strcasecmp(portstr,
"any") == 0)
1669 static int SigParseActionRejectValidate(
const char *action)
1671 #ifdef HAVE_LIBNET11
1672 #if defined HAVE_LIBCAP_NG && !defined HAVE_LIBNET_CAPABILITIES
1675 "incompatible with POSIX based capabilities with privs dropping. "
1676 "For rejects to work, run as root/super user.");
1682 "required for action \"%s\" but is not compiled into Suricata",
1692 static uint8_t ActionStringToFlags(
const char *action)
1694 if (strcasecmp(action,
"alert") == 0) {
1696 }
else if (strcasecmp(action,
"drop") == 0) {
1698 }
else if (strcasecmp(action,
"pass") == 0) {
1700 }
else if (strcasecmp(action,
"reject") == 0 ||
1701 strcasecmp(action,
"rejectsrc") == 0)
1703 if (!(SigParseActionRejectValidate(action)))
1706 }
else if (strcasecmp(action,
"rejectdst") == 0) {
1707 if (!(SigParseActionRejectValidate(action)))
1710 }
else if (strcasecmp(action,
"rejectboth") == 0) {
1711 if (!(SigParseActionRejectValidate(action)))
1714 }
else if (strcasecmp(action,
"config") == 0) {
1716 }
else if (strcasecmp(action,
"accept") == 0) {
1719 SCLogError(
"An invalid action \"%s\" was given", action);
1735 static int SigParseActionDo(
const char *action_in,
const int idx,
const bool fw_rule,
1736 uint8_t *action_out, uint8_t *scope_out)
1739 strlcpy(action, action_in,
sizeof(action));
1740 const char *a = action;
1741 const char *o = NULL;
1743 bool has_scope = strchr(action,
':') != NULL;
1745 char *xsaveptr = NULL;
1746 a = strtok_r(action,
":", &xsaveptr);
1747 o = strtok_r(NULL,
":", &xsaveptr);
1751 SCLogError(
"invalid protocol specification '%s'", action_in);
1755 uint8_t
flags = ActionStringToFlags(a);
1768 SCLogError(
"only accept, config, drop and reject actions allowed as primary action "
1775 SCLogError(
"accept, config, drop and reject actions not allowed as secondary action "
1784 uint8_t scope_flags = 0;
1786 if (strcmp(o,
"packet") == 0) {
1788 }
else if (strcmp(o,
"flow") == 0) {
1791 SCLogError(
"invalid action scope '%s' in action '%s': only 'packet' and 'flow' "
1797 if (strcmp(o,
"packet") == 0) {
1799 }
else if (strcmp(o,
"hook") == 0) {
1801 }
else if (strcmp(o,
"tx") == 0) {
1803 }
else if (strcmp(o,
"flow") == 0) {
1807 "invalid action scope '%s' in action '%s': only 'packet', 'flow', 'tx' and "
1813 if (strcmp(o,
"packet") == 0) {
1816 SCLogError(
"invalid action scope '%s' in action '%s': only 'packet' allowed", o,
1821 SCLogError(
"invalid action scope '%s' in action '%s': scope only supported for actions "
1822 "'drop', 'pass' and 'reject'",
1826 if (*scope_out != 0 && *scope_out != scope_flags) {
1827 SCLogError(
"multi-action rules cannot use different action scopes");
1830 *scope_out = scope_flags;
1834 if (fw_rule && *scope_out == 0) {
1835 SCLogError(
"firewall rules require setting an explicit action scope");
1840 SCLogError(
"'accept' action only supported for firewall rules");
1843 *action_out |=
flags;
1847 static int SigParseAction(
Signature *s,
const char *action_in)
1856 FatalError(
"could not duplicate opt string");
1859 char *xsaveptr = NULL;
1860 char *a = strtok_r(copy,
",", &xsaveptr);
1866 a = strtok_r(NULL,
",", &xsaveptr);
1887 static inline int SigParseToken(
char **input,
char *output,
1888 const size_t output_size)
1890 size_t len = *input == NULL ? 0 : strlen(*input);
1896 while (
len && isblank(**input)) {
1901 char *endptr = strpbrk(*input,
" \t\n\r");
1902 if (endptr != NULL) {
1905 strlcpy(output, *input, output_size);
1922 static inline int SigParseList(
char **input,
char *output,
1923 const size_t output_size)
1926 size_t len = *input != NULL ? strlen(*input) : 0;
1932 while (
len && isblank(**input)) {
1938 for (i = 0; i <
len; i++) {
1939 char c = (*input)[i];
1942 }
else if (c ==
']') {
1944 }
else if (c ==
' ') {
1955 strlcpy(output, *input, output_size);
1956 *input = *input + i + 1;
1976 SigParseToken(&index, parser->
action,
sizeof(parser->
action));
1982 SigParseList(&index, parser->
src,
sizeof(parser->
src));
1985 SigParseList(&index, parser->
sp,
sizeof(parser->
sp));
1991 SigParseList(&index, parser->
dst,
sizeof(parser->
dst));
1994 SigParseList(&index, parser->
dp,
sizeof(parser->
dp));
1997 if (index == NULL) {
2001 while (isspace(*index) || *index ==
'(') {
2004 for (
size_t i = strlen(index); i > 0; i--) {
2005 if (isspace(index[i - 1]) || index[i - 1] ==
')') {
2006 index[i - 1] =
'\0';
2018 if (SigParseAction(s, parser->
action) < 0)
2021 if (SigParseProto(s, parser->
protocol) < 0)
2024 if (strcmp(parser->
direction,
"<>") == 0) {
2026 }
else if (strcmp(parser->
direction,
"=>") == 0) {
2028 SCLogError(
"transactional bidirectional rules not supported for firewall rules");
2033 }
else if (strcmp(parser->
direction,
"->") != 0) {
2034 SCLogError(
"\"%s\" is not a valid direction modifier, "
2035 "\"->\" and \"<>\" are supported.",
2062 static inline bool CheckAscii(
const char *
str)
2064 for (
size_t i = 0; i < strlen(
str); i++) {
2065 if (
str[i] < 0x20) {
2067 if (
str[i] == 0x0a ||
str[i] == 0x0d ||
str[i] == 0x09) {
2071 }
else if (
str[i] == 0x7f) {
2095 if (!SCCheckUtf8(sigstr)) {
2100 if (!CheckAscii(sigstr)) {
2101 SCLogError(
"rule contains invalid (control) characters");
2105 int ret = SigParseBasics(
de_ctx, s, sigstr, parser, addrs_direction, requires);
2112 if (strlen(parser->
opts) > 0) {
2113 size_t buffer_size = strlen(parser->
opts) + 1;
2115 char input[buffer_size];
2116 char output[buffer_size];
2117 memset(input, 0x00, buffer_size);
2118 memcpy(input, parser->
opts, strlen(parser->
opts) + 1);
2124 memset(output, 0x00, buffer_size);
2125 ret = SigParseOptions(
de_ctx, s, input, output, buffer_size, requires);
2127 memcpy(input, output, buffer_size);
2159 memset(b, 0,
sizeof(*b));
2207 static void SigMetadataFree(
Signature *s)
2214 if (s == NULL || s->
metadata == NULL) {
2221 next_mdata = mdata->
next;
2252 next_ref = ref->
next;
2306 while (sm != NULL) {
2315 while (sm != NULL) {
2336 if (s->
sp != NULL) {
2339 if (s->
dp != NULL) {
2388 if (s->
alproto == *alprotos) {
2431 }
else if (i == 1) {
2463 if (!AppProtoIsValid(alproto)) {
2487 alproto = AppProtoCommon(s->
alproto, alproto);
2489 SCLogError(
"can't set rule app proto to %s: already set to %s",
2516 if (addr_match4 == NULL) {
2522 addr_match4[idx].
ip =
SCNtohl(da->ip.addr_data32[0]);
2523 addr_match4[idx].
ip2 =
SCNtohl(da->ip2.addr_data32[0]);
2542 if (addr_match6 == NULL) {
2548 addr_match6[idx].
ip[0] =
SCNtohl(da->ip.addr_data32[0]);
2549 addr_match6[idx].
ip[1] =
SCNtohl(da->ip.addr_data32[1]);
2550 addr_match6[idx].
ip[2] =
SCNtohl(da->ip.addr_data32[2]);
2551 addr_match6[idx].
ip[3] =
SCNtohl(da->ip.addr_data32[3]);
2552 addr_match6[idx].
ip2[0] =
SCNtohl(da->ip2.addr_data32[0]);
2553 addr_match6[idx].
ip2[1] =
SCNtohl(da->ip2.addr_data32[1]);
2554 addr_match6[idx].
ip2[2] =
SCNtohl(da->ip2.addr_data32[2]);
2555 addr_match6[idx].
ip2[3] =
SCNtohl(da->ip2.addr_data32[3]);
2568 static void SigBuildAddressMatchArray(
Signature *s)
2585 static int SigMatchListLen(
SigMatch *sm)
2588 for (; sm != NULL; sm = sm->
next)
2599 int len = SigMatchListLen(
head);
2605 FatalError(
"initializing the detection engine failed");
2611 for (; sm != NULL; sm = sm->
next, smd++) {
2629 SCLogDebug(
"no prefilter for SIG_FLAG_FW_HOOK_LTE sig");
2656 SCLogDebug(
"s %u: no mpm; prefilter? de_ctx->prefilter_setting %u "
2657 "s->init_data->has_possible_prefilter %s",
2671 prefilter_list =
MIN(prefilter_list, sm->
type);
2681 if (sm->
type == prefilter_list) {
2698 static bool DetectRuleValidateTable(
const Signature *s)
2707 if (kw_tables_supported != 0 && (kw_tables_supported & table_as_flag) == 0) {
2708 SCLogError(
"rule %u uses hook \"%s\", but keyword \"%s\" doesn't support this hook",
2719 SCLogError(
"rule %u is loaded as a firewall rule, but does not specify an "
2729 SCLogError(
"rule %u uses action scope \"packet\" for an non-UDP app hook",
2747 SCLogError(
"rule %u: auto-accept notation (<hook) can only be used with accept:flow, "
2748 "accept:tx and accept:hook",
2757 static void DetectRuleSetTable(
Signature *s)
2790 if (!DetectFirewallRuleValidate(
de_ctx, s))
2796 static int SigValidateCheckBuffers(
2799 bool has_frame =
false;
2800 bool has_app =
false;
2801 bool has_pkt =
false;
2802 bool has_pmatch =
false;
2808 nlists += (nlists > 0);
2812 SCLogError(
"rule %u setup buffer %s but didn't add matches to it", s->
id,
2826 struct BufferVsDir {
2829 } bufdir[nlists + 1];
2830 memset(&bufdir, 0, (nlists + 1) *
sizeof(
struct BufferVsDir));
2844 if (b->
head == NULL) {
2849 has_frame |= bt->
frame;
2855 "specific matches (like dsize, flags, ttl) with stream / "
2856 "state matching by matching on app layer proto (like using "
2857 "http_* keywords).");
2861 uint32_t app_buffers_evaluated = 0;
2862 bool buffer_consumed =
false;
2863 uint32_t buffer_skip_alproto = 0;
2864 uint32_t buffer_skip_substate = 0;
2866 for (; app != NULL; app = app->
next) {
2869 app_buffers_evaluated++;
2877 SCLogDebug(
"%u:%s: for buffer %s skip engine %s alproto %s", s->
id,
2881 buffer_skip_alproto++;
2886 buffer_skip_substate++;
2892 SCLogDebug(
"%u:%s: for buffer %s skip engine %s alproto %s", s->
id,
2896 buffer_skip_alproto++;
2913 bufdir[b->
id].ts += (app->
dir == 0);
2914 bufdir[b->
id].tc += (app->
dir == 1);
2926 SCLogError(
"engine progress value doesn't match hook");
2931 buffer_consumed =
true;
2933 if (app_buffers_evaluated && !buffer_consumed) {
2934 SCLogError(
"incompatible rule conditions, skipped buffer %s, reasons: app proto %u sub "
2936 bt->
name, buffer_skip_alproto, buffer_skip_substate);
2951 if (has_pmatch && has_frame) {
2952 SCLogError(
"can't mix pure content and frame inspection");
2955 if (has_app && has_frame) {
2956 SCLogError(
"can't mix app-layer buffer and frame inspection");
2959 if (has_pkt && has_frame) {
2960 SCLogError(
"can't mix pkt buffer and frame inspection");
2964 for (
int x = 0; x < nlists; x++) {
2965 if (bufdir[x].
ts == 0 && bufdir[x].tc == 0)
2967 (*ts_excl) += (bufdir[x].ts > 0 && bufdir[x].tc == 0);
2968 (*tc_excl) += (bufdir[x].ts == 0 && bufdir[x].tc > 0);
2969 (*dir_amb) += (bufdir[x].ts > 0 && bufdir[x].tc > 0);
2978 static int SigValidatePacketStream(
const Signature *s)
2982 "tcp-stream or flow:only_stream. Invalidating signature.");
2988 static int SigConsolidateDirection(
2989 Signature *s,
const int ts_excl,
const int tc_excl,
const int dir_amb)
2992 if (!ts_excl || !tc_excl) {
2993 SCLogError(
"rule %u should use both directions, but does not", s->
id);
2997 SCLogError(
"rule %u means to use both directions, cannot have keywords ambiguous about "
3002 }
else if (ts_excl && tc_excl) {
3004 "rule %u mixes keywords with conflicting directions, a transactional rule with => "
3008 }
else if (ts_excl) {
3009 SCLogDebug(
"%u: implied rule direction is toserver", s->
id);
3011 SCLogError(
"rule %u mixes keywords with conflicting directions", s->
id);
3014 }
else if (tc_excl) {
3015 SCLogDebug(
"%u: implied rule direction is toclient", s->
id);
3017 SCLogError(
"rule %u mixes keywords with conflicting directions", s->
id);
3020 }
else if (dir_amb) {
3021 SCLogDebug(
"%u: rule direction cannot be deduced from keywords", s->
id);
3026 static void SigConsolidateTcpBuffer(
Signature *s)
3058 static bool SigInspectsFiles(
const Signature *s)
3069 static int SigValidateFileHandling(
const Signature *s)
3071 if (!SigInspectsFiles(s)) {
3078 "support file matching",
3095 SCLogError(
"No protocol support file matching");
3100 SCLogError(
"protocol HTTP2 doesn't support file name matching");
3106 static bool SigValidateEthernet(
const Signature *s)
3111 SCLogError(
"can't use ports with ether or arp rule");
3119 static bool SigValidateProtoPkthdr(
const Signature *s)
3122 SCLogError(
"protocol 'pkthdr' is for decoder-events only");
3151 static int SigValidateConsolidate(
3156 if (SigValidateFirewall(
de_ctx, s) == 0)
3159 if (SigValidatePacketStream(s) == 0) {
3163 if (!SigValidateEthernet(s)) {
3171 if (SigValidateCheckBuffers(
de_ctx, s, &ts_excl, &tc_excl, &dir_amb) == 0) {
3175 if (SigConsolidateDirection(s, ts_excl, tc_excl, dir_amb) == 0) {
3179 SigConsolidateTcpBuffer(s);
3182 DetectRuleSetTable(s);
3184 if (!SigValidateProtoPkthdr(s)) {
3188 if (!SigValidateFlowbitUse(
de_ctx, s)) {
3195 int r = SigValidateFileHandling(s);
3199 if (SigInspectsFiles(s)) {
3204 if (DetectRuleValidateTable(s) ==
false) {
3227 memset(&parser, 0x00,
sizeof(parser));
3232 if (firewall_rule) {
3249 int ret = SigParse(
de_ctx, sig, sigstr, dir, &parser,
true);
3256 }
else if (ret < 0) {
3262 SCLogError(
"Signature missing required value \"sid\".");
3267 ret = SigParse(
de_ctx, sig, sigstr, dir, &parser,
false);
3273 }
else if (ret == -2) {
3276 }
else if (ret < 0) {
3281 if (sig->
prio == -1)
3288 int override_needed = 0;
3292 override_needed = 1;
3294 override_needed = 1;
3298 override_needed = 0;
3307 if (override_needed)
3317 for ( ; sm != NULL; sm = sm->
next) {
3341 SCLogDebug(
"sig %"PRIu32
" SIG_FLAG_APPLAYER: %s, SIG_FLAG_PACKET: %s",
3345 SigBuildAddressMatchArray(sig);
3356 SigSetupPrefilter(
de_ctx, sig);
3359 if (SigValidateConsolidate(
de_ctx, sig, &parser, dir) == 0) {
3378 static bool SigHasSameSourceAndDestination(
const Signature *s)
3420 if (SigHasSameSourceAndDestination(sig)) {
3421 SCLogInfo(
"Rule with ID %u is bidirectional, but source and destination are the same, "
3422 "treating the rule as unidirectional", sig->
id);
3427 if (sig->
next == NULL) {
3457 return SigInitDo(
de_ctx, sigstr,
false);
3462 return SigInitDo(
de_ctx, sigstr,
true);
3471 static void DetectParseDupSigFreeFunc(
void *data)
3487 static uint32_t DetectParseDupSigHashFunc(
HashListTable *ht,
void *data, uint16_t datalen)
3506 static char DetectParseDupSigCompareFunc(
void *data1, uint16_t len1,
void *data2,
3512 if (sw1 == NULL || sw2 == NULL ||
3513 sw1->
s == NULL || sw2->
s == NULL)
3517 if (sw1->
s->
id == sw2->
s->
id && sw1->
s->
gid == sw2->
s->
gid)
return 1;
3533 DetectParseDupSigHashFunc,
3534 DetectParseDupSigCompareFunc,
3535 DetectParseDupSigFreeFunc);
3596 if (sw_dup == NULL) {
3609 (
void *)&sw_tmp, 0);
3623 if (sw->
s->
rev <= sw_dup->
s->
rev) {
3632 if (sw_dup->
s_prev == NULL) {
3640 sw_temp.
s = sw_dup->
s->
next;
3644 if (sw_temp.
s != NULL) {
3646 (
void *)&sw_temp, 0);
3667 sw_temp.
s = sw_dup->
s->
next;
3675 if (sw_temp.
s != NULL) {
3677 (
void *)&sw_temp, 0);
3693 (
void *)&sw_tmp, 0);
3695 if (sw_old->
s != sw_dup->
s) {
3738 int dup_sig = DetectEngineSignatureIsDuplicate(
de_ctx, sig);
3742 SCLogError(
"Duplicate signature \"%s\"", sigstr);
3744 }
else if (dup_sig == 2) {
3746 " so the older sig replaced by this new signature \"%s\"",
3751 if (sig->
next != NULL) {
3768 return (dup_sig == 0 || dup_sig == 2) ? sig : NULL;
3772 if (sig != NULL && sig->
next != NULL) {
3810 int dup_sig = DetectEngineSignatureIsDuplicate(
de_ctx, sig);
3814 SCLogError(
"Duplicate signature \"%s\"", sigstr);
3816 }
else if (dup_sig == 2) {
3818 " so the older sig replaced by this new signature \"%s\"",
3823 if (sig->
next != NULL) {
3840 return (dup_sig == 0 || dup_sig == 2) ? sig : NULL;
3844 if (sig != NULL && sig->
next != NULL) {
3857 int start_offset,
int options)
3859 *match = pcre2_match_data_create_from_pattern(parse_regex->
regex, NULL);
3861 return pcre2_match(parse_regex->
regex, (PCRE2_SPTR8)
str, strlen(
str), options, start_offset,
3862 *match, parse_regex->
context);
3869 pcre2_code_free(r->
regex);
3872 pcre2_match_context_free(r->
context);
3887 g_detect_parse_regex_list = NULL;
3896 FatalError(
"failed to alloc memory for pcre free list");
3899 r->
next = g_detect_parse_regex_list;
3900 g_detect_parse_regex_list = r;
3908 detect_parse->
regex =
3909 pcre2_compile((PCRE2_SPTR8)parse_str, PCRE2_ZERO_TERMINATED, opts, &en, &eo, NULL);
3910 if (detect_parse->
regex == NULL) {
3911 PCRE2_UCHAR errbuffer[256];
3912 pcre2_get_error_message(en, errbuffer,
sizeof(errbuffer));
3913 SCLogError(
"pcre compile of \"%s\" failed at "
3915 parse_str, en, errbuffer);
3918 detect_parse->
context = pcre2_match_context_create(NULL);
3919 if (detect_parse->
context == NULL) {
3920 SCLogError(
"pcre2 could not create match context");
3921 pcre2_code_free(detect_parse->
regex);
3922 detect_parse->
regex = NULL;
3937 if (detect_parse == NULL) {
3941 detect_parse->
regex =
3942 pcre2_compile((PCRE2_SPTR8)parse_str, PCRE2_ZERO_TERMINATED, opts, &en, &eo, NULL);
3943 if (detect_parse->
regex == NULL) {
3944 PCRE2_UCHAR errbuffer[256];
3945 pcre2_get_error_message(en, errbuffer,
sizeof(errbuffer));
3946 SCLogError(
"pcre2 compile of \"%s\" failed at "
3948 parse_str, (
int)eo, errbuffer);
3953 detect_parse->
next = g_detect_parse_regex_list;
3954 g_detect_parse_regex_list = detect_parse;
3955 return detect_parse;
3959 pcre2_match_data *match_data, uint32_t number, PCRE2_UCHAR *buffer, PCRE2_SIZE *bufflen)
3961 int r = pcre2_substring_copy_bynumber(match_data, number, buffer, bufflen);
3962 if (r == PCRE2_ERROR_UNSET) {
3971 pcre2_match_data *match_data, uint32_t number, PCRE2_UCHAR **bufferptr, PCRE2_SIZE *bufflen)
3973 int r = pcre2_substring_get_bynumber(match_data, number, bufferptr, bufflen);
3974 if (r == PCRE2_ERROR_UNSET) {
3989 static uint32_t AppPolicyHashFunc(
HashTable *ht,
void *data, uint16_t datalen)
3993 uint32_t hash =
p->alproto * 65537 +
p->sub_state * 257 +
p->progress * 5 +
3994 (
p->direction == STREAM_TOSERVER);
3995 hash ^= (hash >> 10) ^ (hash >> 20);
3999 static char AppPolicyCompareFunc(
void *data1, uint16_t datalen1,
void *data2, uint16_t datalen2)
4004 if (p1 == NULL || p2 == NULL)
4011 static void AppPolicyHashFree(
void *data)
4048 snprintf(out, out_size,
"rejectdst:%s", as);
4050 snprintf(out, out_size,
"rejectboth:%s", as);
4052 snprintf(out, out_size,
"rejectsrc:%s", as);
4055 snprintf(out, out_size,
"drop:%s", as);
4057 snprintf(out, out_size,
"accept:%s", as);
4063 strlcat(out,
",pass:flow", out_size);
4069 strlcat(out,
",alert", out_size);
4091 snprintf(msg,
sizeof(msg),
"SURICATA FW default packet policy");
4093 if (s->
msg == NULL) {
4117 snprintf(msg,
sizeof(msg),
"SURICATA FW default app policy");
4119 if (s->
msg == NULL) {
4144 if (policy_actions == NULL) {
4145 SCLogDebug(
"fw: no policy at %s", policy_name);
4150 uint8_t action_scope = 0;
4155 if (SigParseActionDo(paction->
val, idx,
true, &action, &action_scope) < 0)
4164 static int DoParseAppSubStatePolicy(
const char *prefix,
const AppProto app_proto,
4165 const uint8_t
sub_state,
const char *sub_state_name,
const uint8_t state,
4166 const char *hookname,
const uint8_t complete_state,
const int direction,
4169 char policy_name[256];
4170 BUG_ON(sub_state_name == NULL);
4171 BUG_ON(hookname == NULL);
4176 for (
int i = 0; nname[i] !=
'\0'; i++) {
4177 if (nname[i] ==
'_')
4182 int r = snprintf(policy_name,
sizeof(policy_name),
"%s.%s.%s.%s", prefix, app_name,
4183 sub_state_name, nname);
4186 if (r < 0 || (
size_t)r >=
sizeof(policy_name)) {
4187 FatalError(
"internal error: failed to assemble firewall policy config string");
4191 if (app_pol == NULL)
4203 r = DoParsePolicy(policy_name, &app_pol->
policy);
4210 FatalError(
"internal error: insert policy into hash table");
4215 return AddAppPolicySignature(app_pol);
4221 static int DoParseAppPolicy(
const char *prefix,
const AppProto app_proto,
const char *hookname,
4222 const uint8_t state,
const uint8_t complete_state,
const int direction,
4225 char policy_name[256];
4226 const char *in_name = hookname;
4227 if (hookname == NULL) {
4230 hookname =
"request-started";
4232 hookname =
"response-started";
4233 }
else if (state == complete_state) {
4235 hookname =
"request-complete";
4237 hookname =
"response-complete";
4239 if (hookname == NULL)
4245 for (
int i = 0; nname[i] !=
'\0'; i++) {
4246 if (nname[i] ==
'_')
4251 int r = snprintf(policy_name,
sizeof(policy_name),
"%s.%s.%s", prefix, app_name, nname);
4253 if (r < 0 || (
size_t)r >=
sizeof(policy_name)) {
4254 FatalError(
"internal error: failed to assemble firewall policy config string");
4258 if (app_pol == NULL)
4270 r = DoParsePolicy(policy_name, &app_pol->
policy);
4271 if (r == 0 && in_name != NULL) {
4274 hookname =
"request-started";
4276 hookname =
"response-started";
4277 }
else if (state == complete_state) {
4279 hookname =
"request-complete";
4281 hookname =
"response-complete";
4283 if (hookname == NULL)
4285 r = snprintf(policy_name,
sizeof(policy_name),
"%s.%s.%s", prefix, app_name, hookname);
4286 if (r < 0 || (
size_t)r >=
sizeof(policy_name)) {
4287 FatalError(
"internal error: failed to assemble firewall policy config string");
4290 r = DoParsePolicy(policy_name, &app_pol->
policy);
4298 FatalError(
"internal error: insert policy into hash table");
4304 return AddAppPolicySignature(app_pol);
4314 if (fw_policies == NULL)
4317 HashTableInit(512, AppPolicyHashFunc, AppPolicyCompareFunc, AppPolicyHashFree);
4339 char policy_name[256];
4340 char prefix[96] =
"firewall.policies";
4346 if (fw_policies == NULL)
4349 r = snprintf(policy_name,
sizeof(policy_name),
"%s.packet-filter", prefix);
4350 if (r < 0 || (
size_t)r >=
sizeof(policy_name)) {
4351 FatalError(
"internal error: failed to assemble firewall policy config string");
4357 if (AddPktPolicySignature(fw_policies,
4362 r = snprintf(policy_name,
sizeof(policy_name),
"%s.packet-pre-flow", prefix);
4363 if (r < 0 || (
size_t)r >=
sizeof(policy_name)) {
4364 FatalError(
"internal error: failed to assemble firewall policy config string");
4374 r = snprintf(policy_name,
sizeof(policy_name),
"%s.packet-pre-stream", prefix);
4375 if (r < 0 || (
size_t)r >=
sizeof(policy_name)) {
4376 FatalError(
"internal error: failed to assemble firewall policy config string");
4387 if (!AppProtoIsValid(a))
4393 for (uint8_t s = 1; s <= max_sub_state; s++) {
4397 if (sub_state_name == NULL)
4404 for (uint8_t state = 0; state <= max_state; state++) {
4406 sub_state_name, state);
4407 const char *state_name =
4409 BUG_ON(state_name == NULL);
4411 sub_state_name, state_name);
4412 if (DoParseAppSubStatePolicy(prefix, a, s, sub_state_name, state, state_name,
4413 max_state, STREAM_TOSERVER, fw_policies) < 0)
4417 for (uint8_t state = 0; state <= max_state; state++) {
4419 sub_state_name, state);
4420 const char *state_name =
4422 BUG_ON(state_name == NULL);
4424 sub_state_name, state_name);
4425 if (DoParseAppSubStatePolicy(prefix, a, s, sub_state_name, state, state_name,
4426 max_state, STREAM_TOCLIENT, fw_policies) < 0)
4431 const uint8_t complete_state_ts =
4433 a, STREAM_TOSERVER);
4434 for (uint8_t state = 0; state <= complete_state_ts; state++) {
4437 if (DoParseAppPolicy(prefix, a,
name, state, complete_state_ts, STREAM_TOSERVER,
4441 const uint8_t complete_state_tc =
4443 a, STREAM_TOCLIENT);
4444 for (uint8_t state = 0; state <= complete_state_tc; state++) {
4447 if (DoParseAppPolicy(prefix, a,
name, state, complete_state_tc, STREAM_TOCLIENT,
4464 static int SigParseTest01 (
void)
4473 sig =
SigInit(
de_ctx,
"alert tcp 1.2.3.4 any -> !1.2.3.4 any (msg:\"SigParseTest01\"; sid:1;)");
4483 static int SigParseTest02 (
void)
4498 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;)");
4526 static int SigParseTest03 (
void)
4535 sig =
SigInit(
de_ctx,
"alert tcp 1.2.3.4 any <- !1.2.3.4 any (msg:\"SigParseTest03\"; sid:1;)");
4538 printf(
"expected NULL got sig ptr %p: ",sig);
4547 static int SigParseTest04 (
void)
4556 sig =
SigInit(
de_ctx,
"alert tcp 1.2.3.4 1024: -> !1.2.3.4 1024: (msg:\"SigParseTest04\"; sid:1;)");
4567 static int SigParseTest05 (
void)
4576 sig =
SigInit(
de_ctx,
"alert tcp 1.2.3.4 1024:65536 -> !1.2.3.4 any (msg:\"SigParseTest05\"; sid:1;)");
4580 printf(
"signature didn't fail to parse as we expected: ");
4590 static int SigParseTest06 (
void)
4599 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;)");
4603 printf(
"signature failed to parse: ");
4617 static int SigParseTest07(
void)
4639 static int SigParseTest08(
void)
4662 static int SigParseTest09(
void)
4713 static int SigParseTest10(
void)
4745 static int SigParseTest11(
void)
4756 "drop tcp any any -> any 80 (msg:\"Snort_Inline is blocking the http link\"; sid:1;) ");
4758 printf(
"sig 1 didn't parse: ");
4763 "the http link\"; sid:2;) ");
4765 printf(
"sig 2 didn't parse: ");
4779 static int SigParseTest12(
void)
4791 printf(
"sig 1 should have given an error: ");
4805 static int SigParseTest13(
void)
4817 printf(
"sig 1 invalidated: failure");
4822 printf(
"sig doesn't have stream flag set\n");
4827 printf(
"sig has packet flag set\n");
4842 static int SigParseTest14(
void)
4854 printf(
"sig 1 invalidated: failure");
4859 printf(
"sig doesn't have packet flag set\n");
4864 printf(
"sig has stream flag set\n");
4879 static int SigParseTest15(
void)
4891 printf(
"sig 1 invalidated: failure");
4896 printf(
"sig doesn't have packet flag set\n");
4901 printf(
"sig doesn't have stream flag set\n");
4916 static int SigParseTest16(
void)
4928 printf(
"sig 1 invalidated: failure");
4933 printf(
"sig doesn't have packet flag set\n");
4938 printf(
"sig doesn't have stream flag set\n");
4953 static int SigParseTest17(
void)
4965 printf(
"sig 1 invalidated: failure");
4970 printf(
"sig doesn't have packet flag set\n");
4975 printf(
"sig doesn't have stream flag set\n");
4988 static int SigParseTest18 (
void)
4996 if (
DetectEngineAppendSig(
de_ctx,
"alert tcp 1.2.3.4 any -> !1.2.3.4 any (msg:\"SigParseTest01\"; sid:99999999999999999999;)") != NULL)
5007 static int SigParseTest19 (
void)
5015 if (
DetectEngineAppendSig(
de_ctx,
"alert tcp 1.2.3.4 any -> !1.2.3.4 any (msg:\"SigParseTest01\"; sid:1; gid:99999999999999999999;)") != NULL)
5026 static int SigParseTest20 (
void)
5034 if (
DetectEngineAppendSig(
de_ctx,
"alert tcp 1.2.3.4 any -> !1.2.3.4 any (msg:\"SigParseTest01\"; sid:1; rev:99999999999999999999;)") != NULL)
5045 static int SigParseTest21 (
void)
5064 static int SigParseTest22 (
void)
5072 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)
5085 static int SigParseTest23(
void)
5100 static int SigParseBidirecTest06 (
void)
5120 static int SigParseBidirecTest07 (
void)
5140 static int SigParseBidirecTest08 (
void)
5160 static int SigParseBidirecTest09 (
void)
5180 static int SigParseBidirecTest10 (
void)
5200 static int SigParseBidirecTest11 (
void)
5220 static int SigParseBidirecTest12 (
void)
5240 static int SigParseBidirecTest13 (
void)
5259 static int SigParseBidirecTest14 (
void)
5280 static int SigTestBidirec01 (
void)
5292 if (sig->
next != NULL)
5311 static int SigTestBidirec02 (
void)
5330 if (sig->
next == NULL)
5335 if (copy->
next != NULL)
5356 static int SigTestBidirec03 (
void)
5368 const char *sigs[3];
5369 sigs[0] =
"alert tcp any any -> 192.168.1.1 any (msg:\"SigTestBidirec03 sid 1\"; sid:1;)";
5370 sigs[1] =
"alert tcp any any <> 192.168.1.1 any (msg:\"SigTestBidirec03 sid 2 bidirectional\"; sid:2;)";
5371 sigs[2] =
"alert tcp any any -> 192.168.1.1 any (msg:\"SigTestBidirec03 sid 3\"; sid:3;)";
5378 if (sig->
next == NULL)
5389 uint8_t rawpkt1_ether[] = {
5390 0x00,0x50,0x56,0xea,0x00,0xbd,0x00,0x0c,
5391 0x29,0x40,0xc8,0xb5,0x08,0x00,0x45,0x00,
5392 0x01,0xa8,0xb9,0xbb,0x40,0x00,0x40,0x06,
5393 0xe0,0xbf,0xc0,0xa8,0x1c,0x83,0xc0,0xa8,
5394 0x01,0x01,0xb9,0x0a,0x00,0x50,0x6f,0xa2,
5395 0x92,0xed,0x7b,0xc1,0xd3,0x4d,0x50,0x18,
5396 0x16,0xd0,0xa0,0x6f,0x00,0x00,0x47,0x45,
5397 0x54,0x20,0x2f,0x20,0x48,0x54,0x54,0x50,
5398 0x2f,0x31,0x2e,0x31,0x0d,0x0a,0x48,0x6f,
5399 0x73,0x74,0x3a,0x20,0x31,0x39,0x32,0x2e,
5400 0x31,0x36,0x38,0x2e,0x31,0x2e,0x31,0x0d,
5401 0x0a,0x55,0x73,0x65,0x72,0x2d,0x41,0x67,
5402 0x65,0x6e,0x74,0x3a,0x20,0x4d,0x6f,0x7a,
5403 0x69,0x6c,0x6c,0x61,0x2f,0x35,0x2e,0x30,
5404 0x20,0x28,0x58,0x31,0x31,0x3b,0x20,0x55,
5405 0x3b,0x20,0x4c,0x69,0x6e,0x75,0x78,0x20,
5406 0x78,0x38,0x36,0x5f,0x36,0x34,0x3b,0x20,
5407 0x65,0x6e,0x2d,0x55,0x53,0x3b,0x20,0x72,
5408 0x76,0x3a,0x31,0x2e,0x39,0x2e,0x30,0x2e,
5409 0x31,0x34,0x29,0x20,0x47,0x65,0x63,0x6b,
5410 0x6f,0x2f,0x32,0x30,0x30,0x39,0x30,0x39,
5411 0x30,0x32,0x31,0x37,0x20,0x55,0x62,0x75,
5412 0x6e,0x74,0x75,0x2f,0x39,0x2e,0x30,0x34,
5413 0x20,0x28,0x6a,0x61,0x75,0x6e,0x74,0x79,
5414 0x29,0x20,0x46,0x69,0x72,0x65,0x66,0x6f,
5415 0x78,0x2f,0x33,0x2e,0x30,0x2e,0x31,0x34,
5416 0x0d,0x0a,0x41,0x63,0x63,0x65,0x70,0x74,
5417 0x3a,0x20,0x74,0x65,0x78,0x74,0x2f,0x68,
5418 0x74,0x6d,0x6c,0x2c,0x61,0x70,0x70,0x6c,
5419 0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,0x2f,
5420 0x78,0x68,0x74,0x6d,0x6c,0x2b,0x78,0x6d,
5421 0x6c,0x2c,0x61,0x70,0x70,0x6c,0x69,0x63,
5422 0x61,0x74,0x69,0x6f,0x6e,0x2f,0x78,0x6d,
5423 0x6c,0x3b,0x71,0x3d,0x30,0x2e,0x39,0x2c,
5424 0x2a,0x2f,0x2a,0x3b,0x71,0x3d,0x30,0x2e,
5425 0x38,0x0d,0x0a,0x41,0x63,0x63,0x65,0x70,
5426 0x74,0x2d,0x4c,0x61,0x6e,0x67,0x75,0x61,
5427 0x67,0x65,0x3a,0x20,0x65,0x6e,0x2d,0x75,
5428 0x73,0x2c,0x65,0x6e,0x3b,0x71,0x3d,0x30,
5429 0x2e,0x35,0x0d,0x0a,0x41,0x63,0x63,0x65,
5430 0x70,0x74,0x2d,0x45,0x6e,0x63,0x6f,0x64,
5431 0x69,0x6e,0x67,0x3a,0x20,0x67,0x7a,0x69,
5432 0x70,0x2c,0x64,0x65,0x66,0x6c,0x61,0x74,
5433 0x65,0x0d,0x0a,0x41,0x63,0x63,0x65,0x70,
5434 0x74,0x2d,0x43,0x68,0x61,0x72,0x73,0x65,
5435 0x74,0x3a,0x20,0x49,0x53,0x4f,0x2d,0x38,
5436 0x38,0x35,0x39,0x2d,0x31,0x2c,0x75,0x74,
5437 0x66,0x2d,0x38,0x3b,0x71,0x3d,0x30,0x2e,
5438 0x37,0x2c,0x2a,0x3b,0x71,0x3d,0x30,0x2e,
5439 0x37,0x0d,0x0a,0x4b,0x65,0x65,0x70,0x2d,
5440 0x41,0x6c,0x69,0x76,0x65,0x3a,0x20,0x33,
5441 0x30,0x30,0x0d,0x0a,0x43,0x6f,0x6e,0x6e,
5442 0x65,0x63,0x74,0x69,0x6f,0x6e,0x3a,0x20,
5443 0x6b,0x65,0x65,0x70,0x2d,0x61,0x6c,0x69,
5444 0x76,0x65,0x0d,0x0a,0x0d,0x0a };
5454 uint32_t sids[3] = {1, 2, 3};
5455 uint32_t results[3] = {1, 1, 1};
5471 static int SigTestBidirec04 (
void)
5486 sig =
DetectEngineAppendSig(
de_ctx,
"alert tcp 192.168.1.1 any <> any any (msg:\"SigTestBidirec03 sid 2 bidirectional\"; sid:2;)");
5491 if (sig->
next == NULL)
5503 if (sig->
next == NULL)
5514 uint8_t rawpkt1_ether[] = {
5515 0x00,0x50,0x56,0xea,0x00,0xbd,0x00,0x0c,
5516 0x29,0x40,0xc8,0xb5,0x08,0x00,0x45,0x00,
5517 0x01,0xa8,0xb9,0xbb,0x40,0x00,0x40,0x06,
5518 0xe0,0xbf,0xc0,0xa8,0x1c,0x83,0xc0,0xa8,
5519 0x01,0x01,0xb9,0x0a,0x00,0x50,0x6f,0xa2,
5520 0x92,0xed,0x7b,0xc1,0xd3,0x4d,0x50,0x18,
5521 0x16,0xd0,0xa0,0x6f,0x00,0x00,0x47,0x45,
5522 0x54,0x20,0x2f,0x20,0x48,0x54,0x54,0x50,
5523 0x2f,0x31,0x2e,0x31,0x0d,0x0a,0x48,0x6f,
5524 0x73,0x74,0x3a,0x20,0x31,0x39,0x32,0x2e,
5525 0x31,0x36,0x38,0x2e,0x31,0x2e,0x31,0x0d,
5526 0x0a,0x55,0x73,0x65,0x72,0x2d,0x41,0x67,
5527 0x65,0x6e,0x74,0x3a,0x20,0x4d,0x6f,0x7a,
5528 0x69,0x6c,0x6c,0x61,0x2f,0x35,0x2e,0x30,
5529 0x20,0x28,0x58,0x31,0x31,0x3b,0x20,0x55,
5530 0x3b,0x20,0x4c,0x69,0x6e,0x75,0x78,0x20,
5531 0x78,0x38,0x36,0x5f,0x36,0x34,0x3b,0x20,
5532 0x65,0x6e,0x2d,0x55,0x53,0x3b,0x20,0x72,
5533 0x76,0x3a,0x31,0x2e,0x39,0x2e,0x30,0x2e,
5534 0x31,0x34,0x29,0x20,0x47,0x65,0x63,0x6b,
5535 0x6f,0x2f,0x32,0x30,0x30,0x39,0x30,0x39,
5536 0x30,0x32,0x31,0x37,0x20,0x55,0x62,0x75,
5537 0x6e,0x74,0x75,0x2f,0x39,0x2e,0x30,0x34,
5538 0x20,0x28,0x6a,0x61,0x75,0x6e,0x74,0x79,
5539 0x29,0x20,0x46,0x69,0x72,0x65,0x66,0x6f,
5540 0x78,0x2f,0x33,0x2e,0x30,0x2e,0x31,0x34,
5541 0x0d,0x0a,0x41,0x63,0x63,0x65,0x70,0x74,
5542 0x3a,0x20,0x74,0x65,0x78,0x74,0x2f,0x68,
5543 0x74,0x6d,0x6c,0x2c,0x61,0x70,0x70,0x6c,
5544 0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,0x2f,
5545 0x78,0x68,0x74,0x6d,0x6c,0x2b,0x78,0x6d,
5546 0x6c,0x2c,0x61,0x70,0x70,0x6c,0x69,0x63,
5547 0x61,0x74,0x69,0x6f,0x6e,0x2f,0x78,0x6d,
5548 0x6c,0x3b,0x71,0x3d,0x30,0x2e,0x39,0x2c,
5549 0x2a,0x2f,0x2a,0x3b,0x71,0x3d,0x30,0x2e,
5550 0x38,0x0d,0x0a,0x41,0x63,0x63,0x65,0x70,
5551 0x74,0x2d,0x4c,0x61,0x6e,0x67,0x75,0x61,
5552 0x67,0x65,0x3a,0x20,0x65,0x6e,0x2d,0x75,
5553 0x73,0x2c,0x65,0x6e,0x3b,0x71,0x3d,0x30,
5554 0x2e,0x35,0x0d,0x0a,0x41,0x63,0x63,0x65,
5555 0x70,0x74,0x2d,0x45,0x6e,0x63,0x6f,0x64,
5556 0x69,0x6e,0x67,0x3a,0x20,0x67,0x7a,0x69,
5557 0x70,0x2c,0x64,0x65,0x66,0x6c,0x61,0x74,
5558 0x65,0x0d,0x0a,0x41,0x63,0x63,0x65,0x70,
5559 0x74,0x2d,0x43,0x68,0x61,0x72,0x73,0x65,
5560 0x74,0x3a,0x20,0x49,0x53,0x4f,0x2d,0x38,
5561 0x38,0x35,0x39,0x2d,0x31,0x2c,0x75,0x74,
5562 0x66,0x2d,0x38,0x3b,0x71,0x3d,0x30,0x2e,
5563 0x37,0x2c,0x2a,0x3b,0x71,0x3d,0x30,0x2e,
5564 0x37,0x0d,0x0a,0x4b,0x65,0x65,0x70,0x2d,
5565 0x41,0x6c,0x69,0x76,0x65,0x3a,0x20,0x33,
5566 0x30,0x30,0x0d,0x0a,0x43,0x6f,0x6e,0x6e,
5567 0x65,0x63,0x74,0x69,0x6f,0x6e,0x3a,0x20,
5568 0x6b,0x65,0x65,0x70,0x2d,0x61,0x6c,0x69,
5569 0x76,0x65,0x0d,0x0a,0x0d,0x0a };
5618 static int SigParseTestNegation01 (
void)
5632 static int SigParseTestNegation02 (
void)
5638 "alert tcp any !any -> any any (msg:\"SigTest41-02 src ip is !any \"; "
5639 "classtype:misc-activity; sid:410002; rev:1;)");
5647 static int SigParseTestNegation03 (
void)
5653 "alert tcp any any -> any [80:!80] (msg:\"SigTest41-03 dst port [80:!80] \"; "
5654 "classtype:misc-activity; sid:410003; rev:1;)");
5662 static int SigParseTestNegation04 (
void)
5673 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;)");
5688 static int SigParseTestNegation05 (
void)
5699 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;)");
5714 static int SigParseTestNegation06 (
void)
5725 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;)");
5741 static int SigParseTestNegation07 (
void)
5747 de_ctx,
"alert tcp any any -> [192.168.0.2,!192.168.0.0/24] any (sid:410006;)");
5756 static int SigParseTestNegation08 (
void)
5768 "alert tcp any any -> [192.168.0.0/16,!192.168.0.0/24] any (sid:410006; rev:1;)");
5783 static int SigParseTestMpm01 (
void)
5792 sig =
SigInit(
de_ctx,
"alert tcp any any -> any any (msg:\"mpm test\"; content:\"abcd\"; sid:1;)");
5794 printf(
"sig failed to init: ");
5799 printf(
"sig doesn't have content list: ");
5814 static int SigParseTestMpm02 (
void)
5823 sig =
SigInit(
de_ctx,
"alert tcp any any -> any any (msg:\"mpm test\"; content:\"abcd\"; content:\"abcdef\"; sid:1;)");
5825 printf(
"sig failed to init: ");
5830 printf(
"sig doesn't have content list: ");
5845 static int SigParseTestAppLayerTLS01(
void)
5856 s =
SigInit(
de_ctx,
"alert tls any any -> any any (msg:\"SigParseTestAppLayerTLS01 \"; sid:410006; rev:1;)");
5858 printf(
"parsing sig failed: ");
5863 printf(
"alproto not set: ");
5880 static int SigParseTestAppLayerTLS02(
void)
5891 s =
SigInit(
de_ctx,
"alert tls any any -> any any (msg:\"SigParseTestAppLayerTLS02 \"; tls.version:1.0; sid:410006; rev:1;)");
5893 printf(
"parsing sig failed: ");
5898 printf(
"alproto not set: ");
5914 static int SigParseTestAppLayerTLS03(
void)
5921 "alert tls any any -> any any (msg:\"SigParseTestAppLayerTLS03 \"; "
5922 "tls.version:2.5; sid:410006; rev:1;)");
5928 static int SigParseTestUnbalancedQuotes01(
void)
5934 "alert http any any -> any any (msg:\"SigParseTestUnbalancedQuotes01\"; "
5935 "pcre:\"/\\/[a-z]+\\.php\\?[a-z]+?=\\d{7}&[a-z]+?=\\d{7,8}$/U\" "
5936 "flowbits:set,et.exploitkitlanding; classtype:trojan-activity; sid:2017078; rev:5;)");
5942 static int SigParseTestContentGtDsize01(
void)
5949 "dsize:21; content:\"0123456789001234567890|00 00|\"; "
5956 static int SigParseTestContentGtDsize02(
void)
5963 "dsize:21; content:\"0123456789|00 00|\"; offset:10; "
5980 static int SigParseBidirWithSameSrcAndDest01(
void)
5997 "alert tcp [1.2.3.4, 5.6.7.8] [80, 81] <> [5.6.7.8, 1.2.3.4] [81, 80] (sid:3;)");
6006 static int SigParseBidirWithSameSrcAndDest02(
void)
6014 de_ctx,
"alert tcp 1.2.3.4 any <> [1.2.3.4, 5.6.7.8, ::1] any (sid:1;)");
6021 de_ctx,
"alert tcp [1.2.3.4, ::1] [80, 81, 82] <> [1.2.3.4, ::1] [80, 81] (sid:2;)");
6028 "alert tcp [1.2.3.4, ::1, ABCD:AAAA::1] [80] <> [1.2.3.4, ::1] [80, 81] (sid:3;)");
6035 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;)");
6042 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;)");
6051 static int SigParseTestActionReject(
void)
6057 de_ctx,
"reject tcp 1.2.3.4 any -> !1.2.3.4 any (msg:\"SigParseTest01\"; sid:1;)");
6058 #ifdef HAVE_LIBNET11
6069 static int SigParseTestActionDrop(
void)
6075 de_ctx,
"drop tcp 1.2.3.4 any -> !1.2.3.4 any (msg:\"SigParseTest01\"; sid:1;)");
6083 static int SigSetMultiAppProto(
void)
6158 static int DetectSetupDirection01(
void)
6163 char *
str = (
char *)
"to_client";
6164 FAIL_IF(DetectSetupDirection(s, &
str,
true) < 0);
6169 static int DetectSetupDirection02(
void)
6173 char *
str = (
char *)
"to_server";
6174 FAIL_IF(DetectSetupDirection(s, &
str,
true) < 0);
6176 str = (
char *)
"to_client";
6177 FAIL_IF(DetectSetupDirection(s, &
str,
true) >= 0);
6183 static int DetectSetupDirection03(
void)
6187 char *
str = (
char *)
"to_client , something";
6188 FAIL_IF(DetectSetupDirection(s, &
str,
false) < 0);
6190 str = (
char *)
"to_client,something";
6191 FAIL_IF(DetectSetupDirection(s, &
str,
false) < 0);
6197 static int DetectSetupDirection04(
void)
6202 char *
str = (
char *)
"to_client_toto";
6203 FAIL_IF(DetectSetupDirection(s, &
str,
true) >= 0);
6205 str = (
char *)
"to_client_toto";
6206 FAIL_IF(DetectSetupDirection(s, &
str,
false) < 0);
6208 str = (
char *)
"to_client,something";
6210 FAIL_IF(DetectSetupDirection(s, &
str,
true) >= 0);
6247 UtRegisterTest(
"SigParseTest21 -- address with space", SigParseTest21);
6248 UtRegisterTest(
"SigParseTest22 -- address with space", SigParseTest22);
6249 UtRegisterTest(
"SigParseTest23 -- carriage return", SigParseTest23);
6264 UtRegisterTest(
"SigParseTestNegation01", SigParseTestNegation01);
6265 UtRegisterTest(
"SigParseTestNegation02", SigParseTestNegation02);
6266 UtRegisterTest(
"SigParseTestNegation03", SigParseTestNegation03);
6267 UtRegisterTest(
"SigParseTestNegation04", SigParseTestNegation04);
6268 UtRegisterTest(
"SigParseTestNegation05", SigParseTestNegation05);
6269 UtRegisterTest(
"SigParseTestNegation06", SigParseTestNegation06);
6270 UtRegisterTest(
"SigParseTestNegation07", SigParseTestNegation07);
6271 UtRegisterTest(
"SigParseTestNegation08", SigParseTestNegation08);
6274 UtRegisterTest(
"SigParseTestAppLayerTLS01", SigParseTestAppLayerTLS01);
6275 UtRegisterTest(
"SigParseTestAppLayerTLS02", SigParseTestAppLayerTLS02);
6276 UtRegisterTest(
"SigParseTestAppLayerTLS03", SigParseTestAppLayerTLS03);
6277 UtRegisterTest(
"SigParseTestUnbalancedQuotes01", SigParseTestUnbalancedQuotes01);
6280 SigParseTestContentGtDsize01);
6282 SigParseTestContentGtDsize02);
6285 SigParseBidirWithSameSrcAndDest01);
6287 SigParseBidirWithSameSrcAndDest02);
6288 UtRegisterTest(
"SigParseTestActionReject", SigParseTestActionReject);
6289 UtRegisterTest(
"SigParseTestActionDrop", SigParseTestActionDrop);
6293 UtRegisterTest(
"DetectSetupDirection01", DetectSetupDirection01);
6294 UtRegisterTest(
"DetectSetupDirection02", DetectSetupDirection02);
6295 UtRegisterTest(
"DetectSetupDirection03", DetectSetupDirection03);
6296 UtRegisterTest(
"DetectSetupDirection04", DetectSetupDirection04);