Esempio n. 1
0
int DetectOffsetSetup (DetectEngineCtx *de_ctx, Signature *s, char *offsetstr)
{
    char *str = offsetstr;
    char dubbed = 0;
    SigMatch *pm = NULL;
    int ret = -1;

    /* strip "'s */
   if (offsetstr[0] == '\"' && offsetstr[strlen(offsetstr)-1] == '\"') {
        str = SCStrdup(offsetstr+1);
        if (unlikely(str == NULL))
            goto end;
        str[strlen(offsetstr) - 2] = '\0';
        dubbed = 1;
    }

    /* retrive the sm to apply the depth against */
    if (s->list != DETECT_SM_LIST_NOTSET) {
        pm = SigMatchGetLastSMFromLists(s, 2, DETECT_CONTENT, s->sm_lists_tail[s->list]);
    } else {
        pm =  SigMatchGetLastSMFromLists(s, 28,
                                         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_HRUDMATCH],
                                         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_HSCDMATCH],
                                         DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH],
                                         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]);
    }
    if (pm == NULL) {
        SCLogError(SC_ERR_OFFSET_MISSING_CONTENT, "offset needs "
                   "preceding content, uricontent option, http_client_body, "
                   "http_server_body, http_header option, http_raw_header option, "
                   "http_method option, http_cookie, http_raw_uri, "
                   "http_stat_msg, http_stat_code, http_user_agent or "
                   "file_data/dce_stub_data sticky buffer options");
        goto end;
    }


    /* verify other conditions */
    DetectContentData *cd = (DetectContentData *)pm->ctx;

    if (cd->flags & DETECT_CONTENT_OFFSET) {
        SCLogError(SC_ERR_INVALID_SIGNATURE, "can't use multiple offsets for the same content. ");
        goto end;
    }
    if ((cd->flags & DETECT_CONTENT_WITHIN) || (cd->flags & DETECT_CONTENT_DISTANCE)) {
        SCLogError(SC_ERR_INVALID_SIGNATURE, "can't use a relative "
                   "keyword like within/distance with a absolute "
                   "relative keyword like depth/offset for the same "
                   "content." );
        goto end;
    }
    if (cd->flags & DETECT_CONTENT_NEGATED && cd->flags & DETECT_CONTENT_FAST_PATTERN) {
        SCLogError(SC_ERR_INVALID_SIGNATURE, "can't have a relative "
                   "negated keyword set along with a fast_pattern");
        goto end;
    }
    if (cd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) {
        SCLogError(SC_ERR_INVALID_SIGNATURE, "can't have a relative "
                   "keyword set along with a fast_pattern:only;");
        goto end;
    }
    if (str[0] != '-' && isalpha((unsigned char)str[0])) {
        SigMatch *bed_sm =
            DetectByteExtractRetrieveSMVar(str, s);
        if (bed_sm == NULL) {
            SCLogError(SC_ERR_INVALID_SIGNATURE, "unknown byte_extract var "
                       "seen in offset - %s\n", str);
            goto end;
        }
        cd->offset = ((DetectByteExtractData *)bed_sm->ctx)->local_id;
        cd->flags |= DETECT_CONTENT_OFFSET_BE;
    } else {
        cd->offset = (uint32_t)atoi(str);
        if (cd->depth != 0) {
            if (cd->depth < cd->content_len) {
                SCLogDebug("depth increased to %"PRIu32" to match pattern len",
                           cd->content_len);
                cd->depth = cd->content_len;
            }
            /* Updating the depth as is relative to the offset */
            cd->depth += cd->offset;
        }
    }
    cd->flags |= DETECT_CONTENT_OFFSET;

    ret = 0;
 end:
    if (dubbed)
        SCFree(str);
    return ret;
}
Esempio n. 2
0
/**
 * \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;
}
Esempio n. 3
0
/** \brief Setup within pattern (content/uricontent) modifier.
 *
 *  \todo apply to uricontent
 *
 *  \retval 0 ok
 *  \retval -1 error, sig needs to be invalidated
 */
