Exemplo n.º 1
0
/**
 * \brief This function is used to parse fileet
 *
 * \param str Pointer to the fileext value string
 *
 * \retval pointer to DetectFileextData on success
 * \retval NULL on failure
 */
static DetectFileextData *DetectFileextParse (const char *str, bool negate)
{
    DetectFileextData *fileext = NULL;

    /* We have a correct filename option */
    fileext = SCMalloc(sizeof(DetectFileextData));
    if (unlikely(fileext == NULL))
        goto error;

    memset(fileext, 0x00, sizeof(DetectFileextData));

    if (DetectContentDataParse("fileext", str, &fileext->ext, &fileext->len) == -1) {
        goto error;
    }
    uint16_t u;
    for (u = 0; u < fileext->len; u++)
        fileext->ext[u] = tolower(fileext->ext[u]);

    if (negate) {
        fileext->flags |= DETECT_CONTENT_NEGATED;
    }

    SCLogDebug("flags %02X", fileext->flags);
    if (fileext->flags & DETECT_CONTENT_NEGATED) {
        SCLogDebug("negated fileext");
    }

#ifdef DEBUG
    if (SCLogDebugEnabled()) {
        char *ext = SCMalloc(fileext->len + 1);
        if (ext != NULL) {
            memcpy(ext, fileext->ext, fileext->len);
            ext[fileext->len] = '\0';
            SCLogDebug("will look for fileext %s", ext);
        }
    }
#endif

    return fileext;

error:
    if (fileext != NULL)
        DetectFileextFree(fileext);
    return NULL;

}
Exemplo n.º 2
0
/**
 * \brief Parse the filename keyword
 *
 * \param idstr Pointer to the user provided option
 *
 * \retval filename pointer to DetectFilenameData on success
 * \retval NULL on failure
 */
static DetectFilenameData *DetectFilenameParse (char *str)
{
    DetectFilenameData *filename = NULL;

    /* We have a correct filename option */
    filename = SCMalloc(sizeof(DetectFilenameData));
    if (unlikely(filename == NULL))
        goto error;

    memset(filename, 0x00, sizeof(DetectFilenameData));

    if (DetectContentDataParse ("filename", str, &filename->name, &filename->len, &filename->flags) == -1) {
        goto error;
    }

    filename->bm_ctx = BoyerMooreCtxInit(filename->name, filename->len);
    if (filename->bm_ctx == NULL) {
        goto error;
    }

    SCLogDebug("flags %02X", filename->flags);
    if (filename->flags & DETECT_CONTENT_NEGATED) {
        SCLogDebug("negated filename");
    }

    BoyerMooreCtxToNocase(filename->bm_ctx, filename->name, filename->len);
#ifdef DEBUG
    if (SCLogDebugEnabled()) {
        char *name = SCMalloc(filename->len + 1);
        if (name != NULL) {
            memcpy(name, filename->name, filename->len);
            name[filename->len] = '\0';
            SCLogDebug("will look for filename %s", name);
        }
    }
#endif

    return filename;

error:
    if (filename != NULL)
        DetectFilenameFree(filename);
    return NULL;
}
Exemplo n.º 3
0
int DetectReplaceSetup(DetectEngineCtx *de_ctx, Signature *s, char *replacestr)
{
    uint8_t *content = NULL;
    uint16_t len = 0;
    uint32_t flags = 0;
    SigMatch *pm = NULL;
    DetectContentData *ud = NULL;

    int ret = DetectContentDataParse("replace", replacestr, &content, &len, &flags);
    if (ret == -1)
        goto error;

    if (flags & DETECT_CONTENT_NEGATED) {
        SCLogError(SC_ERR_INVALID_VALUE, "Can't negate replacement string: %s",
                   replacestr);
        goto error;
    }

    switch (run_mode) {
        case RUNMODE_NFQ:
        case RUNMODE_IPFW:
            break;
        default:
            SCLogWarning(SC_ERR_RUNMODE,
                         "Can't use 'replace' keyword in non IPS mode: %s",
                         s->sig_str);
            /* this is a success, having the alert is interesting */
            return 0;
    }

    /* add to the latest "content" keyword from either dmatch or pmatch */
    pm =  SigMatchGetLastSMFromLists(s, 2,
            DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH]);
    if (pm == NULL) {
        SCLogError(SC_ERR_WITHIN_MISSING_CONTENT, "replace needs"
                "preceding content option for raw sig");
        SCFree(content);
        return -1;
    }

    /* we can remove this switch now with the unified structure */
    ud = (DetectContentData *)pm->ctx;
    if (ud == NULL) {
        SCLogError(SC_ERR_INVALID_ARGUMENT, "invalid argument");
        SCFree(content);
        return -1;
    }
    if (ud->flags & DETECT_CONTENT_NEGATED) {
        SCLogError(SC_ERR_INVALID_SIGNATURE, "can't have a relative "
                "negated keyword set along with a replacement");
        goto error;
    }
    if (ud->content_len != len) {
        SCLogError(SC_ERR_INVALID_SIGNATURE, "can't have a content "
                "length different from replace length");
        goto error;
    }

    ud->replace = SCMalloc(len);
    if (ud->replace == NULL) {
        goto error;
    }
    memcpy(ud->replace, content, len);
    ud->replace_len = len;
    ud->flags |= DETECT_CONTENT_REPLACE;
    /* want packet matching only won't be able to replace data with
     * a flow.
     */
    s->flags |= SIG_FLAG_REQUIRE_PACKET;
    SCFree(content);

    return 0;

error:
    SCFree(content);
    return -1;
}
Exemplo n.º 4
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;
}
Exemplo n.º 5
0
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;
}