Beispiel #1
0
END_TEST

START_TEST(test_regexextraction)
{

    int i;
    /*
     * Please note that all strings are \ escaped
     */
    const char *tests[][15] = {
        { "123(\\w+\\s+)abc", "123sdf    abc", "sdf    ", NULL},
        { "123(\\w+\\s+)abc", "abc123sdf    abc", "sdf    ", NULL},
        { "123 (\\d+.\\d.\\d.\\d\\d*\\d*)", "123 45.6.5.567", "45.6.5.567", NULL},
        { "from (\\S*\\d+.\\d+.\\d+.\\d\\d*\\d*)", "sshd[21576]: Illegal user web14 from ::ffff:212.227.60.55", "::ffff:212.227.60.55", NULL},
        { "^sshd[\\d+]: Accepted \\S+ for (\\S+) from (\\S+) port ", "sshd[21405]: Accepted password for root from 192.1.1.1 port 6023", "root", "192.1.1.1", NULL},
        { ": \\((\\S+)@(\\S+)\\) [", "pure-ftpd: ([email protected]) [INFO] New connection from enigma.lab.ossec.net", "?", "enigma.lab.ossec.net", NULL},
        {NULL,NULL,NULL}
    };

    for(i=0; tests[i][0] != NULL; i++) {
        OSRegex reg;
        ck_assert_int_eq(OSRegex_Compile(tests[i][0], &reg, OS_RETURN_SUBSTRING), 1);
        ck_assert_ptr_ne(OSRegex_Execute(tests[i][1], &reg), NULL);



        char **result = reg.sub_strings;

        int j;
        int k;
        for(j = 2, k = 0; tests[i][j] != NULL; j++, k++)
        {
            ck_assert_ptr_ne(result[k], NULL);
            ck_assert_str_eq(result[k], tests[i][j]);
        }
        ck_assert_ptr_eq(result[k], NULL);

        OSRegex_FreePattern(&reg);
    }
}
Beispiel #2
0
/* CheckIfRuleMatch v0.1
 * Will check if the currently_rule matches the event information
 */