static int DetectWithinSetup (DetectEngineCtx *de_ctx, Signature *s, char *withinstr)
{
    char *str = withinstr;
    char dubbed = 0;
    SigMatch *pm = NULL;

    /* strip "'s */
    if (withinstr[0] == '\"' && withinstr[strlen(withinstr)-1] == '\"') {
        str = SCStrdup(withinstr+1);
        if (str == NULL)
            goto error;
        str[strlen(withinstr)-2] = '\0';
        dubbed = 1;
    }

    /* if we still haven't found that the sig is related to DCERPC,
     * it's a direct entry into Signature->[DETECT_SM_LIST_PMATCH] */
    if (s->alproto == ALPROTO_DCERPC) {
        SigMatch *dcem = NULL;
        SigMatch *dm = NULL;
        SigMatch *pm1 = NULL;

        SigMatch *pm1_ots = NULL;
        SigMatch *pm2_ots = NULL;

        dcem = SigMatchGetLastSMFromLists(s, 6,
                DETECT_DCE_IFACE, s->sm_lists_tail[DETECT_SM_LIST_AMATCH],
                DETECT_DCE_OPNUM, s->sm_lists_tail[DETECT_SM_LIST_AMATCH],
                DETECT_DCE_STUB_DATA, s->sm_lists_tail[DETECT_SM_LIST_AMATCH]);

        pm1_ots = 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]);
        if (pm1_ots != NULL && pm1_ots->prev != NULL) {
            pm2_ots = SigMatchGetLastSMFromLists(s, 6,
                    DETECT_CONTENT, pm1_ots->prev,
                    DETECT_PCRE, pm1_ots->prev,
                    DETECT_BYTEJUMP, pm1_ots->prev);
        }

        dm = SigMatchGetLastSMFromLists(s, 2, DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_DMATCH]);
        pm1 = SigMatchGetLastSMFromLists(s, 2, DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH]);

        if (dm == NULL && pm1 == NULL) {
            SCLogError(SC_ERR_INVALID_SIGNATURE, "\"within\" requires a "
                    "preceding content keyword");
            goto error;
        }

        if (dm == NULL) {
            if (pm2_ots == NULL) {
                if (pm1->idx > dcem->idx) {
                    /* transfer pm1 to dmatch list and within is against this */
                    SigMatchTransferSigMatchAcrossLists(pm1,
                            &s->sm_lists[DETECT_SM_LIST_PMATCH],
                            &s->sm_lists_tail[DETECT_SM_LIST_PMATCH],
                            &s->sm_lists[DETECT_SM_LIST_DMATCH],
                            &s->sm_lists_tail[DETECT_SM_LIST_DMATCH]);
                    pm = pm1;
                } else {
                    /* within is against pm1 and we continue this way */
                    pm = pm1;
                }
            } else if (pm2_ots->idx > dcem->idx) {
                /* within is against pm1, pm = pm1; */
                pm = pm1;
            } else if (pm1->idx > dcem->idx) {
                /* transfer pm1 to dmatch list and within is against this */
                SigMatchTransferSigMatchAcrossLists(pm1,
                        &s->sm_lists[DETECT_SM_LIST_PMATCH],
                        &s->sm_lists_tail[DETECT_SM_LIST_PMATCH],
                        &s->sm_lists[DETECT_SM_LIST_DMATCH],
                                                    &s->sm_lists_tail[DETECT_SM_LIST_DMATCH]);
                pm = pm1;
            } else {
                /* within is against pm1 and we continue this way */
                pm = pm1;
            }
        } else {
            if (pm1 == NULL) {
                /* within is against dm and continue this way */
                pm = dm;
            } else if (dm->idx > pm1->idx) {
                /* within is against dm */
                pm = dm;
            } else if (pm2_ots == NULL || pm2_ots->idx < dcem->idx) {
                /* trasnfer pm1 to dmatch list and pm = pm1 */
                SigMatchTransferSigMatchAcrossLists(pm1,
                        &s->sm_lists[DETECT_SM_LIST_PMATCH],
                        &s->sm_lists_tail[DETECT_SM_LIST_PMATCH],
                        &s->sm_lists[DETECT_SM_LIST_DMATCH],
                        &s->sm_lists_tail[DETECT_SM_LIST_DMATCH]);
                pm = pm1;
            } else {
                /* within is against pm1, pm = pm1 */
                pm = pm1;
            }
        }
    } else {
        pm = SigMatchGetLastSMFromLists(s, 24,
                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_HSMDMATCH],
                DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH],
                DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH],
                DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HUADMATCH]);
        if (pm == NULL) {
            SCLogError(SC_ERR_WITHIN_MISSING_CONTENT, "\"within\" requires "
                       "preceeding content, uricontent, http_client_body, "
                       "http_server_body, http_header, http_raw_header, "
                       "http_method, http_cookie, http_raw_uri, "
                       "http_stat_msg, http_stat_code or http_user_agent "
                       "option");
            if (dubbed)
                SCFree(str);
            return -1;
        }
    }

    DetectContentData *cd = NULL;
    DetectPcreData *pe = NULL;

    switch (pm->type) {
        case DETECT_CONTENT:
            cd = (DetectContentData *)pm->ctx;
            if (cd == NULL) {
                SCLogError(SC_ERR_INVALID_SIGNATURE, "content error");
                goto error;
            }

            if (cd->flags & DETECT_CONTENT_NEGATED) {
                if (cd->flags & DETECT_CONTENT_FAST_PATTERN) {
                    SCLogError(SC_ERR_INVALID_SIGNATURE, "can't have a relative "
                               "negated keyword set along with a fast_pattern");
                    goto error;
                }
            } else {
                if (cd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) {
                    SCLogError(SC_ERR_INVALID_SIGNATURE, "can't have a relative "
                               "keyword set along with a fast_pattern:only");
                    goto error;
                }
            }

            if (cd->flags & DETECT_CONTENT_DEPTH || cd->flags & DETECT_CONTENT_OFFSET) {
                SCLogError(SC_ERR_INVALID_SIGNATURE, "can't use a relative keyword "
                               "with a non-relative keyword for the same content" );
                goto error;
            }

            if (str[0] != '-' && isalpha(str[0])) {
                SigMatch *bed_sm =
                    DetectByteExtractRetrieveSMVar(str, s,
                                                   SigMatchListSMBelongsTo(s, pm));
                if (bed_sm == NULL) {
                    SCLogError(SC_ERR_INVALID_SIGNATURE, "unknown byte_extract var "
                               "seen in within - %s\n", str);
                    goto error;
                }
                cd->within = ((DetectByteExtractData *)bed_sm->ctx)->local_id;
                cd->flags |= DETECT_CONTENT_WITHIN_BE;
            } else {
                cd->within = strtol(str, NULL, 10);
                if (cd->within < (int32_t)cd->content_len) {
                    SCLogError(SC_ERR_WITHIN_INVALID, "within argument \"%"PRIi32"\" is "
                               "less than the content length \"%"PRIu32"\" which is invalid, since "
                               "this will never match.  Invalidating signature", cd->within,
                               cd->content_len);
                    goto error;
                }
            }

            cd->flags |= DETECT_CONTENT_WITHIN;

            pm = SigMatchGetLastSMFromLists(s, 6,
                                            DETECT_CONTENT, pm->prev,
                                            DETECT_PCRE, pm->prev,
                                            DETECT_BYTEJUMP, pm->prev);
            if (pm == NULL) {
                if (s->alproto == ALPROTO_DCERPC) {
                    SCLogDebug("content relative without a previous content based "
                               "keyword. Holds good only in the case of DCERPC "
                               "alproto like now.");
                } else {
                    //SCLogError(SC_ERR_INVALID_SIGNATURE, "No related "
                    //           "previous-previous content or pcre keyword");
                    //goto error;
                    ;
                }
            } else {
                switch (pm->type) {
                    case DETECT_CONTENT:
                        /* Set the relative next flag on the prev sigmatch */
                        cd = (DetectContentData *)pm->ctx;
                        if (cd == NULL) {
                            SCLogError(SC_ERR_INVALID_SIGNATURE, "content error");
                            goto error;
                        }
                        cd->flags |= DETECT_CONTENT_RELATIVE_NEXT;

                        if (cd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) {
                            SCLogError(SC_ERR_INVALID_SIGNATURE, "previous keyword "
                                       "has a fast_pattern:only; set. Can't "
                                       "have relative keywords around a fast_pattern "
                                       "only content");
                            goto error;
                        }

                        break;

                    case DETECT_PCRE:
                        pe = (DetectPcreData *) pm->ctx;
                        if (pe == NULL) {
                            SCLogError(SC_ERR_INVALID_SIGNATURE, "pcre error");
                            goto error;
                        }
                        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, "unsupported type %d", pm->type);
                        break;
                }
            }

            break;

        default:
            SCLogError(SC_ERR_WITHIN_MISSING_CONTENT, "within needs two "
                       "preceeding content or uricontent options");
            goto error;
    }

    if (dubbed)
        SCFree(str);
    return 0;

