/** * \brief this function is used to add the parsed ftpbounce * * \param de_ctx pointer to the Detection Engine Context * \param s pointer to the Current Signature * \param m pointer to the Current SigMatch * \param ftpbouncestr pointer to the user provided ftpbounce options * currently there are no options. * * \retval 0 on Success * \retval -1 on Failure */ int DetectFtpbounceSetup(DetectEngineCtx *de_ctx, Signature *s, char *ftpbouncestr) { SCEnter(); SigMatch *sm = NULL; sm = SigMatchAlloc(); if (sm == NULL) { goto error;; } sm->type = DETECT_FTPBOUNCE; /* We don't need to allocate any data for ftpbounce here. * * TODO: As a suggestion, maybe we can add a flag in the flow * to set the stream as "bounce detected" for fast Match. * When you do a ftp bounce attack you usually use the same * communication control stream to "setup" various destinations * whithout breaking the connection, so I guess we can make it a bit faster * with a flow flag set lookup in the Match function. */ sm->ctx = NULL; if (s->alproto != ALPROTO_UNKNOWN && s->alproto != ALPROTO_FTP) { SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains conflicting keywords."); goto error; } SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_AMATCH); s->alproto = ALPROTO_FTP; s->flags |= SIG_FLAG_APPLAYER; SCReturnInt(0); error: if (sm != NULL) { SigMatchFree(sm); } SCReturnInt(-1); }
/** * \brief this function is used to parse filemd5 options * \brief into the current signature * * \param de_ctx pointer to the Detection Engine Context * \param s pointer to the Current Signature * \param str pointer to the user provided "filemd5" option * * \retval 0 on Success * \retval -1 on Failure */ static int DetectFileMd5Setup (DetectEngineCtx *de_ctx, Signature *s, char *str) { DetectFileMd5Data *filemd5 = NULL; SigMatch *sm = NULL; filemd5 = DetectFileMd5Parse(str); if (filemd5 == NULL) goto error; /* 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_FILEMD5; sm->ctx = (void *)filemd5; SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_FILEMATCH); if (s->alproto != ALPROTO_UNKNOWN && s->alproto != ALPROTO_HTTP) { SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains conflicting keywords."); goto error; } AppLayerHtpNeedFileInspection(); /** \todo remove this once we support more than http */ s->alproto = ALPROTO_HTTP; s->file_flags |= (FILE_SIG_NEED_FILE|FILE_SIG_NEED_MD5); return 0; error: if (filemd5 != NULL) DetectFileMd5Free(filemd5); if (sm != NULL) SCFree(sm); return -1; }
/** * \brief this function is used to parse filesize data into the current signature * * \param de_ctx pointer to the Detection Engine Context * \param s pointer to the Current Signature * \param str pointer to the user provided options * * \retval 0 on Success * \retval -1 on Failure */ static int DetectFilesizeSetup (DetectEngineCtx *de_ctx, Signature *s, char *str) { SCEnter(); DetectFilesizeData *fsd = NULL; SigMatch *sm = NULL; fsd = DetectFilesizeParse(str); if (fsd == NULL) goto error; sm = SigMatchAlloc(); if (sm == NULL) goto error; sm->type = DETECT_FILESIZE; sm->ctx = (void *)fsd; SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_FILEMATCH); if (s->alproto != ALPROTO_UNKNOWN && s->alproto != ALPROTO_HTTP) { SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains conflicting keywords."); goto error; } AppLayerHtpNeedFileInspection(); /** \todo remove this once we support more than http */ s->alproto = ALPROTO_HTTP; s->file_flags |= (FILE_SIG_NEED_FILE|FILE_SIG_NEED_SIZE); SCReturnInt(0); error: if (fsd != NULL) DetectFilesizeFree(fsd); if (sm != NULL) SCFree(sm); SCReturnInt(-1); }
/** * \brief this function is used to add the parsed "fingerprint" option * \brief into the current signature * * \param de_ctx pointer to the Detection Engine Context * \param s pointer to the Current Signature * \param id pointer to the user provided "fingerprint" option * * \retval 0 on Success * \retval -1 on Failure */ static int DetectTlsFingerprintSetup (DetectEngineCtx *de_ctx, Signature *s, char *str) { DetectTlsData *tls = NULL; SigMatch *sm = NULL; tls = DetectTlsFingerprintParse(str); if (tls == NULL) goto error; /* Okay so far so good, lets get this into a SigMatch * and put it in the Signature. */ sm = SigMatchAlloc(); if (sm == NULL) goto error; if (s->alproto != ALPROTO_UNKNOWN && s->alproto != ALPROTO_TLS) { SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains conflicting keywords."); goto error; } sm->type = DETECT_AL_TLS_FINGERPRINT; sm->ctx = (void *)tls; s->flags |= SIG_FLAG_APPLAYER; s->alproto = ALPROTO_TLS; SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_AMATCH); return 0; error: if (tls != NULL) DetectTlsFingerprintFree(tls); if (sm != NULL) SCFree(sm); return -1; }
/** \internal * * \brief this function is used to add the parsed "id" option into the current signature * * \param de_ctx Pointer to the Detection Engine Context * \param s Pointer to the Current Signature * \param str Pointer to the user provided "id" option * * \retval 0 on Success or -1 on Failure */ static int DetectModbusSetup(DetectEngineCtx *de_ctx, Signature *s, char *str) { SCEnter(); DetectModbus *modbus = NULL; SigMatch *sm = NULL; if (s->alproto != ALPROTO_UNKNOWN && s->alproto != ALPROTO_MODBUS) { SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains conflicting keywords."); goto error; } if ((modbus = DetectModbusFunctionParse(str)) == NULL) { if ((modbus = DetectModbusAccessParse(str)) == NULL) { SCLogError(SC_ERR_PCRE_MATCH, "invalid modbus option"); goto error; } } /* 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_AL_MODBUS; sm->ctx = (void *) modbus; SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_MODBUS_MATCH); s->alproto = ALPROTO_MODBUS; SCReturnInt(0); error: if (modbus != NULL) DetectModbusFree(modbus); if (sm != NULL) SCFree(sm); SCReturnInt(-1); }
int DetectAppLayerProtocolSetup(DetectEngineCtx *de_ctx, Signature *s, char *arg) { DetectAppLayerProtocolData *data = NULL; SigMatch *sm = NULL; if (s->alproto != ALPROTO_UNKNOWN) { SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "Either we already " "have the rule match on an app layer protocol set through " "other keywords that match on this protocol, or have " "already seen a non-negated app-layer-protocol."); goto error; } data = DetectAppLayerProtocolParse(arg); if (data == NULL) goto error; if (!data->negated) s->alproto = data->alproto; sm = SigMatchAlloc(); if (sm == NULL) goto error; sm->type = DETECT_AL_APP_LAYER_PROTOCOL; sm->ctx = (void *)data; SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_AMATCH); s->flags |= SIG_FLAG_APPLAYER; return 0; error: if (data != NULL) SCFree(data); return -1; }
/** * \brief this function is used to add the parsed "id" option * \brief into the current signature * * \param de_ctx pointer to the Detection Engine Context * \param s pointer to the Current Signature * \param idstr pointer to the user provided "id" option * * \retval 0 on Success * \retval -1 on Failure */ static int DetectSshSoftwareVersionSetup (DetectEngineCtx *de_ctx, Signature *s, char *str) { DetectSshSoftwareVersionData *ssh = NULL; SigMatch *sm = NULL; ssh = DetectSshSoftwareVersionParse(str); if (ssh == NULL) goto error; /* Okay so far so good, lets get this into a SigMatch * and put it in the Signature. */ sm = SigMatchAlloc(); if (sm == NULL) goto error; if (s->alproto != ALPROTO_UNKNOWN && s->alproto != ALPROTO_SSH) { SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains conflicting keywords."); goto error; } sm->type = DETECT_AL_SSH_SOFTWAREVERSION; sm->ctx = (void *)ssh; s->flags |= SIG_FLAG_APPLAYER; s->alproto = ALPROTO_SSH; SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_AMATCH); return 0; error: if (ssh != NULL) DetectSshSoftwareVersionFree(ssh); if (sm != NULL) SCFree(sm); return -1; }
/** * \internal * \brief this function is used to add the sameip option into the signature * * \param de_ctx pointer to the Detection Engine Context * \param s pointer to the Current Signature * \param optstr pointer to the user provided options * * \retval 0 on Success * \retval -1 on Failure */ static int DetectSameipSetup(DetectEngineCtx *de_ctx, Signature *s, char *optstr) { SigMatch *sm = NULL; /* Get this into a SigMatch and put it in the Signature. */ sm = SigMatchAlloc(); if (sm == NULL) goto error; sm->type = DETECT_SAMEIP; sm->ctx = NULL; SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_MATCH); s->flags |= SIG_FLAG_REQUIRE_PACKET; return 0; error: if (sm != NULL) SCFree(sm); return -1; }
/** * \brief this function is used to add the parsed icmp_seq data into the current signature * * \param de_ctx pointer to the Detection Engine Context * \param s pointer to the Current Signature * \param icmpseqstr pointer to the user provided icmp_seq option * * \retval 0 on Success * \retval -1 on Failure */ static int DetectIcmpSeqSetup (DetectEngineCtx *de_ctx, Signature *s, char *icmpseqstr) { DetectIcmpSeqData *iseq = NULL; SigMatch *sm = NULL; iseq = DetectIcmpSeqParse(icmpseqstr); if (iseq == NULL) goto error; sm = SigMatchAlloc(); if (sm == NULL) goto error; sm->type = DETECT_ICMP_SEQ; sm->ctx = (void *)iseq; SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_MATCH); return 0; error: if (iseq != NULL) DetectIcmpSeqFree(iseq); if (sm != NULL) SCFree(sm); return -1; }
/** * \brief this function is used to add the parsed fragoffset data into the current signature * * \param de_ctx pointer to the Detection Engine Context * \param s pointer to the Current Signature * \param fragoffsetstr pointer to the user provided fragoffset option * * \retval 0 on Success * \retval -1 on Failure */ static int DetectFragOffsetSetup (DetectEngineCtx *de_ctx, Signature *s, char *fragoffsetstr) { DetectFragOffsetData *fragoff = NULL; SigMatch *sm = NULL; fragoff = DetectFragOffsetParse(fragoffsetstr); if (fragoff == NULL) goto error; sm = SigMatchAlloc(); if (sm == NULL) goto error; sm->type = DETECT_FRAGOFFSET; sm->ctx = (void *)fragoff; SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_MATCH); s->flags |= SIG_FLAG_REQUIRE_PACKET; return 0; error: if (fragoff != NULL) DetectFragOffsetFree(fragoff); if (sm != NULL) SCFree(sm); return -1; }
/** * \brief this function is used to add the parsed icode data into the current signature * * \param de_ctx pointer to the Detection Engine Context * \param s pointer to the Current Signature * \param icodestr pointer to the user provided icode options * * \retval 0 on Success * \retval -1 on Failure */ static int DetectICodeSetup(DetectEngineCtx *de_ctx, Signature *s, char *icodestr) { DetectICodeData *icd = NULL; SigMatch *sm = NULL; icd = DetectICodeParse(icodestr); if (icd == NULL) goto error; sm = SigMatchAlloc(); if (sm == NULL) goto error; sm->type = DETECT_ICODE; sm->ctx = (void *)icd; SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_MATCH); s->flags |= SIG_FLAG_REQUIRE_PACKET; return 0; error: if (icd != NULL) DetectICodeFree(icd); if (sm != NULL) SCFree(sm); return -1; }
/** * \brief this function is used to parse luajit options * \brief into the current signature * * \param de_ctx pointer to the Detection Engine Context * \param s pointer to the Current Signature * \param str pointer to the user provided "luajit" option * * \retval 0 on Success * \retval -1 on Failure */ static int DetectLuajitSetup (DetectEngineCtx *de_ctx, Signature *s, char *str) { DetectLuajitData *luajit = NULL; SigMatch *sm = NULL; luajit = DetectLuajitParse(str); if (luajit == NULL) goto error; if (DetectLuaSetupPrime(luajit) == -1) { goto error; } luajit->thread_ctx_id = DetectRegisterThreadCtxFuncs(de_ctx, "luajit", DetectLuajitThreadInit, (void *)luajit, DetectLuajitThreadFree, 0); if (luajit->thread_ctx_id == -1) goto error; if (luajit->alproto != ALPROTO_UNKNOWN) { if (s->alproto != ALPROTO_UNKNOWN && luajit->alproto != s->alproto) { goto error; } s->alproto = luajit->alproto; } /* 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_LUAJIT; sm->ctx = (void *)luajit; if (luajit->alproto == ALPROTO_UNKNOWN) SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_MATCH); else if (luajit->alproto == ALPROTO_HTTP) { if (luajit->flags & DATATYPE_HTTP_RESPONSE_BODY) SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_HSBDMATCH); else if (luajit->flags & DATATYPE_HTTP_REQUEST_BODY) SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_HCBDMATCH); else if (luajit->flags & DATATYPE_HTTP_URI) SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_UMATCH); else if (luajit->flags & DATATYPE_HTTP_URI_RAW) SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_HRUDMATCH); else if (luajit->flags & DATATYPE_HTTP_REQUEST_COOKIE) SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_HCDMATCH); else if (luajit->flags & DATATYPE_HTTP_REQUEST_UA) SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_HUADMATCH); else if (luajit->flags & (DATATYPE_HTTP_REQUEST_HEADERS|DATATYPE_HTTP_RESPONSE_HEADERS)) SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_HHDMATCH); else if (luajit->flags & (DATATYPE_HTTP_REQUEST_HEADERS_RAW|DATATYPE_HTTP_RESPONSE_HEADERS_RAW)) SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_HRHDMATCH); else if (luajit->flags & DATATYPE_HTTP_RESPONSE_COOKIE) SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_HCDMATCH); else SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_AMATCH); } de_ctx->detect_luajit_instances++; return 0; error: if (luajit != NULL) DetectLuajitFree(luajit); if (sm != NULL) SCFree(sm); return -1; }
/** * \brief This function is used to add the parsed isdataatdata into the current * signature. * \param de_ctx pointer to the Detection Engine Context * \param s pointer to the Current Signature * \param isdataatstr pointer to the user provided isdataat options * * \retval 0 on Success * \retval -1 on Failure */ int DetectIsdataatSetup (DetectEngineCtx *de_ctx, Signature *s, char *isdataatstr) { DetectIsdataatData *idad = NULL; SigMatch *sm = NULL; SigMatch *dm = NULL; SigMatch *pm = NULL; SigMatch *prev_pm = NULL; char *offset = NULL; idad = DetectIsdataatParse(isdataatstr, &offset); if (idad == NULL) goto error; sm = SigMatchAlloc(); if (sm == NULL) goto error; sm->type = DETECT_ISDATAAT; sm->ctx = (void *)idad; if (s->alproto == ALPROTO_DCERPC && (idad->flags & ISDATAAT_RELATIVE)) { pm = SigMatchGetLastSMFromLists(s, 6, DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_PMATCH]); dm = SigMatchGetLastSMFromLists(s, 6, DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_DMATCH], DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_DMATCH], DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_DMATCH]); if (pm == NULL) { SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_DMATCH); } else if (dm == NULL) { SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_DMATCH); } else if (pm->idx > dm->idx) { SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_PMATCH); } else { SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_DMATCH); } prev_pm = SigMatchGetLastSMFromLists(s, 6, DETECT_CONTENT, sm->prev, DETECT_BYTEJUMP, sm->prev, DETECT_PCRE, sm->prev); if (prev_pm == NULL) { SCLogDebug("No preceding content or pcre keyword. Possible " "since this is a dce alproto sig."); if (offset != NULL) { SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown byte_extract var " "seen in isdataat - %s", offset); goto error; } return 0; } } else if (s->init_flags & SIG_FLAG_INIT_FILE_DATA) { if (idad->flags & ISDATAAT_RELATIVE) { pm = SigMatchGetLastSMFromLists(s, 10, DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HSBDMATCH], DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HSBDMATCH], DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HSBDMATCH], DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HSBDMATCH], DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HSBDMATCH]); if (pm == NULL) { idad->flags &= ~ISDATAAT_RELATIVE; } s->flags |= SIG_FLAG_APPLAYER; AppLayerHtpEnableResponseBodyCallback(); SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_HSBDMATCH); } else { s->flags |= SIG_FLAG_APPLAYER; AppLayerHtpEnableResponseBodyCallback(); SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_HSBDMATCH); } if (pm == NULL) { SCLogDebug("No preceding content or pcre keyword. Possible " "since this is a file_data sig."); if (offset != NULL) { SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown byte_extract var " "seen in isdataat - %s", offset); goto error; } return 0; } prev_pm = pm; } else { if (!(idad->flags & ISDATAAT_RELATIVE)) { SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_PMATCH); if (offset != NULL) { SigMatch *bed_sm = DetectByteExtractRetrieveSMVar(offset, s, SigMatchListSMBelongsTo(s, sm)); if (bed_sm == NULL) { SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown byte_extract var " "seen in isdataat - %s\n", offset); goto error; } DetectIsdataatData *isdd = sm->ctx; isdd->dataat = ((DetectByteExtractData *)bed_sm->ctx)->local_id; isdd->flags |= ISDATAAT_OFFSET_BE; SCFree(offset); } return 0; } pm = SigMatchGetLastSMFromLists(s, 66, DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH], DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HSBDMATCH], DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH], DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH], DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH], DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH], DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH], DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH], DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH], DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HUADMATCH], DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH], DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH], DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH], DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HSBDMATCH], DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH], DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH], DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH], DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH], DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH], DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HUADMATCH], DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH], DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH], DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_DMATCH], DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_DMATCH], DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_UMATCH]); if (pm == NULL) { SCLogError(SC_ERR_INVALID_SIGNATURE, "isdataat relative seen " "without a previous content uricontent, " "http_client_body, http_header, http_raw_header, " "http_method, http_cookie, http_raw_uri, " "http_stat_msg, http_stat_code, byte_test, " "byte_extract, byte_jump, http_user_agent, " "http_host or http_raw_host keyword"); goto error; } else { int list_type = SigMatchListSMBelongsTo(s, pm); if (list_type == -1) { goto error; } SigMatchAppendSMToList(s, sm, list_type); } /* else - if (pm == NULL) */ prev_pm = pm; } if (offset != NULL) { SigMatch *bed_sm = DetectByteExtractRetrieveSMVar(offset, s, SigMatchListSMBelongsTo(s, sm)); if (bed_sm == NULL) { SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown byte_extract var " "seen in isdataat - %s\n", offset); goto error; } DetectIsdataatData *isdd = sm->ctx; isdd->dataat = ((DetectByteExtractData *)bed_sm->ctx)->local_id; isdd->flags |= ISDATAAT_OFFSET_BE; SCFree(offset); } DetectContentData *cd = NULL; DetectPcreData *pe = NULL; switch (prev_pm->type) { case DETECT_CONTENT: /* Set the relative next flag on the prev sigmatch */ cd = (DetectContentData *)prev_pm->ctx; if (cd == NULL) { SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous-" "previous keyword!"); return -1; } cd->flags |= DETECT_CONTENT_RELATIVE_NEXT; break; case DETECT_PCRE: pe = (DetectPcreData *)prev_pm->ctx; if (pe == NULL) { SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous-" "previous keyword!"); return -1; } pe->flags |= DETECT_PCRE_RELATIVE_NEXT; break; case DETECT_BYTEJUMP: case DETECT_BYTETEST: case DETECT_BYTE_EXTRACT: SCLogDebug("Do nothing for byte_jump, byte_test, byte_extract"); break; default: /* this will never hit */ SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous-" "previous keyword!"); return -1; } /* switch */ return 0; error: return -1; }
int DetectBytejumpSetup(DetectEngineCtx *de_ctx, Signature *s, char *optstr) { DetectBytejumpData *data = NULL; SigMatch *sm = NULL; char *offset = NULL; data = DetectBytejumpParse(optstr, &offset); if (data == NULL) goto error; sm = SigMatchAlloc(); if (sm == NULL) goto error; sm->type = DETECT_BYTEJUMP; sm->ctx = (void *)data; /* check bytejump modifiers against the signature alproto. In case they conflict * chuck out invalid signature */ if (data->flags & DETECT_BYTEJUMP_DCE) { if (s->alproto != ALPROTO_DCERPC) { SCLogError(SC_ERR_INVALID_SIGNATURE, "Non dce alproto sig has " "bytetest with dce enabled"); goto error; } if ( (data->flags & DETECT_BYTEJUMP_STRING) || (data->flags & DETECT_BYTEJUMP_LITTLE) || (data->flags & DETECT_BYTEJUMP_BIG) || (data->flags & DETECT_BYTEJUMP_BEGIN) || (data->base == DETECT_BYTEJUMP_BASE_DEC) || (data->base == DETECT_BYTEJUMP_BASE_HEX) || (data->base == DETECT_BYTEJUMP_BASE_OCT) ) { SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "Invalid option. " "DCERPC rule holds an invalid modifier for bytejump."); goto error; } } if (s->init_flags & SIG_FLAG_INIT_FILE_DATA) { if (data->flags & DETECT_BYTEJUMP_RELATIVE) { SigMatch *prev_sm = NULL; prev_sm = SigMatchGetLastSMFromLists(s, 8, DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HSBDMATCH], DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HSBDMATCH], DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HSBDMATCH], DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HSBDMATCH]); if (prev_sm == NULL) { data->flags &= ~DETECT_BYTEJUMP_RELATIVE; } s->flags |= SIG_FLAG_APPLAYER; AppLayerHtpEnableResponseBodyCallback(); SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_HSBDMATCH); } else { s->flags |= SIG_FLAG_APPLAYER; AppLayerHtpEnableResponseBodyCallback(); SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_HSBDMATCH); } } else if (s->alproto == ALPROTO_DCERPC && (data->flags & DETECT_BYTEJUMP_RELATIVE)) { SigMatch *pm = NULL; SigMatch *dm = NULL; pm = SigMatchGetLastSMFromLists(s, 6, DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_PMATCH]); dm = SigMatchGetLastSMFromLists(s, 6, DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_DMATCH], DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_DMATCH], DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_DMATCH]); if (pm == NULL) { SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_DMATCH); } else if (dm == NULL) { SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_DMATCH); } else if (pm->idx > dm->idx) { SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_PMATCH); } else { SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_DMATCH); } } else { SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_PMATCH); } if (offset != NULL) { SigMatch *bed_sm = DetectByteExtractRetrieveSMVar(offset, s, SigMatchListSMBelongsTo(s, sm)); if (bed_sm == NULL) { SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown byte_extract var " "seen in byte_jump - %s\n", offset); goto error; } DetectBytejumpData *bjd = sm->ctx; bjd->offset = ((DetectByteExtractData *)bed_sm->ctx)->local_id; bjd->flags |= DETECT_BYTEJUMP_OFFSET_BE; SCFree(offset); } if (s->init_flags & SIG_FLAG_INIT_FILE_DATA) { return 0; } if ( !(data->flags & DETECT_BYTEJUMP_RELATIVE)) { return(0); } SigMatch *prev_sm = NULL; prev_sm = SigMatchGetLastSMFromLists(s, 6, DETECT_CONTENT, sm->prev, DETECT_BYTEJUMP, sm->prev, DETECT_PCRE, sm->prev); if (prev_sm == NULL) { if (s->alproto == ALPROTO_DCERPC) { SCLogDebug("No preceding content or pcre keyword. Possible " "since this is an alproto sig."); return 0; } else { SCLogError(SC_ERR_INVALID_SIGNATURE, "No preceding content " "or uricontent or pcre option"); return -1; } } DetectContentData *cd = NULL; DetectPcreData *pe = NULL; switch (prev_sm->type) { case DETECT_CONTENT: /* Set the relative next flag on the prev sigmatch */ cd = (DetectContentData *)prev_sm->ctx; if (cd == NULL) { SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous-" "previous keyword!"); return -1; } cd->flags |= DETECT_CONTENT_RELATIVE_NEXT; break; case DETECT_PCRE: pe = (DetectPcreData *)prev_sm->ctx; if (pe == NULL) { SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous-" "previous keyword!"); return -1; } pe->flags |= DETECT_PCRE_RELATIVE_NEXT; break; case DETECT_BYTEJUMP: SCLogDebug("No setting relative_next for bytejump. We " "have no use for it"); break; default: /* this will never hit */ SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous-" "previous keyword!"); return -1; } /* switch */ return 0; error: if (data != NULL) DetectBytejumpFree(data); if (sm != NULL) SCFree(sm); return -1; }
static int DetectBytejumpSetup(DetectEngineCtx *de_ctx, Signature *s, const char *optstr) { SigMatch *sm = NULL; SigMatch *prev_pm = NULL; DetectBytejumpData *data = NULL; char *offset = NULL; int ret = -1; data = DetectBytejumpParse(optstr, &offset); if (data == NULL) goto error; int sm_list; if (s->init_data->list != DETECT_SM_LIST_NOTSET) { sm_list = s->init_data->list; if (data->flags & DETECT_BYTEJUMP_RELATIVE) { prev_pm = DetectGetLastSMFromLists(s, DETECT_CONTENT, DETECT_PCRE, -1); } } else if (data->flags & DETECT_BYTEJUMP_DCE) { if (data->flags & DETECT_BYTEJUMP_RELATIVE) { prev_pm = DetectGetLastSMFromLists(s, DETECT_CONTENT, DETECT_PCRE, DETECT_BYTETEST, DETECT_BYTEJUMP, DETECT_BYTE_EXTRACT, DETECT_ISDATAAT, -1); if (prev_pm == NULL) { sm_list = DETECT_SM_LIST_PMATCH; } else { sm_list = SigMatchListSMBelongsTo(s, prev_pm); if (sm_list < 0) goto error; } } else { sm_list = DETECT_SM_LIST_PMATCH; } if (DetectSignatureSetAppProto(s, ALPROTO_DCERPC) != 0) goto error; } else if (data->flags & DETECT_BYTEJUMP_RELATIVE) { prev_pm = DetectGetLastSMFromLists(s, DETECT_CONTENT, DETECT_PCRE, DETECT_BYTETEST, DETECT_BYTEJUMP, DETECT_BYTE_EXTRACT, DETECT_ISDATAAT, -1); if (prev_pm == NULL) { sm_list = DETECT_SM_LIST_PMATCH; } else { sm_list = SigMatchListSMBelongsTo(s, prev_pm); if (sm_list < 0) goto error; } } else { sm_list = DETECT_SM_LIST_PMATCH; } if (data->flags & DETECT_BYTEJUMP_DCE) { if ((data->flags & DETECT_BYTEJUMP_STRING) || (data->flags & DETECT_BYTEJUMP_LITTLE) || (data->flags & DETECT_BYTEJUMP_BIG) || (data->flags & DETECT_BYTEJUMP_BEGIN) || (data->base == DETECT_BYTEJUMP_BASE_DEC) || (data->base == DETECT_BYTEJUMP_BASE_HEX) || (data->base == DETECT_BYTEJUMP_BASE_OCT) ) { SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "Invalid option. " "A byte_jump keyword with dce holds other invalid modifiers."); goto error; } } if (offset != NULL) { SigMatch *bed_sm = DetectByteExtractRetrieveSMVar(offset, s); if (bed_sm == NULL) { SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown byte_extract var " "seen in byte_jump - %s\n", offset); goto error; } data->offset = ((DetectByteExtractData *)bed_sm->ctx)->local_id; data->flags |= DETECT_BYTEJUMP_OFFSET_BE; SCFree(offset); } sm = SigMatchAlloc(); if (sm == NULL) goto error; sm->type = DETECT_BYTEJUMP; sm->ctx = (SigMatchCtx *)data; SigMatchAppendSMToList(s, sm, sm_list); if (!(data->flags & DETECT_BYTEJUMP_RELATIVE)) goto okay; if (prev_pm == NULL) goto okay; if (prev_pm->type == DETECT_CONTENT) { DetectContentData *cd = (DetectContentData *)prev_pm->ctx; cd->flags |= DETECT_CONTENT_RELATIVE_NEXT; } else if (prev_pm->type == DETECT_PCRE) { DetectPcreData *pd = (DetectPcreData *)prev_pm->ctx; pd->flags |= DETECT_PCRE_RELATIVE_NEXT; } okay: ret = 0; return ret; error: DetectBytejumpFree(data); return ret; }
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) { 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 = VariableNameGetIdx(de_ctx, 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; }
/** * \brief This function is used to add the parsed isdataatdata into the current * signature. * \param de_ctx pointer to the Detection Engine Context * \param s pointer to the Current Signature * \param isdataatstr pointer to the user provided isdataat options * * \retval 0 on Success * \retval -1 on Failure */ int DetectIsdataatSetup (DetectEngineCtx *de_ctx, Signature *s, char *isdataatstr) { DetectIsdataatData *idad = NULL; SigMatch *sm = NULL; SigMatch *dm = NULL; SigMatch *pm = NULL; SigMatch *prev_pm = NULL; idad = DetectIsdataatParse(isdataatstr); if (idad == NULL) goto error; sm = SigMatchAlloc(); if (sm == NULL) goto error; sm->type = DETECT_ISDATAAT; sm->ctx = (void *)idad; if (s->alproto == ALPROTO_DCERPC && idad->flags & ISDATAAT_RELATIVE) { pm = SigMatchGetLastSMFromLists(s, 6, DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_PMATCH]); dm = SigMatchGetLastSMFromLists(s, 6, DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_DMATCH], DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_DMATCH], DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_DMATCH]); if (pm == NULL) { SigMatchAppendDcePayload(s, sm); } else if (dm == NULL) { SigMatchAppendDcePayload(s, sm); } else if (pm->idx > dm->idx) { SigMatchAppendPayload(s, sm); } else { SigMatchAppendDcePayload(s, sm); } prev_pm = SigMatchGetLastSMFromLists(s, 6, DETECT_CONTENT, sm->prev, DETECT_BYTEJUMP, sm->prev, DETECT_PCRE, sm->prev); } else { pm = SigMatchGetLastSMFromLists(s, 30, DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], DETECT_URICONTENT, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], DETECT_AL_HTTP_CLIENT_BODY, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH], DETECT_AL_HTTP_HEADER, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH], DETECT_AL_HTTP_RAW_HEADER, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH], DETECT_AL_HTTP_METHOD, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH], DETECT_AL_HTTP_COOKIE, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH], DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH], DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH], DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH], DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH], DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH], DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_PMATCH]); if (pm == NULL) { if (idad->flags & ISDATAAT_RELATIVE) { SCLogError(SC_ERR_INVALID_SIGNATURE, "isdataat relative seen " "without a previous content uricontent, " "http_client_body, http_header, http_raw_header, " "http_method or http_cookie keyword"); goto error; } else { SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_PMATCH); } } else { int list_type; if (pm->type == DETECT_PCRE || pm->type == DETECT_BYTEJUMP) { list_type = SigMatchListSMBelongsTo(s, pm); if (list_type == -1) { goto error; } } else { switch (pm->type) { case DETECT_CONTENT: list_type = DETECT_SM_LIST_PMATCH; break; case DETECT_URICONTENT: list_type = DETECT_SM_LIST_UMATCH; break; case DETECT_AL_HTTP_CLIENT_BODY: list_type = DETECT_SM_LIST_HCBDMATCH; break; case DETECT_AL_HTTP_RAW_HEADER: list_type = DETECT_SM_LIST_HRHDMATCH; break; case DETECT_AL_HTTP_HEADER: list_type = DETECT_SM_LIST_HHDMATCH; break; case DETECT_AL_HTTP_METHOD: list_type = DETECT_SM_LIST_HMDMATCH; break; case DETECT_AL_HTTP_COOKIE: list_type = DETECT_SM_LIST_HCDMATCH; break; } /* switch */ } /* else */ SigMatchAppendSMToList(s, sm, list_type); } /* else - if (pm == NULL) */ prev_pm = pm; } if (!(idad->flags & ISDATAAT_RELATIVE)) { return 0; } if (prev_pm == NULL) { if (s->alproto == ALPROTO_DCERPC) { SCLogDebug("No preceding content or pcre keyword. Possible " "since this is a dce alproto sig."); return 0; } else { SCLogError(SC_ERR_INVALID_SIGNATURE, "No preceding content, pcre, " "uricontent, http_client_body, http_header, " "http_raw_header, http_method or http_cookie keyword"); goto error; } } DetectContentData *cd = NULL; DetectPcreData *pe = NULL; switch (prev_pm->type) { case DETECT_CONTENT: case DETECT_URICONTENT: case DETECT_AL_HTTP_CLIENT_BODY: case DETECT_AL_HTTP_HEADER: case DETECT_AL_HTTP_RAW_HEADER: case DETECT_AL_HTTP_METHOD: case DETECT_AL_HTTP_COOKIE: /* Set the relative next flag on the prev sigmatch */ cd = (DetectContentData *)prev_pm->ctx; if (cd == NULL) { SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous-" "previous keyword!"); return -1; } cd->flags |= DETECT_CONTENT_RELATIVE_NEXT; break; case DETECT_PCRE: pe = (DetectPcreData *)prev_pm->ctx; if (pe == NULL) { SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous-" "previous keyword!"); return -1; } pe->flags |= DETECT_PCRE_RELATIVE_NEXT; break; case DETECT_BYTEJUMP: SCLogDebug("Do nothing for bytejump"); break; default: /* this will never hit */ SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous-" "previous keyword!"); return -1; } /* switch */ return 0; error: //if (idad != NULL) // DetectIsdataatFree(idad); //if (sm != NULL) // SCFree(sm); return -1; }
int DetectIPRepSetup (DetectEngineCtx *de_ctx, Signature *s, char *rawstr) { DetectIPRepData *cd = NULL; SigMatch *sm = NULL; char *cmd_str = NULL, *name = NULL, *op_str = NULL, *value = NULL; uint8_t cmd = 0; #define MAX_SUBSTRINGS 30 int ret = 0, res = 0; int ov[MAX_SUBSTRINGS]; ret = pcre_exec(parse_regex, parse_regex_study, rawstr, strlen(rawstr), 0, 0, ov, MAX_SUBSTRINGS); if (ret != 5) { SCLogError(SC_ERR_PCRE_MATCH, "\"%s\" is not a valid setting for iprep", 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; } cmd_str = (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"); goto error; } name = (char *)str_ptr; res = pcre_get_substring((char *)rawstr, ov, MAX_SUBSTRINGS, 3, &str_ptr); if (res < 0) { SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); goto error; } op_str = (char *)str_ptr; res = pcre_get_substring((char *)rawstr, ov, MAX_SUBSTRINGS, 4, &str_ptr); if (res < 0) { SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); goto error; } value = (char *)str_ptr; if (strcmp(cmd_str,"any") == 0) { cmd = DETECT_IPREP_CMD_ANY; } else if (strcmp(cmd_str,"both") == 0) { cmd = DETECT_IPREP_CMD_BOTH; } else if (strcmp(cmd_str,"src") == 0) { cmd = DETECT_IPREP_CMD_SRC; } else if (strcmp(cmd_str,"dst") == 0) { cmd = DETECT_IPREP_CMD_DST; } else { SCLogError(SC_ERR_UNKNOWN_VALUE, "ERROR: iprep \"%s\" is not supported.", cmd_str); goto error; } //SCLogInfo("category %s", name); uint8_t cat = SRepCatGetByShortname(name); if (cat == 0) { SCLogError(SC_ERR_UNKNOWN_VALUE, "unknown iprep category \"%s\"", name); goto error; } uint8_t op = 0; uint8_t val = 0; if (op_str == NULL || strlen(op_str) != 1) { goto error; } switch(op_str[0]) { case '<': op = DETECT_IPREP_OP_LT; break; case '>': op = DETECT_IPREP_OP_GT; break; case '=': op = DETECT_IPREP_OP_EQ; break; default: goto error; break; } if (value != NULL && strlen(value) > 0) { int ival = atoi(value); if (ival < 0 || ival > 127) goto error; val = (uint8_t)ival; } cd = SCMalloc(sizeof(DetectIPRepData)); if (unlikely(cd == NULL)) goto error; cd->cmd = cmd; cd->cat = cat; cd->op = op; cd->val = val; //SCLogInfo("cmd %u, cat %u, op %u, val %u", cd->cmd, cd->cat, cd->op, cd->val); pcre_free_substring(name); name = NULL; pcre_free_substring(cmd_str); cmd_str = NULL; /* 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_IPREP; sm->ctx = (void *)cd; SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_MATCH); return 0; error: if (name != NULL) pcre_free_substring(name); if (cmd_str != NULL) pcre_free_substring(cmd_str); if (cd != NULL) SCFree(cd); if (sm != NULL) SCFree(sm); return -1; }
static int DetectBase64DecodeSetup(DetectEngineCtx *de_ctx, Signature *s, char *str) { uint32_t bytes = 0; uint32_t offset = 0; uint8_t relative = 0; DetectBase64Decode *data = NULL; int sm_list; SigMatch *sm = NULL; SigMatch *pm = NULL; if (str != NULL) { if (!DetectBase64DecodeParse(str, &bytes, &offset, &relative)) { goto error; } } data = SCCalloc(1, sizeof(DetectBase64Decode)); if (unlikely(data == NULL)) { goto error; } data->bytes = bytes; data->offset = offset; data->relative = relative; if (s->list != DETECT_SM_LIST_NOTSET) { sm_list = s->list; #if 0 if (data->relative) { pm = SigMatchGetLastSMFromLists(s, 4, DETECT_CONTENT, s->sm_lists_tail[sm_list], DETECT_PCRE, s->sm_lists_tail[sm_list]); } #endif } else { /* Copied from detect-isdataat.c. */ pm = SigMatchGetLastSMFromLists(s, 168, DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH], DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_FILEDATA], DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH], DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH], DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH], DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH], DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH], DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH], DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH], DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HUADMATCH], DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH], DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH], DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH], DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_FILEDATA], DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH], DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH], DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH], DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH], DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH], DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH], DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH], DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HUADMATCH], DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH], DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH], DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH], DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_FILEDATA], DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH], DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH], DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH], DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH], DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH], DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH], DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH], DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HUADMATCH], DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH], DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH], DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH], DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_FILEDATA], DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH], DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH], DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH], DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH], DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH], DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH], DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH], DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HUADMATCH], DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH], DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH], DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH], DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_FILEDATA], DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH], DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH], DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH], DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH], DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH], DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH], DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH], DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HUADMATCH], DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH], DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH], DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH], DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_FILEDATA], DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH], DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH], DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH], DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH], DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH], DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH], DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH], DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_HUADMATCH], DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH], DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH]); if (pm == NULL) { sm_list = DETECT_SM_LIST_PMATCH; } else { sm_list = SigMatchListSMBelongsTo(s, pm); if (sm_list < 0) { goto error; } } } sm = SigMatchAlloc(); if (sm == NULL) { goto error; } sm->type = DETECT_BASE64_DECODE; sm->ctx = (SigMatchCtx *)data; SigMatchAppendSMToList(s, sm, sm_list); if (!data->bytes) { data->bytes = BASE64_DECODE_MAX; } if (data->bytes > de_ctx->base64_decode_max_len) { de_ctx->base64_decode_max_len = data->bytes; } return 0; error: if (data != NULL) { SCFree(data); } return -1; }
/** * \brief this function is used to parse filestore options * \brief into the current signature * * \param de_ctx pointer to the Detection Engine Context * \param s pointer to the Current Signature * \param str pointer to the user provided "filestore" option * * \retval 0 on Success * \retval -1 on Failure */ static int DetectFilestoreSetup (DetectEngineCtx *de_ctx, Signature *s, char *str) { SCEnter(); DetectFilestoreData *fd = NULL; SigMatch *sm = NULL; char *args[3] = {NULL,NULL,NULL}; #define MAX_SUBSTRINGS 30 int ret = 0, res = 0; int ov[MAX_SUBSTRINGS]; sm = SigMatchAlloc(); if (sm == NULL) goto error; sm->type = DETECT_FILESTORE; if (str != NULL && strlen(str) > 0) { SCLogDebug("str %s", str); ret = pcre_exec(parse_regex, parse_regex_study, str, strlen(str), 0, 0, ov, MAX_SUBSTRINGS); if (ret < 1 || ret > 4) { SCLogError(SC_ERR_PCRE_MATCH, "parse error, ret %" PRId32 ", string %s", ret, str); goto error; } if (ret > 1) { const char *str_ptr; res = pcre_get_substring((char *)str, ov, MAX_SUBSTRINGS, 1, &str_ptr); if (res < 0) { SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); goto error; } args[0] = (char *)str_ptr; if (ret > 2) { res = pcre_get_substring((char *)str, ov, MAX_SUBSTRINGS, 2, &str_ptr); if (res < 0) { SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); goto error; } args[1] = (char *)str_ptr; } if (ret > 3) { res = pcre_get_substring((char *)str, ov, MAX_SUBSTRINGS, 3, &str_ptr); if (res < 0) { SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); goto error; } args[2] = (char *)str_ptr; } } fd = SCMalloc(sizeof(DetectFilestoreData)); if (fd == NULL) goto error; memset(fd, 0x00, sizeof(DetectFilestoreData)); if (args[0] != NULL) { SCLogDebug("first arg %s", args[0]); if (strcasecmp(args[0], "request") == 0 || strcasecmp(args[0], "to_server") == 0) { fd->direction = FILESTORE_DIR_TOSERVER; fd->scope = FILESTORE_SCOPE_TX; } else if (strcasecmp(args[0], "response") == 0 || strcasecmp(args[0], "to_client") == 0) { fd->direction = FILESTORE_DIR_TOCLIENT; fd->scope = FILESTORE_SCOPE_TX; } else if (strcasecmp(args[0], "both") == 0) { fd->direction = FILESTORE_DIR_BOTH; fd->scope = FILESTORE_SCOPE_TX; } } else { fd->direction = FILESTORE_DIR_DEFAULT; } if (args[1] != NULL) { SCLogDebug("second arg %s", args[1]); if (strcasecmp(args[1], "file") == 0) { fd->scope = FILESTORE_SCOPE_DEFAULT; } else if (strcasecmp(args[1], "tx") == 0) { fd->scope = FILESTORE_SCOPE_TX; } else if (strcasecmp(args[1], "ssn") == 0 || strcasecmp(args[1], "flow") == 0) { fd->scope = FILESTORE_SCOPE_SSN; } } else { if (fd->scope == 0) fd->scope = FILESTORE_SCOPE_DEFAULT; } sm->ctx = fd; } else { sm->ctx = NULL; } SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_FILEMATCH); if (s->alproto != ALPROTO_UNKNOWN && s->alproto != ALPROTO_HTTP) { SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains conflicting keywords."); goto error; } AppLayerHtpNeedFileInspection(); s->alproto = ALPROTO_HTTP; s->flags |= SIG_FLAG_FILESTORE; return 0; error: if (sm != NULL) SCFree(sm); return -1; }
int DetectXbitSetup (DetectEngineCtx *de_ctx, Signature *s, char *rawstr) { DetectXbitsData *cd = NULL; SigMatch *sm = NULL; uint8_t fb_cmd = 0; uint8_t hb_dir = 0; #define MAX_SUBSTRINGS 30 int ret = 0, res = 0; int ov[MAX_SUBSTRINGS]; char fb_cmd_str[16] = "", fb_name[256] = ""; char hb_dir_str[16] = ""; enum VarTypes var_type = VAR_TYPE_NOT_SET; int expire = 30; ret = pcre_exec(parse_regex, parse_regex_study, rawstr, strlen(rawstr), 0, 0, ov, MAX_SUBSTRINGS); if (ret != 2 && ret != 3 && ret != 4 && ret != 5) { SCLogError(SC_ERR_PCRE_MATCH, "\"%s\" is not a valid setting for xbits.", rawstr); return -1; } SCLogDebug("ret %d, %s", ret, rawstr); res = pcre_copy_substring((char *)rawstr, ov, MAX_SUBSTRINGS, 1, fb_cmd_str, sizeof(fb_cmd_str)); if (res < 0) { SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed"); return -1; } if (ret >= 3) { res = pcre_copy_substring((char *)rawstr, ov, MAX_SUBSTRINGS, 2, fb_name, sizeof(fb_name)); if (res < 0) { SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed"); goto error; } if (ret >= 4) { res = pcre_copy_substring((char *)rawstr, ov, MAX_SUBSTRINGS, 3, hb_dir_str, sizeof(hb_dir_str)); if (res < 0) { SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed"); goto error; } SCLogDebug("hb_dir_str %s", hb_dir_str); if (strlen(hb_dir_str) > 0) { if (strcmp(hb_dir_str, "ip_src") == 0) { hb_dir = DETECT_XBITS_TRACK_IPSRC; var_type = VAR_TYPE_HOST_BIT; } else if (strcmp(hb_dir_str, "ip_dst") == 0) { hb_dir = DETECT_XBITS_TRACK_IPDST; var_type = VAR_TYPE_HOST_BIT; } else if (strcmp(hb_dir_str, "ip_pair") == 0) { hb_dir = DETECT_XBITS_TRACK_IPPAIR; var_type = VAR_TYPE_IPPAIR_BIT; } else { // TODO goto error; } } if (ret >= 5) { char expire_str[16] = ""; res = pcre_copy_substring((char *)rawstr, ov, MAX_SUBSTRINGS, 4, expire_str, sizeof(expire_str)); if (res < 0) { SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed"); goto error; } SCLogDebug("expire_str %s", expire_str); expire = atoi(expire_str); SCLogDebug("expire %d", expire); } } } if (strcmp(fb_cmd_str,"noalert") == 0) { fb_cmd = DETECT_XBITS_CMD_NOALERT; } else if (strcmp(fb_cmd_str,"isset") == 0) { fb_cmd = DETECT_XBITS_CMD_ISSET; } else if (strcmp(fb_cmd_str,"isnotset") == 0) { fb_cmd = DETECT_XBITS_CMD_ISNOTSET; } else if (strcmp(fb_cmd_str,"set") == 0) { fb_cmd = DETECT_XBITS_CMD_SET; } else if (strcmp(fb_cmd_str,"unset") == 0) { fb_cmd = DETECT_XBITS_CMD_UNSET; } else if (strcmp(fb_cmd_str,"toggle") == 0) { fb_cmd = DETECT_XBITS_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_XBITS_CMD_NOALERT: if (strlen(fb_name) != 0) goto error; s->flags |= SIG_FLAG_NOALERT; return 0; case DETECT_XBITS_CMD_ISNOTSET: case DETECT_XBITS_CMD_ISSET: case DETECT_XBITS_CMD_SET: case DETECT_XBITS_CMD_UNSET: case DETECT_XBITS_CMD_TOGGLE: default: if (strlen(fb_name) == 0) goto error; break; } cd = SCMalloc(sizeof(DetectXbitsData)); if (unlikely(cd == NULL)) goto error; cd->idx = VariableNameGetIdx(de_ctx, fb_name, var_type); cd->cmd = fb_cmd; cd->tracker = hb_dir; cd->type = var_type; cd->expire = expire; 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_XBITS; sm->ctx = (void *)cd; switch (fb_cmd) { case DETECT_XBITS_CMD_NOALERT: /* nothing to do */ break; case DETECT_XBITS_CMD_ISNOTSET: case DETECT_XBITS_CMD_ISSET: /* checks, so packet list */ SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_MATCH); break; case DETECT_XBITS_CMD_SET: case DETECT_XBITS_CMD_UNSET: case DETECT_XBITS_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; }
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 DetectFlowvarSetup (DetectEngineCtx *de_ctx, Signature *s, char *rawstr) { DetectFlowvarData *fd = NULL; SigMatch *sm = NULL; char *varname = NULL, *varcontent = NULL; #define MAX_SUBSTRINGS 30 int ret = 0, res = 0; int ov[MAX_SUBSTRINGS]; const char *str_ptr; uint8_t *content = NULL; uint16_t contentlen = 0; uint32_t contentflags = 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 flowvar.", rawstr); return -1; } 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; res = DetectContentDataParse("flowvar", varcontent, &content, &contentlen, &contentflags); if (res == -1) goto error; fd = SCMalloc(sizeof(DetectFlowvarData)); if (unlikely(fd == NULL)) goto error; memset(fd, 0x00, sizeof(*fd)); fd->content = SCMalloc(contentlen); if (unlikely(fd->content == NULL)) goto error; memcpy(fd->content, content, contentlen); fd->content_len = contentlen; fd->flags = contentflags; fd->name = SCStrdup(varname); if (unlikely(fd->name == NULL)) goto error; fd->idx = VariableNameGetIdx(de_ctx, varname, VAR_TYPE_FLOW_VAR); /* Okay so far so good, lets get this into a SigMatch * and put it in the Signature. */ sm = SigMatchAlloc(); if (unlikely(sm == NULL)) goto error; sm->type = DETECT_FLOWVAR; sm->ctx = (SigMatchCtx *)fd; SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_MATCH); SCFree(content); return 0; error: if (fd != NULL) DetectFlowvarDataFree(fd); if (sm != NULL) SCFree(sm); if (content != NULL) SCFree(content); return -1; }
int DetectFlowbitSetup (DetectEngineCtx *de_ctx, Signature *s, char *rawstr) { DetectFlowbitsData *cd = NULL; SigMatch *sm = NULL; char *fb_cmd_str = NULL, *fb_name = NULL; uint8_t fb_cmd = 0; #define MAX_SUBSTRINGS 30 int ret = 0, res = 0; int ov[MAX_SUBSTRINGS]; 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 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; } fb_cmd_str = (char *)str_ptr; if (ret == 3) { 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"); goto error; } fb_name = (char *)str_ptr; } 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(fb_name != NULL) 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(fb_name == NULL) goto error; break; } cd = SCMalloc(sizeof(DetectFlowbitsData)); if (unlikely(cd == NULL)) goto error; cd->idx = VariableNameGetIdx(de_ctx, fb_name, DETECT_FLOWBITS); cd->cmd = fb_cmd; SCLogDebug("idx %" PRIu32 ", cmd %s, name %s", cd->idx, fb_cmd_str, fb_name ? fb_name : "(null)"); pcre_free_substring(fb_name); fb_name = NULL; pcre_free_substring(fb_cmd_str); fb_cmd_str = NULL; /* 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 = (void *)cd; switch (fb_cmd) { case DETECT_FLOWBITS_CMD_NOALERT: /* nothing to do */ break; 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 (fb_name != NULL) pcre_free_substring(fb_name); if (fb_cmd_str != NULL) pcre_free_substring(fb_cmd_str); if (cd != NULL) SCFree(cd); if (sm != NULL) SCFree(sm); return -1; }