RuleInfo *OS_CheckIfRuleMatch(Eventinfo *lf, RuleNode *curr_node)
{
    /* We check for:
     * decoded_as,
     * fts,
     * word match (fast regex),
     * regex,
     * url,
     * id,
     * user,
     * maxsize,
     * protocol,
     * srcip,
     * dstip,
     * srcport,
     * dstport,
     * time,
     * weekday,
     * status,
     */
    RuleInfo *currently_rule = curr_node->ruleinfo;


    /* Can't be null */
    if(!currently_rule)
    {
        merror("%s: Inconsistent state. currently rule NULL", ARGV0);
        return(NULL);
    }


    #ifdef TESTRULE
    if(full_output && !alert_only)
    print_out("    Trying rule: %d - %s", currently_rule->sigid,
                                          currently_rule->comment);
    #endif


    /* Checking if any decoder pre-matched here */
    if(currently_rule->decoded_as &&
       currently_rule->decoded_as != lf->decoder_info->id)
    {
        return(NULL);
    }


    /* Checking program name */
    if(currently_rule->program_name)
    {
        if(!lf->program_name)
            return(NULL);

        if(!OSMatch_Execute(lf->program_name,
                            lf->p_name_size,
                            currently_rule->program_name))
                        return(NULL);
    }


    /* Checking for the id */
    if(currently_rule->id)
    {
        if(!lf->id)
        {
            return(NULL);
        }

        if(!OSMatch_Execute(lf->id,
                            strlen(lf->id),
                            currently_rule->id))
            return(NULL);
        #ifdef CDBLOOKUP

        #endif
    }


    /* Checking if any word to match exists */
    if(currently_rule->match)
    {
        if(!OSMatch_Execute(lf->log, lf->size, currently_rule->match))
            return(NULL);
    }


    /* Checking if exist any regex for this rule */
    if(currently_rule->regex)
    {
        if(!OSRegex_Execute(lf->log, currently_rule->regex))
            return(NULL);
    }


    /* Checking for actions */
    if(currently_rule->action)
    {
        if(!lf->action)
            return(NULL);

        if(strcmp(currently_rule->action,lf->action) != 0)
            return(NULL);
    }


    /* Checking for the url */
    if(currently_rule->url)
    {
        if(!lf->url)
        {
            return(NULL);
        }

        if(!OSMatch_Execute(lf->url, strlen(lf->url), currently_rule->url))
        {
            return(NULL);
        }
        #ifdef CDBLOOKUP

        #endif
    }



    /* Getting tcp/ip packet information */
    if(currently_rule->alert_opts & DO_PACKETINFO)
    {
        /* Checking for the srcip */
        if(currently_rule->srcip)
        {
            if(!lf->srcip)
            {
                return(NULL);
            }

            if(!OS_IPFoundList(lf->srcip, currently_rule->srcip))
            {
                return(NULL);
            }
            #ifdef CDBLOOKUP

            #endif
        }

        /* Checking for the dstip */
        if(currently_rule->dstip)
        {
            if(!lf->dstip)
            {
                return(NULL);
            }

            if(!OS_IPFoundList(lf->dstip, currently_rule->dstip))
            {
                return(NULL);
            }
            #ifdef CDBLOOKUP

            #endif
        }

        if(currently_rule->srcport)
        {
            if(!lf->srcport)
            {
                return(NULL);
            }

            if(!OSMatch_Execute(lf->srcport,
                                strlen(lf->srcport),
                                currently_rule->srcport))
            {
                return(NULL);
            }
            #ifdef CDBLOOKUP

            #endif
        }
        if(currently_rule->dstport)
        {
            if(!lf->dstport)
            {
                return(NULL);
            }

            if(!OSMatch_Execute(lf->dstport,
                                strlen(lf->dstport),
                                currently_rule->dstport))
            {
                return(NULL);
            }
            #ifdef CDBLOOKUP

            #endif
        }
    } /* END PACKET_INFO */


    /* Extra information from event */
    if(currently_rule->alert_opts & DO_EXTRAINFO)
    {
        /* Checking compiled rule. */
        if(currently_rule->compiled_rule)
        {
            if(!currently_rule->compiled_rule(lf))
            {
                return(NULL);
            }
        }


        /* Checking if exist any user to match */
        if(currently_rule->user)
        {
            if(lf->dstuser)
            {
                if(!OSMatch_Execute(lf->dstuser,
                            strlen(lf->dstuser),
                            currently_rule->user))
                    return(NULL);
            }
            else if(lf->srcuser)
            {
                if(!OSMatch_Execute(lf->srcuser,
                            strlen(lf->srcuser),
                            currently_rule->user))
                    return(NULL);
            }
            else
            #ifdef CDBLOOKUP

            #endif
            {
                /* no user set */
                return(NULL);
            }
        }


        /* Checking if any rule related to the size exist */
        if(currently_rule->maxsize)
        {
            if(lf->size < currently_rule->maxsize)
                return(NULL);
        }


        /* Checking if we are in the right time */
        if(currently_rule->day_time)
        {
            if(!OS_IsonTime(lf->hour, currently_rule->day_time))
            {
                return(NULL);
            }
        }


        /* Checking week day */
        if(currently_rule->week_day)
        {
            if(!OS_IsonDay(__crt_wday, currently_rule->week_day))
            {
                return(NULL);
            }
        }


        /* Getting extra data */
        if(currently_rule->extra_data)
        {
            if(!lf->data)
                return(NULL);

            if(!OSMatch_Execute(lf->data,
                        strlen(lf->data),
                        currently_rule->extra_data))
                return(NULL);
        }


        /* Checking hostname */
        if(currently_rule->hostname)
        {
            if(!lf->hostname)
                return(NULL);

            if(!OSMatch_Execute(lf->hostname,
                        strlen(lf->hostname),
                        currently_rule->hostname))
                return(NULL);
        }


        /* Checking for status */
        if(currently_rule->status)
        {
            if(!lf->status)
                return(NULL);

            if(!OSMatch_Execute(lf->status,
                        strlen(lf->status),
                        currently_rule->status))
                return(NULL);
        }


        /* Do diff check. */
        if(currently_rule->context_opts & SAME_DODIFF)
        {
            if(!doDiff(currently_rule, lf))
            {
                return(NULL);
            }
        }
    }

    /* Checking for the FTS flag */
    if(currently_rule->alert_opts & DO_FTS)
    {
        /** FTS CHECKS **/
        if(lf->decoder_info->fts)
        {
            if(lf->decoder_info->fts & FTS_DONE)
            {
                /* We already did the fts in here. */
            }
            else if(!FTS(lf))
            {
                return(NULL);
            }
        }
        else
        {
            return(NULL);
        }
    }

    /* List lookups */
    if(currently_rule->lists != NULL)
    {
        ListRule *list_holder=currently_rule->lists;
        while(list_holder)
        {
            switch(list_holder->field)
            {
                case RULE_SRCIP:
                    if(!lf->srcip)
                        return(NULL);
                    if(!OS_DBSearch(list_holder,lf->srcip))
                        return(NULL);
                    break;
                case RULE_SRCPORT:
                    if(!lf->srcport)
                        return(NULL);
                    if(!OS_DBSearch(list_holder,lf->srcport))
                        return(NULL);
                    break;
                case RULE_DSTIP:
                    if(!lf->dstip)
                        return(NULL);
                    if(!OS_DBSearch(list_holder,lf->dstip))
                        return(NULL);
                    break;
                case RULE_DSTPORT:
                    if(!lf->dstport)
                        return(NULL);
                    if(!OS_DBSearch(list_holder,lf->dstport))
                        return(NULL);
                    break;
                case RULE_USER:
                    if(lf->srcuser)
                    {
                        if(!OS_DBSearch(list_holder,lf->srcuser))
                            return(NULL);
                    }
                    else if(lf->dstuser)
                    {
                        if(!OS_DBSearch(list_holder,lf->dstuser))
                            return(NULL);
                    }
                    else
                    {
                        return(NULL);
                    }
                    break;
                case RULE_URL:
                    if(!lf->url)
                        return(NULL);
                    if(!OS_DBSearch(list_holder,lf->url))
                        return(NULL);
                    break;
                case RULE_ID:
                    if(!lf->id)
                        return(NULL);
                    if(!OS_DBSearch(list_holder,lf->id))
                        return(NULL);
                    break;
                case RULE_HOSTNAME:
                    if(!lf->hostname)
                        return(NULL);
                    if(!OS_DBSearch(list_holder,lf->hostname))
                        return(NULL);
                    break;
                case RULE_PROGRAM_NAME:
                    if(!lf->program_name)
                        return(NULL);
                    if(!OS_DBSearch(list_holder,lf->program_name))
                        return(NULL);
                    break;
                case RULE_STATUS:
                    if(!lf->status)
                        return(NULL);
                    if(!OS_DBSearch(list_holder,lf->status))
                        return(NULL);
                    break;
                case RULE_ACTION:
                    if(!lf->action)
                        return(NULL);
                    if(!OS_DBSearch(list_holder,lf->action))
                        return(NULL);
                    break;
                default:
                    return(NULL);
            }

            list_holder = list_holder->next;
        }
    }


    /* If it is a context rule, search for it */
    if(currently_rule->context == 1)
    {
        if(!currently_rule->event_search(lf, currently_rule))
            return(NULL);
    }

    #ifdef TESTRULE
    if(full_output && !alert_only)
    print_out("       *Rule %d matched.", currently_rule->sigid);
    #endif


    /* Search for dependent rules */
    if(curr_node->child)
    {
        RuleNode *child_node = curr_node->child;
        RuleInfo *child_rule = NULL;

        #ifdef TESTRULE
        if(full_output && !alert_only)
        print_out("       *Trying child rules.");
        #endif

        while(child_node)
        {
            child_rule = OS_CheckIfRuleMatch(lf, child_node);
            if(child_rule != NULL)
            {
                return(child_rule);
            }

            child_node = child_node->next;
        }
    }


    /* If we are set to no alert, keep going */
    if(currently_rule->alert_opts & NO_ALERT)
    {
        return(NULL);
    }


    hourly_alerts++;
    currently_rule->firedtimes++;

    return(currently_rule);  /* Matched */
}
Beispiel #3
0
/* Use the osdecoders to decode the received event */
void DecodeEvent(Eventinfo *lf)
{
    OSDecoderNode *node;
    OSDecoderNode *child_node;
    OSDecoderInfo *nnode;

    const char *llog = NULL;
    const char *pmatch = NULL;
    const char *cmatch = NULL;
    const char *regex_prev = NULL;

    node = OS_GetFirstOSDecoder(lf->program_name);

    if (!node) {
        return;
    }

#ifdef TESTRULE
    if (!alert_only) {
        print_out("\n**Phase 2: Completed decoding.");
    }
#endif

    do {
        nnode = node->osdecoder;

        /* First check program name */
        if (lf->program_name) {
            if (!OSMatch_Execute(lf->program_name, lf->p_name_size,
                                 nnode->program_name)) {
                continue;
            }
            pmatch = lf->log;
        }

        /* If prematch fails, go to the next osdecoder in the list */
        if (nnode->prematch) {
            if (!(pmatch = OSRegex_Execute(lf->log, nnode->prematch))) {
                continue;
            }

            /* Next character */
            if (*pmatch != '\0') {
                pmatch++;
            }
        }

#ifdef TESTRULE
        if (!alert_only) {
            print_out("       decoder: '%s'", nnode->name);
        }
#endif

        lf->decoder_info = nnode;
        child_node = node->child;

        /* If no child node is set, set the child node
         * as if it were the child (ugh)
         */
        if (!child_node) {
            child_node = node;
        }

        else {
            /* Check if we have any child osdecoder */
            while (child_node) {
                nnode = child_node->osdecoder;

                /* If we have a pre match and it matches, keep
                 * going. If we don't have a prematch, stop
                 * and go for the regexes.
                 */
                if (nnode->prematch) {
                    const char *llog2;

                    /* If we have an offset set, use it */
                    if (nnode->prematch_offset & AFTER_PARENT) {
                        llog2 = pmatch;
                    } else {
                        llog2 = lf->log;
                    }

                    if ((cmatch = OSRegex_Execute(llog2, nnode->prematch))) {
                        if (*cmatch != '\0') {
                            cmatch++;
                        }

                        lf->decoder_info = nnode;

                        break;
                    }
                } else {
                    cmatch = pmatch;
                    break;
                }

                /* If we have multiple regex-only childs,
                 * do not attempt to go any further with them.
                 */
                if (child_node->osdecoder->get_next) {
                    do {
                        child_node = child_node->next;
                    } while (child_node && child_node->osdecoder->get_next);

                    if (!child_node) {
                        return;
                    }

                    child_node = child_node->next;
                    nnode = NULL;
                } else {
                    child_node = child_node->next;
                    nnode = NULL;
                }
            }
        }

        /* Nothing matched */
        if (!nnode) {
            return;
        }

        /* If we have an external decoder, execute it */
        if (nnode->plugindecoder) {
            nnode->plugindecoder(lf);
            return;
        }

        /* Get the regex */
        while (child_node) {
            if (nnode->regex) {
                int i;

                /* With regex we have multiple options
                 * regarding the offset:
                 * after the prematch,
                 * after the parent,
                 * after some previous regex,
                 * or any offset
                 */
                if (nnode->regex_offset) {
                    if (nnode->regex_offset & AFTER_PARENT) {
                        llog = pmatch;
                    } else if (nnode->regex_offset & AFTER_PREMATCH) {
                        llog = cmatch;
                    } else if (nnode->regex_offset & AFTER_PREVREGEX) {
                        if (!regex_prev) {
                            llog = cmatch;
                        } else {
                            llog = regex_prev;
                        }
                    }
                } else {
                    llog = lf->log;
                }

                /* If Regex does not match, return */
                if (!(regex_prev = OSRegex_Execute(llog, nnode->regex))) {
                    if (nnode->get_next) {
                        child_node = child_node->next;
                        nnode = child_node->osdecoder;
                        continue;
                    }
                    return;
                }

                /* Fix next pointer */
                if (*regex_prev != '\0') {
                    regex_prev++;
                }

                for (i = 0; nnode->regex->sub_strings[i]; i++) {
                    if (lf->nfields >= Config.decoder_order_size) {
                        merror("%s: ERROR: Regex has too many groups.", ARGV0);
                        return;
                    }

                    if (nnode->order[i])
                        nnode->order[i](lf, nnode->regex->sub_strings[i], nnode->fields[i]);
                    else
                        /* We do not free any memory used above */
                        os_free(nnode->regex->sub_strings[i]);

                    nnode->regex->sub_strings[i] = NULL;
                }

                /* If we have a next regex, try getting it */
                if (nnode->get_next) {
                    child_node = child_node->next;
                    nnode = child_node->osdecoder;
                    continue;
                }

                break;
            }

            /* If we don't have a regex, we may leave now */
            return;
        }

        /* ok to return  */
        return;
    } while ((node = node->next) != NULL);

#ifdef TESTRULE
    if (!alert_only) {
        print_out("       No decoder matched.");
    }
#endif
}
Beispiel #4
0
/* Look if any of the last events (inside the timeframe)
 * match the specified rule
 */