error:
    if (dubbed)
        SCFree(str);
    return -1;
}
Esempio n. 4
0
int DetectOffsetSetup (DetectEngineCtx *de_ctx, Signature *s, char *offsetstr)
{
    char *str = offsetstr;
    char dubbed = 0;
    SigMatch *pm = NULL;

    /* strip "'s */
    if (offsetstr[0] == '\"' && offsetstr[strlen(offsetstr)-1] == '\"') {
        str = SCStrdup(offsetstr+1);
        if (unlikely(str == NULL))
            goto error;
        str[strlen(offsetstr)-2] = '\0';
        dubbed = 1;
    }

    switch (s->alproto) {
        case ALPROTO_DCERPC:
            /* add to the latest "content" keyword from either dmatch or pmatch */
            pm =  SigMatchGetLastSMFromLists(s, 4,
                    DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_DMATCH],
                    DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH]);
            if (pm == NULL) {
                SCLogError(SC_ERR_OFFSET_MISSING_CONTENT, "offset needs "
                           "preceding content option for dcerpc sig");
                if (dubbed)
                    SCFree(str);
                return -1;
            }

            break;

        default:
            pm = SigMatchGetLastSMFromLists(s, 24,
                    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_HSMDMATCH],
                    DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH],
                    DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH],
                    DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HUADMATCH]);
            if (pm == NULL) {
                SCLogError(SC_ERR_OFFSET_MISSING_CONTENT, "offset needs "
                           "preceding content or uricontent option, http_client_body, "
                           "http_header, http_raw_header, http_method, "
                           "http_cookie, http_raw_uri, http_stat_msg, "
                           "http_stat_code or http_user_agent option");
                if (dubbed)
                    SCFree(str);
                return -1;
            }

            break;
    }

    /* we can remove this switch now with the unified structure */
    DetectContentData *cd = NULL;
    switch (pm->type) {
        case DETECT_CONTENT:
            cd = (DetectContentData *)pm->ctx;
            if (cd == NULL) {
                SCLogError(SC_ERR_INVALID_ARGUMENT, "invalid argument");
                if (dubbed)
                    SCFree(str);
                return -1;
            }

            if (cd->flags & DETECT_CONTENT_NEGATED) {
                if (cd->flags & DETECT_CONTENT_FAST_PATTERN) {
                    SCLogError(SC_ERR_INVALID_SIGNATURE, "can't have a relative "
                               "negated keyword set along with a fast_pattern");
                    goto error;
                }
            } else {
                if (cd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) {
                    SCLogError(SC_ERR_INVALID_SIGNATURE, "can't have a relative "
                               "keyword set along with a fast_pattern:only;");
                    goto error;
                }
            }

            if ((cd->flags & DETECT_CONTENT_WITHIN) || (cd->flags & DETECT_CONTENT_DISTANCE)) {
                SCLogError(SC_ERR_INVALID_SIGNATURE, "can't use a relative keyword "
                               "with a non-relative keyword for the same content." );
                goto error;
            }

            if (cd->flags & DETECT_CONTENT_OFFSET) {
                SCLogError(SC_ERR_INVALID_SIGNATURE, "can't use multiple offsets for the same content. ");
                goto error;
            }

            if (str[0] != '-' && isalpha((unsigned char)str[0])) {
                SigMatch *bed_sm =
                    DetectByteExtractRetrieveSMVar(str, s,
                                                   SigMatchListSMBelongsTo(s, pm));
                if (bed_sm == NULL) {
                    SCLogError(SC_ERR_INVALID_SIGNATURE, "unknown byte_extract var "
                               "seen in offset - %s\n", str);
                    goto error;
                }
                cd->offset = ((DetectByteExtractData *)bed_sm->ctx)->local_id;
                cd->flags |= DETECT_CONTENT_OFFSET_BE;
            } else {
                cd->offset = (uint32_t)atoi(str);
                if (cd->depth != 0) {
                    if (cd->depth < cd->content_len) {
                        SCLogDebug("depth increased to %"PRIu32" to match pattern len",
                                   cd->content_len);
                        cd->depth = cd->content_len;
                    }
                    /* Updating the depth as is relative to the offset */
                    cd->depth += cd->offset;
                }
            }

            cd->flags |= DETECT_CONTENT_OFFSET;

            break;

        default:
            SCLogError(SC_ERR_OFFSET_MISSING_CONTENT, "offset needs a preceding"
                    " content keyword");
            goto error;
    }

    if (dubbed)
        SCFree(str);
    return 0;

