|
|
|
@ -46,7 +46,7 @@
|
|
|
|
|
#include "util-unittest.h"
|
|
|
|
|
#include "util-debug.h"
|
|
|
|
|
|
|
|
|
|
#define PARSE_REGEX "([a-z]+)(?:,(.*))?"
|
|
|
|
|
#define PARSE_REGEX "([a-z]+)(?:,\\s*([^\\s]*))?"
|
|
|
|
|
static pcre *parse_regex;
|
|
|
|
|
static pcre_extra *parse_regex_study;
|
|
|
|
|
|
|
|
|
@ -176,36 +176,51 @@ int DetectFlowbitMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int DetectFlowbitSetup (DetectEngineCtx *de_ctx, Signature *s, char *rawstr)
|
|
|
|
|
static int DetectFlowbitParse(char *str, char *cmd, int cmd_len, char *name,
|
|
|
|
|
int name_len)
|
|
|
|
|
{
|
|
|
|
|
DetectFlowbitsData *cd = NULL;
|
|
|
|
|
SigMatch *sm = NULL;
|
|
|
|
|
uint8_t fb_cmd = 0;
|
|
|
|
|
#define MAX_SUBSTRINGS 30
|
|
|
|
|
int ret = 0, res = 0;
|
|
|
|
|
int ov[MAX_SUBSTRINGS];
|
|
|
|
|
char fb_cmd_str[16] = "", fb_name[256] = "";
|
|
|
|
|
|
|
|
|
|
ret = pcre_exec(parse_regex, parse_regex_study, rawstr, strlen(rawstr), 0, 0, ov, MAX_SUBSTRINGS);
|
|
|
|
|
if (ret != 2 && ret != 3) {
|
|
|
|
|
SCLogError(SC_ERR_PCRE_MATCH, "\"%s\" is not a valid setting for flowbits.", rawstr);
|
|
|
|
|
return -1;
|
|
|
|
|
const int max_substrings = 30;
|
|
|
|
|
int count, rc;
|
|
|
|
|
int ov[max_substrings];
|
|
|
|
|
|
|
|
|
|
count = pcre_exec(parse_regex, parse_regex_study, str, strlen(str), 0, 0,
|
|
|
|
|
ov, max_substrings);
|
|
|
|
|
if (count != 2 && count != 3) {
|
|
|
|
|
SCLogError(SC_ERR_PCRE_MATCH,
|
|
|
|
|
"\"%s\" is not a valid setting for flowbits.", str);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
res = pcre_copy_substring((char *)rawstr, ov, MAX_SUBSTRINGS, 1, fb_cmd_str, sizeof(fb_cmd_str));
|
|
|
|
|
if (res < 0) {
|
|
|
|
|
rc = pcre_copy_substring((char *)str, ov, max_substrings, 1, cmd, cmd_len);
|
|
|
|
|
if (rc < 0) {
|
|
|
|
|
SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed");
|
|
|
|
|
return -1;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ret == 3) {
|
|
|
|
|
res = pcre_copy_substring((char *)rawstr, ov, MAX_SUBSTRINGS, 2, fb_name, sizeof(fb_name));
|
|
|
|
|
if (res < 0) {
|
|
|
|
|
if (count == 3) {
|
|
|
|
|
rc = pcre_copy_substring((char *)str, ov, max_substrings, 2, name,
|
|
|
|
|
name_len);
|
|
|
|
|
if (rc < 0) {
|
|
|
|
|
SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed");
|
|
|
|
|
goto error;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int DetectFlowbitSetup (DetectEngineCtx *de_ctx, Signature *s, char *rawstr)
|
|
|
|
|
{
|
|
|
|
|
DetectFlowbitsData *cd = NULL;
|
|
|
|
|
SigMatch *sm = NULL;
|
|
|
|
|
uint8_t fb_cmd = 0;
|
|
|
|
|
char fb_cmd_str[16] = "", fb_name[256] = "";
|
|
|
|
|
|
|
|
|
|
if (!DetectFlowbitParse(rawstr, fb_cmd_str, sizeof(fb_cmd_str), fb_name,
|
|
|
|
|
sizeof(fb_name))) {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (strcmp(fb_cmd_str,"noalert") == 0) {
|
|
|
|
|
fb_cmd = DETECT_FLOWBITS_CMD_NOALERT;
|
|
|
|
|
} else if (strcmp(fb_cmd_str,"isset") == 0) {
|
|
|
|
@ -297,6 +312,74 @@ void DetectFlowbitFree (void *ptr)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef UNITTESTS
|
|
|
|
|
|
|
|
|
|
static int FlowBitsTestParse01(void)
|
|
|
|
|
{
|
|
|
|
|
int ret = 0;
|
|
|
|
|
char command[16] = "", name[16] = "";
|
|
|
|
|
|
|
|
|
|
/* Single argument version. */
|
|
|
|
|
if (!DetectFlowbitParse("noalert", command, sizeof(command), name,
|
|
|
|
|
sizeof(name))) {
|
|
|
|
|
goto end;
|
|
|
|
|
}
|
|
|
|
|
if (strcmp(command, "noalert") != 0) {
|
|
|
|
|
goto end;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* No leading or trailing spaces. */
|
|
|
|
|
if (!DetectFlowbitParse("set,flowbit", command, sizeof(command), name,
|
|
|
|
|
sizeof(name))) {
|
|
|
|
|
goto end;
|
|
|
|
|
}
|
|
|
|
|
if (strcmp(command, "set") != 0) {
|
|
|
|
|
goto end;
|
|
|
|
|
}
|
|
|
|
|
if (strcmp(name, "flowbit") != 0) {
|
|
|
|
|
goto end;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Leading space. */
|
|
|
|
|
if (!DetectFlowbitParse("set, flowbit", command, sizeof(command), name,
|
|
|
|
|
sizeof(name))) {
|
|
|
|
|
goto end;
|
|
|
|
|
}
|
|
|
|
|
if (strcmp(command, "set") != 0) {
|
|
|
|
|
goto end;
|
|
|
|
|
}
|
|
|
|
|
if (strcmp(name, "flowbit") != 0) {
|
|
|
|
|
goto end;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Trailing space. */
|
|
|
|
|
if (!DetectFlowbitParse("set,flowbit ", command, sizeof(command), name,
|
|
|
|
|
sizeof(name))) {
|
|
|
|
|
goto end;
|
|
|
|
|
}
|
|
|
|
|
if (strcmp(command, "set") != 0) {
|
|
|
|
|
goto end;
|
|
|
|
|
}
|
|
|
|
|
if (strcmp(name, "flowbit") != 0) {
|
|
|
|
|
goto end;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Leading and trailing space. */
|
|
|
|
|
if (!DetectFlowbitParse("set, flowbit ", command, sizeof(command), name,
|
|
|
|
|
sizeof(name))) {
|
|
|
|
|
goto end;
|
|
|
|
|
}
|
|
|
|
|
if (strcmp(command, "set") != 0) {
|
|
|
|
|
goto end;
|
|
|
|
|
}
|
|
|
|
|
if (strcmp(name, "flowbit") != 0) {
|
|
|
|
|
goto end;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ret = 1;
|
|
|
|
|
end:
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \test FlowBitsTestSig01 is a test for a valid noalert flowbits option
|
|
|
|
|
*
|
|
|
|
@ -1060,6 +1143,7 @@ end:
|
|
|
|
|
void FlowBitsRegisterTests(void)
|
|
|
|
|
{
|
|
|
|
|
#ifdef UNITTESTS
|
|
|
|
|
UtRegisterTest("FlowBitsTestParse01", FlowBitsTestParse01, 1);
|
|
|
|
|
UtRegisterTest("FlowBitsTestSig01", FlowBitsTestSig01, 0);
|
|
|
|
|
UtRegisterTest("FlowBitsTestSig02", FlowBitsTestSig02, 0);
|
|
|
|
|
UtRegisterTest("FlowBitsTestSig03", FlowBitsTestSig03, 0);
|
|
|
|
|