Eventinfo *Search_LastEvents(Eventinfo *my_lf, RuleInfo *rule)
{
    EventNode *eventnode_pt;
    Eventinfo *lf;

    /* Last events */
    eventnode_pt = OS_GetLastEvent();
    if (!eventnode_pt) {
        /* Nothing found */
        return (NULL);
    }

    /* Set frequency to 0 */
    rule->__frequency = 0;

    /* Search all previous events */
    do {
        lf = eventnode_pt->event;

        /* If time is outside the timeframe, return */
        if ((c_time - lf->time) > rule->timeframe) {
            return (NULL);
        }

        /* The category must be the same */
        else if (lf->decoder_info->type != my_lf->decoder_info->type) {
            continue;
        }

        /* If regex does not match, go to next */
        if (rule->if_matched_regex) {
            if (!OSRegex_Execute(lf->log, rule->if_matched_regex)) {
                /* Didn't match */
                continue;
            }
        }

        /* Check for repetitions on user error */
        if (rule->context_opts & SAME_USER) {
            if ((!lf->dstuser) || (!my_lf->dstuser)) {
                continue;
            }

            if (strcmp(lf->dstuser, my_lf->dstuser) != 0) {
                continue;
            }
        }

        /* Check for same ID */
        if (rule->context_opts & SAME_ID) {
            if ((!lf->id) || (!my_lf->id)) {
                continue;
            }

            if (strcmp(lf->id, my_lf->id) != 0) {
                continue;
            }
        }

        /* Check for repetitions from same src_ip */
        if (rule->context_opts & SAME_SRCIP) {
            if ((!lf->srcip) || (!my_lf->srcip)) {
                continue;
            }

            if (strcmp(lf->srcip, my_lf->srcip) != 0) {
                continue;
            }
        }

        /* Check for different urls */
        if (rule->context_opts & DIFFERENT_URL) {
            if ((!lf->url) || (!my_lf->url)) {
                continue;
            }

            if (strcmp(lf->url, my_lf->url) == 0) {
                continue;
            }
        }

        /* Check for different from same srcgeoip */
        if (rule->context_opts & DIFFERENT_SRCGEOIP) {

            if ((!lf->srcgeoip) || (!my_lf->srcgeoip)) {
                continue;
            }

            if (strcmp(lf->srcgeoip, my_lf->srcgeoip) == 0) {
                continue;
            }
        }

        /* We avoid multiple triggers for the same rule
         * or rules with a lower level.
         */
        else if (lf->matched >= rule->level) {
            return (NULL);
        }

        /* Check if the number of matches worked */
        if (rule->__frequency < rule->frequency) {
            if (rule->__frequency <= 10) {
                rule->last_events[rule->__frequency]
                    = lf->full_log;
                rule->last_events[rule->__frequency + 1]
                    = NULL;
            }

            rule->__frequency++;
            continue;
        }

        /* If reached here, we matched */
        my_lf->matched = rule->level;
        lf->matched = rule->level;

        return (lf);

    } while ((eventnode_pt = eventnode_pt->next) != NULL);

    return (NULL);
}
/** main **/
int main(int argc, char **argv)
{
    char *pattern;
    
    char msg[OS_MAXSTR +1];
    memset(msg, '\0', OS_MAXSTR +1);
    OSRegex regex; 
    OSMatch matcher; 

    OS_SetName(ARGV0);
        
    
    /* user arguments */
    if(argc != 2)
    {
        helpmsg();
        return(-1);
    }
    
    /* User options */
    if(strcmp(argv[1], "-h") == 0)
    {
        helpmsg();
        return(-1);
    }

    os_strdup(argv[1], pattern);
    if(!OSRegex_Compile(pattern, &regex, 0)) 
    { 
        printf("pattern does not compile with OSRegex_Compile\n");
        return(-1); 
    }
    if(!OSMatch_Compile(pattern, &matcher, 0))
    {
        printf("pattern does not compile with OSMatch_Compile\n");
        return(-1);
    }


    while((fgets(msg, OS_MAXSTR, stdin)) != NULL)
    {        
        /* Removing new line. */                                                                                                                                       
        if(msg[strlen(msg) -1] == '\n')
            msg[strlen(msg) -1] = '\0';

        /* Make sure we ignore blank lines. */                                                                                                                         
        if(strlen(msg) < 2) { continue; }                                                            

        if(OSRegex_Execute(msg, &regex))
            printf("+OSRegex_Execute: %s\n",msg); 
        /*
        else
            printf("-OSRegex_Execute: \n"); 
            */

        if(OS_Regex(pattern, msg)) 
            printf("+OS_Regex       : %s\n", msg);
        /*
        else
            printf("-OS_Regex: \n"); 
            */

        if(OSMatch_Execute(msg, strlen(msg), &matcher)) 
            printf("+OSMatch_Compile: %s\n", msg); 
        
        if(OS_Match2(pattern, msg)) 
            printf("+OS_Match2      : %s\n", msg); 
    }
    return(0);
}