error:
    if (dubbed)
        SCFree(str);
    return -1;
}
Esempio n. 5
0
static int DetectDepthSetup (DetectEngineCtx *de_ctx, Signature *s, char *depthstr)
{
    char *str = depthstr;
    char dubbed = 0;
    SigMatch *pm = NULL;
    DetectContentData *cd = NULL;

    /* strip "'s */
    if (depthstr[0] == '\"' && depthstr[strlen(depthstr) - 1] == '\"') {
        str = SCStrdup(depthstr + 1);
        if (str == NULL)
            goto error;
        str[strlen(depthstr) - 2] = '\0';
        dubbed = 1;
    }

    switch (s->alproto) {
        case ALPROTO_DCERPC:
            /* add to the latest content keyword from either dmatch or pmatch */
            pm =  SigMatchGetLastSMFromLists(s, 4,
                    DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_DMATCH],
                    DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH]);
            if (pm == NULL) {
                SCLogError(SC_ERR_DEPTH_MISSING_CONTENT, "depth needs "
                           "preceding content option for dcerpc sig");
                if (dubbed)
                    SCFree(str);
                return -1;
            }

            break;

        default:
            pm =  SigMatchGetLastSMFromLists(s, 24,
                    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_HRUDMATCH],
                    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_HSCDMATCH],
                    DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH],
                    DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HUADMATCH]);
            if (pm == NULL) {
                SCLogError(SC_ERR_DEPTH_MISSING_CONTENT, "depth needs "
                        "preceding content, uricontent option, http_client_body, "
                        "http_server_body, http_header option, http_raw_header option, "
                        "http_method option, http_cookie, http_raw_uri, "
                        "http_stat_msg, http_stat_code or http_user_agent option");
                if (dubbed)
                    SCFree(str);
                return -1;
            }

            break;
    }

    /* i swear we will clean this up :).  Use a single version for all.  Using
     * separate versions for all now, to avoiding breaking any code */
    switch (pm->type) {
        case DETECT_CONTENT:
            cd = (DetectContentData *)pm->ctx;
            if (cd == NULL) {
                SCLogError(SC_ERR_INVALID_ARGUMENT, "invalid argument");
                if (dubbed) SCFree(str);
                return -1;
            }

            if (cd->flags & DETECT_CONTENT_NEGATED) {
                if (cd->flags & DETECT_CONTENT_FAST_PATTERN) {
                    SCLogError(SC_ERR_INVALID_SIGNATURE, "can't have a relative "
                               "negated keyword set along with a fast_pattern");
                    goto error;
                }
            } else {
                if (cd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) {
                    SCLogError(SC_ERR_INVALID_SIGNATURE, "can't have a relative "
                               "keyword set along with a fast_pattern:only;");
                    goto error;
                }
            }

            if (cd->flags & DETECT_CONTENT_WITHIN || cd->flags & DETECT_CONTENT_DISTANCE) {
                SCLogError(SC_ERR_INVALID_SIGNATURE, "can't use a relative keyword "
                               "with a non-relative keyword for the same content." );
                goto error;
            }

            if (cd->flags & DETECT_CONTENT_DEPTH) {
                SCLogError(SC_ERR_INVALID_SIGNATURE, "can't use multiple depths for the same content.");
                goto error;
            }

            if (str[0] != '-' && isalpha(str[0])) {
                SigMatch *bed_sm =
                    DetectByteExtractRetrieveSMVar(str, s,
                                                   SigMatchListSMBelongsTo(s, pm));
                if (bed_sm == NULL) {
                    SCLogError(SC_ERR_INVALID_SIGNATURE, "unknown byte_extract var "
                               "seen in depth - %s\n", str);
                    goto error;
                }
                cd->depth = ((DetectByteExtractData *)bed_sm->ctx)->local_id;
                cd->flags |= DETECT_CONTENT_DEPTH_BE;
            } else {
                cd->depth = (uint32_t)atoi(str);
                if (cd->depth < cd->content_len) {
                    uint32_t content_len = cd->content_len;
                    SCLogError(SC_ERR_INVALID_SIGNATURE, "depth - %"PRIu16
                               " smaller than content length - %"PRIu32,
                               cd->depth, content_len);
                    goto error;
                }
                /* Now update the real limit, as depth is relative to the offset */
                cd->depth += cd->offset;
            }

            cd->flags |= DETECT_CONTENT_DEPTH;

            break;

        default:
            SCLogError(SC_ERR_DEPTH_MISSING_CONTENT, "depth needs a preceding "
                    "content (or uricontent) option");
            goto error;
    }

    if (dubbed)
        SCFree(str);
    return 0;

