static int FlowBitsTestSig04(void) { Signature *s = NULL; DetectEngineCtx *de_ctx = NULL; int idx = 0; de_ctx = DetectEngineCtxInit(); FAIL_IF_NULL(de_ctx); de_ctx->flags |= DE_QUIET; s = de_ctx->sig_list = SigInit(de_ctx,"alert ip any any -> any any (msg:\"isset option\"; flowbits:isset,fbt; content:\"GET \"; sid:1;)"); FAIL_IF_NULL(s); idx = VarNameStoreSetupAdd("fbt", VAR_TYPE_FLOW_BIT); FAIL_IF(idx != 1); SigGroupBuild(de_ctx); DetectEngineCtxFree(de_ctx); PASS; }
static int DetectPktvarSetup (DetectEngineCtx *de_ctx, Signature *s, const char *rawstr) { char *varname = NULL, *varcontent = NULL; #define MAX_SUBSTRINGS 30 int ret = 0, res = 0; int ov[MAX_SUBSTRINGS]; uint8_t *content = NULL; uint16_t len = 0; ret = pcre_exec(parse_regex, parse_regex_study, rawstr, strlen(rawstr), 0, 0, ov, MAX_SUBSTRINGS); if (ret != 3) { SCLogError(SC_ERR_PCRE_MATCH, "\"%s\" is not a valid setting for pktvar.", rawstr); return -1; } const char *str_ptr; res = pcre_get_substring((char *)rawstr, ov, MAX_SUBSTRINGS, 1, &str_ptr); if (res < 0) { SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); return -1; } varname = (char *)str_ptr; res = pcre_get_substring((char *)rawstr, ov, MAX_SUBSTRINGS, 2, &str_ptr); if (res < 0) { SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); return -1; } varcontent = (char *)str_ptr; SCLogDebug("varname '%s', varcontent '%s'", varname, varcontent); char *parse_content; if (strlen(varcontent) >= 2 && varcontent[0] == '"' && varcontent[strlen(varcontent) - 1] == '"') { parse_content = varcontent + 1; varcontent[strlen(varcontent) - 1] = '\0'; } else { parse_content = varcontent; } ret = DetectContentDataParse("pktvar", parse_content, &content, &len); if (ret == -1 || content == NULL) { pcre_free(varname); pcre_free(varcontent); return -1; } DetectPktvarData *cd = SCCalloc(1, sizeof(DetectPktvarData)); if (unlikely(cd == NULL)) { pcre_free(varname); pcre_free(varcontent); SCFree(content); return -1; } cd->content = content; cd->content_len = len; cd->id = VarNameStoreSetupAdd(varname, VAR_TYPE_PKT_VAR); pcre_free(varname); pcre_free(varcontent); /* Okay so far so good, lets get this into a SigMatch * and put it in the Signature. */ SigMatch *sm = SigMatchAlloc(); if (unlikely(sm == NULL)) { SCFree(cd->content); SCFree(cd); return -1; } sm->type = DETECT_PKTVAR; sm->ctx = (SigMatchCtx *)cd; SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_MATCH); return 0; }
static int FlowBitsTestSig08(void) { uint8_t *buf = (uint8_t *) "GET /one/ HTTP/1.1\r\n" "Host: one.example.org\r\n" "\r\n"; uint16_t buflen = strlen((char *)buf); Packet *p = SCMalloc(SIZE_OF_PACKET); if (unlikely(p == NULL)) return 0; Signature *s = NULL; ThreadVars th_v; DetectEngineThreadCtx *det_ctx = NULL; DetectEngineCtx *de_ctx = NULL; Flow f; GenericVar flowvar, *gv = NULL; int result = 0; uint32_t idx = 0; memset(p, 0, SIZE_OF_PACKET); memset(&th_v, 0, sizeof(th_v)); memset(&f, 0, sizeof(Flow)); memset(&flowvar, 0, sizeof(GenericVar)); FLOW_INITIALIZE(&f); p->flow = &f; p->flow->flowvar = &flowvar; p->src.family = AF_INET; p->dst.family = AF_INET; p->payload = buf; p->payload_len = buflen; p->proto = IPPROTO_TCP; de_ctx = DetectEngineCtxInit(); FAIL_IF_NULL(de_ctx); de_ctx->flags |= DE_QUIET; s = de_ctx->sig_list = SigInit(de_ctx,"alert ip any any -> any any (msg:\"Flowbit set\"; flowbits:set,myflow2; sid:10;)"); FAIL_IF_NULL(s); s = s->next = SigInit(de_ctx,"alert ip any any -> any any (msg:\"Flowbit unset\"; flowbits:toggle,myflow2; sid:11;)"); FAIL_IF_NULL(s); idx = VarNameStoreSetupAdd("myflow", VAR_TYPE_FLOW_BIT); SigGroupBuild(de_ctx); DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); SigMatchSignatures(&th_v, de_ctx, det_ctx, p); gv = p->flow->flowvar; FAIL_IF_NULL(gv); for ( ; gv != NULL; gv = gv->next) { if (gv->type == DETECT_FLOWBITS && gv->idx == idx) { result = 1; } } FAIL_IF(result); DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); DetectEngineCtxFree(de_ctx); FLOW_DESTROY(&f); SCFree(p); PASS; }
int DetectFlowbitSetup (DetectEngineCtx *de_ctx, Signature *s, const 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) { fb_cmd = DETECT_FLOWBITS_CMD_ISSET; } else if (strcmp(fb_cmd_str,"isnotset") == 0) { fb_cmd = DETECT_FLOWBITS_CMD_ISNOTSET; } else if (strcmp(fb_cmd_str,"set") == 0) { fb_cmd = DETECT_FLOWBITS_CMD_SET; } else if (strcmp(fb_cmd_str,"unset") == 0) { fb_cmd = DETECT_FLOWBITS_CMD_UNSET; } else if (strcmp(fb_cmd_str,"toggle") == 0) { fb_cmd = DETECT_FLOWBITS_CMD_TOGGLE; } else { SCLogError(SC_ERR_UNKNOWN_VALUE, "ERROR: flowbits action \"%s\" is not supported.", fb_cmd_str); goto error; } switch (fb_cmd) { case DETECT_FLOWBITS_CMD_NOALERT: if (strlen(fb_name) != 0) goto error; s->flags |= SIG_FLAG_NOALERT; return 0; case DETECT_FLOWBITS_CMD_ISNOTSET: case DETECT_FLOWBITS_CMD_ISSET: case DETECT_FLOWBITS_CMD_SET: case DETECT_FLOWBITS_CMD_UNSET: case DETECT_FLOWBITS_CMD_TOGGLE: default: if (strlen(fb_name) == 0) goto error; break; } cd = SCMalloc(sizeof(DetectFlowbitsData)); if (unlikely(cd == NULL)) goto error; cd->idx = VarNameStoreSetupAdd(fb_name, VAR_TYPE_FLOW_BIT); cd->cmd = fb_cmd; SCLogDebug("idx %" PRIu32 ", cmd %s, name %s", cd->idx, fb_cmd_str, strlen(fb_name) ? fb_name : "(none)"); /* Okay so far so good, lets get this into a SigMatch * and put it in the Signature. */ sm = SigMatchAlloc(); if (sm == NULL) goto error; sm->type = DETECT_FLOWBITS; sm->ctx = (SigMatchCtx *)cd; switch (fb_cmd) { /* case DETECT_FLOWBITS_CMD_NOALERT can't happen here */ case DETECT_FLOWBITS_CMD_ISNOTSET: case DETECT_FLOWBITS_CMD_ISSET: /* checks, so packet list */ SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_MATCH); break; case DETECT_FLOWBITS_CMD_SET: case DETECT_FLOWBITS_CMD_UNSET: case DETECT_FLOWBITS_CMD_TOGGLE: /* modifiers, only run when entire sig has matched */ SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_POSTMATCH); break; } return 0; error: if (cd != NULL) SCFree(cd); if (sm != NULL) SCFree(sm); return -1; }