error:
    if (dubbed)
        SCFree(str);
    return -1;
}
Esempio n. 6
0
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;
}
Esempio n. 7
0
static int DetectDistanceSetup (DetectEngineCtx *de_ctx, Signature *s,
        char *distancestr)
{
    char *str = distancestr;
    char dubbed = 0;
    SigMatch *pm = NULL;
    int ret = -1;

    /* strip "'s */
    if (distancestr[0] == '\"' && distancestr[strlen(distancestr) - 1] == '\"') {
        str = SCStrdup(distancestr + 1);
        if (unlikely(str == NULL))
            goto end;
        str[strlen(distancestr) - 2] = '\0';
        dubbed = 1;
    }

    /* retrive the sm to apply the depth against */
    if (s->list != DETECT_SM_LIST_NOTSET) {
        pm = SigMatchGetLastSMFromLists(s, 2, DETECT_CONTENT, s->sm_lists_tail[s->list]);
    } else {
        pm =  SigMatchGetLastSMFromLists(s, 28,
                                         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_HRUDMATCH],
                                         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_HSCDMATCH],
                                         DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH],
                                         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]);
    }
    if (pm == NULL) {
        SCLogError(SC_ERR_OFFSET_MISSING_CONTENT, "distance needs "
                   "preceding content, uricontent option, http_client_body, "
                   "http_server_body, http_header option, http_raw_header option, "
                   "http_method option, http_cookie, http_raw_uri, "
                   "http_stat_msg, http_stat_code, http_user_agent or "
                   "file_data/dce_stub_data sticky buffer option");
        goto end;
    }

    /* verify other conditions */
    DetectContentData *cd = (DetectContentData *)pm->ctx;
    if (cd->flags & DETECT_CONTENT_DISTANCE) {
        SCLogError(SC_ERR_INVALID_SIGNATURE, "can't use multiple distances for the same content.");
        goto end;
    }
    if ((cd->flags & DETECT_CONTENT_DEPTH) || (cd->flags & DETECT_CONTENT_OFFSET)) {
        SCLogError(SC_ERR_INVALID_SIGNATURE, "can't use a relative "
                   "keyword like within/distance with a absolute "
                   "relative keyword like depth/offset for the same "
                   "content." );
        goto end;
    }
    if (cd->flags & DETECT_CONTENT_NEGATED && cd->flags & DETECT_CONTENT_FAST_PATTERN) {
        SCLogError(SC_ERR_INVALID_SIGNATURE, "can't have a relative "
                   "negated keyword set along with a fast_pattern");
        goto end;
    }
    if (cd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) {
        SCLogError(SC_ERR_INVALID_SIGNATURE, "can't have a relative "
                   "keyword set along with a fast_pattern:only;");
        goto end;
    }
    if (str[0] != '-' && isalpha((unsigned char)str[0])) {
        SigMatch *bed_sm = DetectByteExtractRetrieveSMVar(str, s);
        if (bed_sm == NULL) {
            SCLogError(SC_ERR_INVALID_SIGNATURE, "unknown byte_extract var "
                       "seen in distance - %s\n", str);
            goto end;
        }
        cd->distance = ((DetectByteExtractData *)bed_sm->ctx)->local_id;
        cd->flags |= DETECT_CONTENT_DISTANCE_BE;
    } else {
        cd->distance = strtol(str, NULL, 10);
    }
    cd->flags |= DETECT_CONTENT_DISTANCE;

    SigMatch *prev_pm = SigMatchGetLastSMFromLists(s, 4,
                                                   DETECT_CONTENT, pm->prev,
                                                   DETECT_PCRE, pm->prev);
    if (prev_pm == NULL) {
        ret = 0;
        goto end;
    }
    if (prev_pm->type == DETECT_CONTENT) {
        DetectContentData *cd = (DetectContentData *)prev_pm->ctx;
        if (cd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) {
            SCLogError(SC_ERR_INVALID_SIGNATURE, "previous keyword "
                       "has a fast_pattern:only; set. Can't "
                       "have relative keywords around a fast_pattern "
                       "only content");
            goto end;
        }
        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;
    }

    ret = 0;
 end:
    if (dubbed)
        SCFree(str);
    return ret;
}
Esempio n. 8
0
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;
}