Exemple #1
0
int OS_DBSearchKeyAddressValue(ListRule *lrule, char *key)
{
    int result=-1;
    char *val;
    unsigned vlen, vpos;
    if (lrule->db!= NULL)
    {
        if(_OS_CDBOpen(lrule->db) == -1) return 0;

        // First lookup for a single IP address
        if(cdb_find(&lrule->db->cdb, key, strlen(key)) > 0 ) {
            vpos = cdb_datapos(&lrule->db->cdb);
            vlen = cdb_datalen(&lrule->db->cdb);
            val = malloc(vlen);
            cdb_read(&lrule->db->cdb, val, vlen, vpos);
            result = OSMatch_Execute(val, vlen, lrule->matcher);
            free(val);
            return result;
        } else {
            // IP address not found, look for matching subnets
            char *tmpkey;
            os_strdup(key, tmpkey);
            while(strlen(tmpkey) > 0)
            {
                if(tmpkey[strlen(tmpkey) - 1] == '.')
                {
                    if( cdb_find(&lrule->db->cdb, tmpkey, strlen(tmpkey)) > 0 ) {
                        vpos = cdb_datapos(&lrule->db->cdb);
                        vlen = cdb_datalen(&lrule->db->cdb);
                        val = malloc(vlen);
                        cdb_read(&lrule->db->cdb, val, vlen, vpos);
                        result = OSMatch_Execute(val, vlen, lrule->matcher);
                        free(val);
                        free(tmpkey);
                        return result;
                    }
                }
                tmpkey[strlen(tmpkey) - 1] = '\0';
            }
            free(tmpkey);
            return 0;
        }
    }
    return 0;
}
Exemple #2
0
/* Mark rules that match specific group (for if_matched_group) */
int OS_MarkGroup(RuleNode *r_node, RuleInfo *orig_rule)
{
    /* If no r_node is given, get first node */
    if(r_node == NULL)
    {
        r_node = OS_GetFirstRule();
    }

    while(r_node)
    {
        if(OSMatch_Execute(r_node->ruleinfo->group, 
                           strlen(r_node->ruleinfo->group),
                           orig_rule->if_matched_group))
        {
            int rule_g = 0;
            if(r_node->ruleinfo->group_prev_matched)
            {
                while(r_node->ruleinfo->group_prev_matched[rule_g])
                {
                    rule_g++;
                }
            }
            
            os_realloc(r_node->ruleinfo->group_prev_matched, 
                       (rule_g + 2)*sizeof(OSList *),
                       r_node->ruleinfo->group_prev_matched); 
            
            r_node->ruleinfo->group_prev_matched[rule_g] = NULL;
            r_node->ruleinfo->group_prev_matched[rule_g +1] = NULL;
            
            /* Setting the size */
            r_node->ruleinfo->group_prev_matched_sz = rule_g +1;
            
            r_node->ruleinfo->group_prev_matched[rule_g] = 
                              orig_rule->group_search;
        }


        /* Checking if the child has a rule */
        if(r_node->child)
        {
            OS_MarkGroup(r_node->child, orig_rule);
        }

        r_node = r_node->next;
    }

    return(0);
}
int OS_DBSearchKeyValue(ListRule *lrule, char *key)
{
    int result=-1;
    char *val;
    unsigned vlen, vpos;
    if (lrule->db!= NULL)
    {
        if(_OS_CDBOpen(lrule->db) == -1) return 0;
        if(cdb_find(&lrule->db->cdb, key, strlen(key)) > 0 ) {
            vpos = cdb_datapos(&lrule->db->cdb);
            vlen = cdb_datalen(&lrule->db->cdb);
            val = malloc(vlen);
            cdb_read(&lrule->db->cdb, val, vlen, vpos);
            result = OSMatch_Execute(val, vlen, lrule->matcher);
            free(val);
            return result; 
        } else {
            return 0;
        }
    } 
    return 0;
}
Exemple #4
0
/* Read and generate the integrity data of a file */
static int read_file(const char *file_name, int opts, OSMatch *restriction)
{
    char *buf;
    char sha1s = '+';
    struct stat statbuf;

    /* Check if the file should be ignored */
    if (syscheck.ignore) {
        int i = 0;
        while (syscheck.ignore[i] != NULL) {
            if (strncasecmp(syscheck.ignore[i], file_name,
                            strlen(syscheck.ignore[i])) == 0) {
                return (0);
            }
            i++;
        }
    }

    /* Check in the regex entry */
    if (syscheck.ignore_regex) {
        int i = 0;
        while (syscheck.ignore_regex[i] != NULL) {
            if (OSMatch_Execute(file_name, strlen(file_name),
                                syscheck.ignore_regex[i])) {
                return (0);
            }
            i++;
        }
    }

#ifdef WIN32
    /* Win32 does not have lstat */
    if (stat(file_name, &statbuf) < 0)
#else
    if (lstat(file_name, &statbuf) < 0)
#endif
    {
        if(errno == ENOTDIR){
		/*Deletion message sending*/
		char alert_msg[PATH_MAX+4];
		alert_msg[PATH_MAX + 3] = '\0';
		snprintf(alert_msg, PATH_MAX + 4, "-1 %s", file_name);
		send_syscheck_msg(alert_msg);
		return (0);
	}else{
		merror("%s: Error accessing '%s'.", ARGV0, file_name);
		return (-1);
	}
    }

    if (S_ISDIR(statbuf.st_mode)) {
#ifdef DEBUG
        verbose("%s: Reading dir: %s\n", ARGV0, file_name);
#endif

#ifdef WIN32
        /* Directory links are not supported */
        if (GetFileAttributes(file_name) & FILE_ATTRIBUTE_REPARSE_POINT) {
            merror("%s: WARN: Links are not supported: '%s'", ARGV0, file_name);
            return (-1);
        }
#endif
        return (read_dir(file_name, opts, restriction));
    }

    /* Restrict file types */
    if (restriction) {
        if (!OSMatch_Execute(file_name, strlen(file_name),
                             restriction)) {
            return (0);
        }
    }

    /* No S_ISLNK on Windows */
#ifdef WIN32
    if (S_ISREG(statbuf.st_mode))
#else
    if (S_ISREG(statbuf.st_mode) || S_ISLNK(statbuf.st_mode))
#endif
    {
        os_md5 mf_sum;
        os_sha1 sf_sum;
        os_sha1 sf_sum2;
        os_sha1 sf_sum3;

        /* Clean sums */
        strncpy(mf_sum,  "xxx", 4);
        strncpy(sf_sum,  "xxx", 4);
        strncpy(sf_sum2, "xxx", 4);
        strncpy(sf_sum3, "xxx", 4);

        /* Generate checksums */
        if ((opts & CHECK_MD5SUM) || (opts & CHECK_SHA1SUM)) {
            /* If it is a link, check if dest is valid */
#ifndef WIN32
            if (S_ISLNK(statbuf.st_mode)) {
                struct stat statbuf_lnk;
                if (stat(file_name, &statbuf_lnk) == 0) {
                    if (S_ISREG(statbuf_lnk.st_mode)) {
                        if (OS_MD5_SHA1_File(file_name, syscheck.prefilter_cmd, mf_sum, sf_sum, OS_BINARY) < 0) {
                            strncpy(mf_sum, "xxx", 4);
                            strncpy(sf_sum, "xxx", 4);
                        }
                    }
                }
            } else if (OS_MD5_SHA1_File(file_name, syscheck.prefilter_cmd, mf_sum, sf_sum, OS_BINARY) < 0)
#else
            if (OS_MD5_SHA1_File(file_name, syscheck.prefilter_cmd, mf_sum, sf_sum, OS_BINARY) < 0)
#endif
            {
                strncpy(mf_sum, "xxx", 4);
                strncpy(sf_sum, "xxx", 4);
            }

            if (opts & CHECK_SEECHANGES) {
                sha1s = 's';
            }
        } else {
            if (opts & CHECK_SEECHANGES) {
                sha1s = 'n';
            } else {
                sha1s = '-';
            }
        }

        buf = (char *) OSHash_Get(syscheck.fp, file_name);
        if (!buf) {
            char alert_msg[916 + 1];    /* to accommodate a long */
            alert_msg[916] = '\0';

            if (opts & CHECK_SEECHANGES) {
                char *alertdump = seechanges_addfile(file_name);
                if (alertdump) {
                    free(alertdump);
                    alertdump = NULL;
                }
            }

            snprintf(alert_msg, 916, "%c%c%c%c%c%c%c%c%ld:%d:%d:%d:%s:%s:%s:%s:%ld:%ld",
                     opts & CHECK_SIZE ? '+' : '-',
                     opts & CHECK_PERM ? '+' : '-',
                     opts & CHECK_OWNER ? '+' : '-',
                     opts & CHECK_GROUP ? '+' : '-',
                     opts & CHECK_MD5SUM ? '+' : '-',
                     sha1s,
                     opts & CHECK_MTIME ? '+' : '-',
                     opts & CHECK_INODE ? '+' : '-',
                     opts & CHECK_SIZE ? (long)statbuf.st_size : 0,
                     opts & CHECK_PERM ? (int)statbuf.st_mode : 0,
                     opts & CHECK_OWNER ? (int)statbuf.st_uid : 0,
                     opts & CHECK_GROUP ? (int)statbuf.st_gid : 0,
                     opts & CHECK_MD5SUM ? mf_sum : "xxx",
                     opts & CHECK_SHA1SUM ? sf_sum : "xxx",
                     opts & CHECK_OWNER ? get_user(file_name, statbuf.st_uid) : "",
                     opts & CHECK_GROUP ? get_group(statbuf.st_gid) : "",
                     opts & CHECK_MTIME ? (long)statbuf.st_mtime : 0,
                     opts & CHECK_INODE ? (long)statbuf.st_ino : 0);

            if (OSHash_Add(syscheck.fp, file_name, strdup(alert_msg)) <= 0) {
                merror("%s: ERROR: Unable to add file to db: %s", ARGV0, file_name);
            }

            /* Send the new checksum to the analysis server */
            alert_msg[916] = '\0';

            snprintf(alert_msg, 916, "%ld:%d:%d:%d:%s:%s:%s:%s:%ld:%ld %s",
                     opts & CHECK_SIZE ? (long)statbuf.st_size : 0,
                     opts & CHECK_PERM ? (int)statbuf.st_mode : 0,
                     opts & CHECK_OWNER ? (int)statbuf.st_uid : 0,
                     opts & CHECK_GROUP ? (int)statbuf.st_gid : 0,
                     opts & CHECK_MD5SUM ? mf_sum : "xxx",
                     opts & CHECK_SHA1SUM ? sf_sum : "xxx",
                     opts & CHECK_OWNER ? get_user(file_name, statbuf.st_uid) : "",
                     opts & CHECK_GROUP ? get_group(statbuf.st_gid) : "",
                     opts & CHECK_MTIME ? (long)statbuf.st_mtime : 0,
                     opts & CHECK_INODE ? (long)statbuf.st_ino : 0,
                     file_name);
            send_syscheck_msg(alert_msg);
        } else {
            char alert_msg[OS_MAXSTR + 1];
            char c_sum[256 + 2];

            c_sum[0] = '\0';
            c_sum[256] = '\0';
            alert_msg[0] = '\0';
            alert_msg[OS_MAXSTR] = '\0';

            /* If it returns < 0, we have already alerted */
            if (c_read_file(file_name, buf, c_sum) < 0) {
                return (0);
            }

            if (strcmp(c_sum, buf + 6) != 0) {
                /* Send the new checksum to the analysis server */
                alert_msg[OS_MAXSTR] = '\0';
                char *fullalert = NULL;
                if (buf[5] == 's' || buf[5] == 'n') {
                    fullalert = seechanges_addfile(file_name);
                    if (fullalert) {
                        snprintf(alert_msg, OS_MAXSTR, "%s %s\n%s", c_sum, file_name, fullalert);
                        free(fullalert);
                        fullalert = NULL;
                    } else {
                        snprintf(alert_msg, 916, "%s %s", c_sum, file_name);
                    }
                } else {
                    snprintf(alert_msg, 916, "%s %s", c_sum, file_name);
                }
                send_syscheck_msg(alert_msg);
            }
        }

        /* Sleep here too */
        if (__counter >= (syscheck.sleep_after)) {
            sleep(syscheck.tsleep);
            __counter = 0;
        }
        __counter++;

#ifdef DEBUG
        verbose("%s: file '%s %s'", ARGV0, file_name, mf_sum);
#endif
    } else {
#ifdef DEBUG
        verbose("%s: *** IRREG file: '%s'\n", ARGV0, file_name);
#endif
    }

    return (0);
}
/* Receive a Message on the Mail queue */
MailMsg *OS_RecvMailQ(file_queue *fileq, struct tm *p,
                      MailConfig *Mail, MailMsg **msg_sms)
{
    int i = 0, sms_set = 0, donotgroup = 0;
    size_t body_size = OS_MAXSTR - 3, log_size;
    char logs[OS_MAXSTR + 1];
    char extra_data[OS_MAXSTR + 1];
    char log_string[OS_MAXSTR / 4 + 1];
    char *subject_host;
#ifdef LIBGEOIP_ENABLED
    char geoip_msg_src[OS_SIZE_1024 + 1];
    char geoip_msg_dst[OS_SIZE_1024 + 1];
#endif

    MailMsg *mail;
    alert_data *al_data;

    Mail->priority = 0;

    /* Get message if available */
    al_data = Read_FileMon(fileq, p, mail_timeout);
    if (!al_data) {
        return (NULL);
    }

    /* If e-mail came correctly, generate the e-mail body/subject */
    os_calloc(1, sizeof(MailMsg), mail);
    os_calloc(BODY_SIZE, sizeof(char), mail->body);
    os_calloc(SUBJECT_SIZE, sizeof(char), mail->subject);

    /* Generate the logs */
    logs[0] = '\0';
    extra_data[0] = '\0';
    logs[OS_MAXSTR] = '\0';

    while (al_data->log[i]) {
        log_size = strlen(al_data->log[i]) + 4;

        /* If size left is small than the size of the log, stop it */
        if (body_size <= log_size) {
            break;
        }

        strncat(logs, al_data->log[i], body_size);
        strncat(logs, "\r\n", body_size);
        body_size -= log_size;
        i++;
    }

    if (al_data->old_md5) {
        log_size = strlen(al_data->old_md5) + 16 + 4;
        if (body_size > log_size) {
            strncat(logs, "Old md5sum was: ", 16);
            strncat(logs, al_data->old_md5, body_size);
            strncat(logs, "\r\n", 4);
            body_size -= log_size;
        }
    }
    if (al_data->new_md5) {
        log_size = strlen(al_data->new_md5) + 16 + 4;
        if (body_size > log_size) {
            strncat(logs, "New md5sum is : ", 16);
            strncat(logs, al_data->new_md5, body_size);
            strncat(logs, "\r\n", 4);
            body_size -= log_size;
        }
    }
    if (al_data->old_sha1) {
        log_size = strlen(al_data->old_sha1) + 17 + 4;
        if (body_size > log_size) {
            strncat(logs, "Old sha1sum was: ", 17);
            strncat(logs, al_data->old_sha1, body_size);
            strncat(logs, "\r\n", 4);
            body_size -= log_size;
        }
    }
    if (al_data->new_sha1) {
        log_size = strlen(al_data->new_sha1) + 17 + 4;
        if (body_size > log_size) {
            strncat(logs, "New sha1sum is : ", 17);
            strncat(logs, al_data->new_sha1, body_size);
            strncat(logs, "\r\n", 4);
            body_size -= log_size;
        }
    }

    /* EXTRA DATA */
    if (al_data->srcip) {
        log_size = snprintf(log_string, sizeof(log_string) - 1, "Src IP: %s\r\n", al_data->srcip );
        if (body_size > log_size) {
            if ( strncat(extra_data, log_string, log_size) != NULL ) {
                body_size -= log_size;
            }
        }
    }
    if (al_data->dstip) {
        log_size = snprintf(log_string, sizeof(log_string) - 1, "Dst IP: %s\r\n", al_data->dstip );
        if (body_size > log_size) {
            if ( strncat(extra_data, log_string, log_size) != NULL ) {
                body_size -= log_size;
            }
        }
    }
    if (al_data->user) {
        log_size = snprintf(log_string, sizeof(log_string) - 1, "User: %s\r\n", al_data->user );
        if (body_size > log_size) {
            if ( strncat(extra_data, log_string, log_size) != NULL ) {
                body_size -= log_size;
            }
        }
    }

    /* Subject */
    subject_host = strchr(al_data->location, '>');
    if (subject_host) {
        subject_host--;
        *subject_host = '\0';
    }

    /* We have two subject options - full and normal */
    if (Mail->subject_full) {
        /* Option for a clean full subject (without ossec in the name) */
#ifdef CLEANFULL
        snprintf(mail->subject, SUBJECT_SIZE - 1, MAIL_SUBJECT_FULL2,
                 al_data->level,
                 al_data->comment,
                 al_data->location);
#else
        snprintf(mail->subject, SUBJECT_SIZE - 1, MAIL_SUBJECT_FULL,
                 al_data->location,
                 al_data->level,
                 al_data->comment);
#endif
    } else {
        snprintf(mail->subject, SUBJECT_SIZE - 1, MAIL_SUBJECT,
                 al_data->location,
                 al_data->level);
    }


    /* Fix subject back */
    if (subject_host) {
        *subject_host = '-';
    }

#ifdef LIBGEOIP_ENABLED
    /* Get GeoIP information */
    if (Mail->geoip) {
        if (al_data->srcgeoip) {
            snprintf(geoip_msg_src, OS_SIZE_1024, "Src Location: %s\r\n", al_data->srcgeoip);
        } else {
            geoip_msg_src[0] = '\0';
        }
        if (al_data->dstgeoip) {
            snprintf(geoip_msg_dst, OS_SIZE_1024, "Dst Location: %s\r\n", al_data->dstgeoip);
        } else {
            geoip_msg_dst[0] = '\0';
        }
    } else {
        geoip_msg_src[0] = '\0';
        geoip_msg_dst[0] = '\0';
    }
#endif

    /* Body */
#ifdef LIBGEOIP_ENABLED
    snprintf(mail->body, BODY_SIZE - 1, MAIL_BODY,
             al_data->date,
             al_data->location,
             al_data->rule,
             al_data->level,
             al_data->comment,
             geoip_msg_src,
             geoip_msg_dst,
             extra_data,
             logs);
#else
    snprintf(mail->body, BODY_SIZE - 1, MAIL_BODY,
             al_data->date,
             al_data->location,
             al_data->rule,
             al_data->level,
             al_data->comment,
             extra_data,
             logs);
#endif
    debug2("OS_RecvMailQ: mail->body[%s]", mail->body);

    /* Check for granular email configs */
    if (Mail->gran_to) {
        i = 0;
        while (Mail->gran_to[i] != NULL) {
            int gr_set = 0;

            /* Look if location is set */
            if (Mail->gran_location[i]) {
                if (OSMatch_Execute(al_data->location,
                                    strlen(al_data->location),
                                    Mail->gran_location[i])) {
                    gr_set = 1;
                } else {
                    i++;
                    continue;
                }
            }

            /* Look for the level */
            if (Mail->gran_level[i]) {
                if (al_data->level >= Mail->gran_level[i]) {
                    gr_set = 1;
                } else {
                    i++;
                    continue;
                }
            }

            /* Look for rule id */
            if (Mail->gran_id[i]) {
                int id_i = 0;
                while (Mail->gran_id[i][id_i] != 0) {
                    if (Mail->gran_id[i][id_i] == al_data->rule) {
                        break;
                    }
                    id_i++;
                }

                /* If we found, id is going to be a valid rule */
                if (Mail->gran_id[i][id_i]) {
                    gr_set = 1;
                } else {
                    i++;
                    continue;
                }
            }

            /* Look for the group */
            if (Mail->gran_group[i]) {
                if (OSMatch_Execute(al_data->group,
                                    strlen(al_data->group),
                                    Mail->gran_group[i])) {
                    gr_set = 1;
                } else {
                    i++;
                    continue;
                }
            }

            /* If we got here, everything matched. Set this e-mail to be used. */
            if (gr_set) {
                if (Mail->gran_format[i] == SMS_FORMAT) {
                    Mail->gran_set[i] = SMS_FORMAT;

                    /* Set the SMS flag */
                    sms_set = 1;
                } else {
                    /* Options */
                    if (Mail->gran_format[i] == FORWARD_NOW) {
                        Mail->priority = 1;
                        Mail->gran_set[i] = FULL_FORMAT;
                    } else if (Mail->gran_format[i] == DONOTGROUP) {
                        Mail->priority = DONOTGROUP;
                        Mail->gran_set[i] = DONOTGROUP;
                        donotgroup = 1;
                    } else {
                        Mail->gran_set[i] = FULL_FORMAT;
                    }
                }
            }
            i++;
        }
    }


    /* If DONOTGROUP is set, we can't assign the new subject */
    if (!donotgroup) {
        /* Get highest level for alert */
        if (_g_subject[0] != '\0') {
            if (_g_subject_level < al_data->level) {
                strncpy(_g_subject, mail->subject, SUBJECT_SIZE);
                _g_subject_level = al_data->level;
            }
        } else {
            strncpy(_g_subject, mail->subject, SUBJECT_SIZE);
            _g_subject_level = al_data->level;
        }
    }

    /* If SMS is set, create the SMS output */
    if (sms_set) {
        MailMsg *msg_sms_tmp;

        /* Allocate memory for SMS */
        os_calloc(1, sizeof(MailMsg), msg_sms_tmp);
        os_calloc(BODY_SIZE, sizeof(char), msg_sms_tmp->body);
        os_calloc(SUBJECT_SIZE, sizeof(char), msg_sms_tmp->subject);

        snprintf(msg_sms_tmp->subject, SUBJECT_SIZE - 1, SMS_SUBJECT,
                 al_data->level,
                 al_data->rule,
                 al_data->comment);


        strncpy(msg_sms_tmp->body, logs, 128);
        msg_sms_tmp->body[127] = '\0';
        *msg_sms = msg_sms_tmp;
    }

    /* Clear the memory */
    FreeAlertData(al_data);

    return (mail);
}
Exemple #6
0
/** int OS_Alert_SendSyslog
 * Sends an alert via syslog.
 * Returns 1 on success or 0 on error.
 */
int OS_Alert_SendSyslog(alert_data *al_data, SyslogConfig *syslog_config)
{
    char *tstamp;
    char syslog_msg[OS_SIZE_2048];

    /* padding value */
    int padding = 0;

    /* Invalid socket. */
    if(syslog_config->socket < 0)
    {
        return(0);
    }


    /* Clearing the memory before insert */
    memset(syslog_msg, '\0', OS_SIZE_2048);


    /* Looking if location is set */
    if(syslog_config->location)
    {
        if(!OSMatch_Execute(al_data->location,
                            strlen(al_data->location),
                            syslog_config->location))
        {
            return(0);
        }
    }


    /* Looking for the level */
    if(syslog_config->level)
    {
        if(al_data->level < syslog_config->level)
        {
            return(0);
        }
    }


    /* Looking for rule id */
    if(syslog_config->rule_id)
    {
        int id_i = 0;
        while(syslog_config->rule_id[id_i] != 0)
        {
            if(syslog_config->rule_id[id_i] == al_data->rule)
            {
                break;
            }
            id_i++;
        }


        /* If we found, id is going to be a valid rule */
        if(!syslog_config->rule_id[id_i])
        {
            return(0);
        }
    }


    /* Looking for the group */
    if(syslog_config->group)
    {
        if(!OSMatch_Execute(al_data->group,
                            strlen(al_data->group),
                            syslog_config->group))
        {
            return(0);
        }
    }


    /* Fixing the timestamp to be syslog compatible.
     * We have 2008 Jul 10 10:11:23
     * Should be: Jul 10 10:11:23
     */
    tstamp = al_data->date;
    if(strlen(al_data->date) > 14)
    {
        tstamp+=5;

        /* Fixing first digit if the day is < 10 */
        if(tstamp[4] == '0')
            tstamp[4] = ' ';
    }

    /* Inserting data */
    if(syslog_config->format == DEFAULT_CSYSLOG)
    {
       	/* Building syslog message. */
       	snprintf(syslog_msg, OS_SIZE_2048,
                "<%d>%s %s ossec: Alert Level: %d; Rule: %d - %s; Location: %s;",
               	syslog_config->priority, tstamp, __shost,
                al_data->level,
                al_data->rule, al_data->comment,
                al_data->location
        );
        field_add_string(syslog_msg, OS_SIZE_2048, " srcip: %s;", al_data->srcip );
#ifdef GEOIP
        field_add_string(syslog_msg, OS_SIZE_2048, " srccity: %s;", al_data->geoipdatasrc );
        field_add_string(syslog_msg, OS_SIZE_2048, " dstcity: %s;", al_data->geoipdatadst );
#endif
        field_add_string(syslog_msg, OS_SIZE_2048, " dstip: %s;", al_data->dstip );
        field_add_string(syslog_msg, OS_SIZE_2048, " user: %s;", al_data->user );
        field_add_string(syslog_msg, OS_SIZE_2048, " Previous MD5: %s;", al_data->old_md5 );
        field_add_string(syslog_msg, OS_SIZE_2048, " Current MD5: %s;", al_data->new_md5 );
        field_add_string(syslog_msg, OS_SIZE_2048, " Previous SHA1: %s;", al_data->old_sha1 );
        field_add_string(syslog_msg, OS_SIZE_2048, " Current SHA1: %s;", al_data->new_sha1 );
        field_add_truncated(syslog_msg, OS_SIZE_2048, " %s", al_data->log[0], 2 );
    }
    else if(syslog_config->format == CEF_CSYSLOG)
    {
       	snprintf(syslog_msg, OS_SIZE_2048,

                "<%d>%s CEF:0|%s|%s|%s|%d|%s|%d|dvc=%s cs2=%s cs2Label=Location",
               	syslog_config->priority,
		tstamp,
		__author,
		__ossec_name,
		__version,
		al_data->rule,
		al_data->comment,
		(al_data->level > 10) ? 10 : al_data->level,
                __shost, al_data->location);
        field_add_string(syslog_msg, OS_SIZE_2048, " src=%s", al_data->srcip );
        field_add_string(syslog_msg, OS_SIZE_2048, " dpt=%s", al_data->dstport );
        field_add_string(syslog_msg, OS_SIZE_2048, " spt=%s", al_data->srcport );
        field_add_string(syslog_msg, OS_SIZE_2048, " fname=%s", al_data->filename );
        field_add_string(syslog_msg, OS_SIZE_2048, " dhost=%s", al_data->dstip );
        field_add_string(syslog_msg, OS_SIZE_2048, " shost=%s", al_data->srcip );
        field_add_string(syslog_msg, OS_SIZE_2048, " suser=%s", al_data->user );
        field_add_string(syslog_msg, OS_SIZE_2048, " dst=%s", al_data->dstip );
#ifdef GEOIP
        field_add_string(syslog_msg, OS_SIZE_2048, " cs3Label=SrcCity cs3=%s", al_data->geoipdatasrc );
        field_add_string(syslog_msg, OS_SIZE_2048, " cs4Label=DstCity cs4=%s", al_data->geoipdatadst );
#endif
        field_add_string(syslog_msg, OS_SIZE_2048, " suser=%s", al_data->user );
        field_add_string(syslog_msg, OS_SIZE_2048, " dst=%s", al_data->dstip );
        field_add_truncated(syslog_msg, OS_SIZE_2048, " msg=%s", al_data->log[0], 2 );
        if (al_data->new_md5 && al_data->new_sha1) {
            field_add_string(syslog_msg, OS_SIZE_2048, " cs1Label=OldMD5 cs1=%s", al_data->old_md5);
            field_add_string(syslog_msg, OS_SIZE_2048, " cs2Label=NewMDG cs2=%s", al_data->new_md5);
            field_add_string(syslog_msg, OS_SIZE_2048, " oldFileHash=%s", al_data->old_sha1 );
            field_add_string(syslog_msg, OS_SIZE_2048, " fhash=%s", al_data->new_sha1 );
            field_add_string(syslog_msg, OS_SIZE_2048, " fileHash=%s", al_data->new_sha1 );
        }
    }
    else if(syslog_config->format == JSON_CSYSLOG)
    {
        /* Build a JSON Object for logging */
        cJSON *root;
        char *json_string;
        root = cJSON_CreateObject();

        // Data guaranteed to be there
        cJSON_AddNumberToObject(root, "crit",      al_data->level);
        cJSON_AddNumberToObject(root, "id",        al_data->rule);
        cJSON_AddStringToObject(root, "component", al_data->location);

        // Rule Meta Data
        if (al_data->group)   cJSON_AddStringToObject(root, "classification", al_data->group);
        if (al_data->comment) cJSON_AddStringToObject(root, "description",    al_data->comment);

        // Raw log message generating event
        if (al_data->log && al_data->log[0])
                cJSON_AddStringToObject(root, "message",        al_data->log[0]);

        // Add data if it exists
        if (al_data->user)       cJSON_AddStringToObject(root,   "acct",       al_data->user);
        if (al_data->srcip)      cJSON_AddStringToObject(root,   "src_ip",     al_data->srcip);
        if (al_data->srcport)    cJSON_AddNumberToObject(root,   "src_port",   al_data->srcport);
        if (al_data->dstip)      cJSON_AddStringToObject(root,   "dst_ip",     al_data->dstip);
        if (al_data->dstport)    cJSON_AddNumberToObject(root,   "dst_port",   al_data->dstport);
        if (al_data->filename)   cJSON_AddStringToObject(root,   "file",       al_data->filename);
        if (al_data->old_md5)    cJSON_AddStringToObject(root,   "md5_old",    al_data->old_md5);
        if (al_data->new_md5)    cJSON_AddStringToObject(root,   "md5_new",    al_data->new_md5);
        if (al_data->old_sha1)   cJSON_AddStringToObject(root,   "sha1_old",   al_data->old_sha1);
        if (al_data->new_sha1)   cJSON_AddStringToObject(root,   "sha1_new",   al_data->new_sha1);
#ifdef GEOIP
        if (al_data->geoipdatasrc) cJSON_AddStringToObject(root, "src_city", al_data->geoipdatasrc);
        if (al_data->geoipdatadst) cJSON_AddStringToObject(root, "dst_city", al_data->geoipdatadst);
#endif

        // Create the JSON String
        json_string = cJSON_PrintUnformatted(root);

        // Create the syslog message
        snprintf(syslog_msg, OS_SIZE_2048 - padding,
                "<%d>%s %s ossec: %s",

                /* syslog header */
                syslog_config->priority, tstamp, __shost,

                /* JSON Encoded Data */
                json_string
        );
        // Cleanup the memory for the JSON Structure
        free(json_string);
        cJSON_Delete(root);
    }
    else if(syslog_config->format == SPLUNK_CSYSLOG)
    {
        /* Build a Splunk Style Key/Value string for logging */
        snprintf(syslog_msg, OS_SIZE_2048,
                "<%d>%s %s ossec: crit=%d id=%d description=\"%s\" component=\"%s\",",

                /* syslog header */
                syslog_config->priority, tstamp, __shost,

                /* OSSEC metadata */
                al_data->level, al_data->rule, al_data->comment,
                al_data->location
        );
        /* Event specifics */
        field_add_string(syslog_msg, OS_SIZE_2048, " classification=\"%s\",", al_data->group );

        if( field_add_string(syslog_msg, OS_SIZE_2048, " src_ip=\"%s\",", al_data->srcip ) > 0 )
            field_add_int(syslog_msg, OS_SIZE_2048, " src_port=%d,", al_data->srcport );

#ifdef GEOIP
        field_add_string(syslog_msg, OS_SIZE_2048, " src_city=\"%s\",", al_data->geoipdatasrc );
        field_add_string(syslog_msg, OS_SIZE_2048, " dst_city=\"%s\",", al_data->geoipdatadst );
#endif

        if( field_add_string(syslog_msg, OS_SIZE_2048, " dst_ip=\"%s\",", al_data->dstip ) > 0 )
            field_add_int(syslog_msg, OS_SIZE_2048, " dst_port=%d,", al_data->dstport );

        field_add_string(syslog_msg, OS_SIZE_2048, " file=\"%s\",", al_data->filename );
        field_add_string(syslog_msg, OS_SIZE_2048, " acct=\"%s\",", al_data->user );
        field_add_string(syslog_msg, OS_SIZE_2048, " md5_old=\"%s\",", al_data->old_md5 );
        field_add_string(syslog_msg, OS_SIZE_2048, " md5_new=\"%s\",", al_data->new_md5 );
        field_add_string(syslog_msg, OS_SIZE_2048, " sha1_old=\"%s\",", al_data->old_sha1 );
        field_add_string(syslog_msg, OS_SIZE_2048, " sha1_new=\"%s\",", al_data->new_sha1 );
        /* Message */
        field_add_truncated(syslog_msg, OS_SIZE_2048, " message=\"%s\"", al_data->log[0], 2 );
    }


    OS_SendUDPbySize(syslog_config->socket, strlen(syslog_msg), syslog_msg);
    return(1);
}
Exemple #7
0
/* FW_Log: v0.1, 2005/12/30 */
int FW_Log(Eventinfo *lf)
{
    /* If we don't have the srcip or the
     * action, there is no point in going
     * forward over here
     */
    if(!lf->action || !lf->srcip)
    {
        return(0);
    }


    /* Setting the actions */
    switch(*lf->action)
    {
        /* discard, drop, deny, */
        case 'd':
        case 'D':
        /* reject, */
        case 'r':
        case 'R':
        /* block */
        case 'b':
        case 'B':
            os_free(lf->action);
            os_strdup("DROP", lf->action);
            break;
        /* Closed */
        case 'c':
        case 'C':
        /* Teardown */
        case 't':
        case 'T':
            os_free(lf->action);
            os_strdup("CLOSED", lf->action);
            break;
        /* allow, accept, */    
        case 'a':
        case 'A':
        /* pass/permitted */
        case 'p':
        case 'P':
        /* open */
        case 'o':
        case 'O':    
            os_free(lf->action);
            os_strdup("ALLOW", lf->action);        
            break;
        default:
            if(OSMatch_Execute(lf->action,strlen(lf->action),&FWDROPpm))
            {
                os_free(lf->action);
                os_strdup("DROP", lf->action);
            }
            if(OSMatch_Execute(lf->action,strlen(lf->action),&FWALLOWpm))
            {
                os_free(lf->action);
                os_strdup("ALLOW", lf->action);
            }
            else
            {
                os_free(lf->action);
                os_strdup("UNKNOWN", lf->action);
            }
            break;    
    }


    /* log to file */
    fprintf(_fflog,
            "%d %s %02d %s %s%s%s %s %s %s:%s->%s:%s\n",
            lf->year,
            lf->mon,
            lf->day,
            lf->hour,
            lf->hostname != lf->location?lf->hostname:"",
            lf->hostname != lf->location?"->":"",
            lf->location,
            lf->action,
            lf->protocol,
            lf->srcip,
            lf->srcport,
            lf->dstip,
            lf->dstport);
    
    fflush(_fflog);

    return(1);
}
Exemple #8
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 */
}
Exemple #9
0
/** int OS_Alert_SendSyslog
 * Sends an alert via syslog.
 * Returns 1 on success or 0 on error.
 */
int OS_Alert_SendSyslog(alert_data *al_data, SyslogConfig *syslog_config)
{
    char *tstamp;
    char user_msg[256];
    char srcip_msg[256];
    
    char syslog_msg[OS_SIZE_2048 +1];


    /* Invalid socket. */
    if(syslog_config->socket < 0)
    {
        return(0);
    }
    

    /* Clearing the memory before insert */
    memset(syslog_msg, '\0', OS_SIZE_2048 +1);


    /* Looking if location is set */
    if(syslog_config->location)
    {
        if(!OSMatch_Execute(al_data->location,
                            strlen(al_data->location),
                            syslog_config->location))
        {
            return(0);
        }
    }


    /* Looking for the level */
    if(syslog_config->level)
    {
        if(al_data->level < syslog_config->level)
        {
            return(0);
        }
    }


    /* Looking for rule id */
    if(syslog_config->rule_id)
    {
        int id_i = 0;
        while(syslog_config->rule_id[id_i] != 0)
        {
            if(syslog_config->rule_id[id_i] == al_data->rule)
            {
                break;
            }
            id_i++;
        }


        /* If we found, id is going to be a valid rule */
        if(!syslog_config->rule_id[id_i])
        {
            return(0);
        }
    }


    /* Looking for the group */
    if(syslog_config->group)
    {
        if(!OSMatch_Execute(al_data->group,
                            strlen(al_data->group),
                            syslog_config->group))
        {
            return(0);
        }
    }


    /* Fixing the timestamp to be syslog compatible. 
     * We have 2008 Jul 10 10:11:23
     * Should be: Jul 10 10:11:23
     */
    tstamp = al_data->date;
    if(strlen(al_data->date) > 14)
    {
        tstamp+=5;

        /* Fixing first digit if the day is < 10 */ 
        if(tstamp[4] == '0')
            tstamp[4] = ' ';
    }
    

    /* Adding source ip. */
    if(!al_data->srcip || 
       ((al_data->srcip[0] == '(') &&
        (al_data->srcip[1] == 'n') &&
        (al_data->srcip[2] == 'o')))
    {
        srcip_msg[0] = '\0';
    }
    else
    {
        snprintf(srcip_msg, 255, " srcip: %s;", al_data->srcip);
    }


    /* Adding username. */
    if(!al_data->user || 
       ((al_data->user[0] == '(') &&
        (al_data->user[1] == 'n') &&
        (al_data->user[2] == 'o')))
    {
        user_msg[0] = '\0';
    }
    else
    {
        snprintf(user_msg, 255, " user: %s;", al_data->user);
    }


    /* Inserting data */
    if(syslog_config->format == DEFAULT_CSYSLOG)
    {
        /* Building syslog message. */
        snprintf(syslog_msg, OS_SIZE_2048,
                "<%d>%s %s ossec: Alert Level: %d; Rule: %d - %s; "
                "Location: %s;%s%s  %s",
                syslog_config->priority, tstamp, __shost,
                al_data->level, al_data->rule, al_data->comment,
                al_data->location, 

                /* Source ip. */
                srcip_msg,
                user_msg,
                al_data->log[0]);
    }


    OS_SendUDPbySize(syslog_config->socket, strlen(syslog_msg), syslog_msg);
    
    return(1);
}
Exemple #10
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
}
Exemple #11
0
/** int OS_Alert_SendSyslog
 * Sends an alert via syslog.
 * Returns 1 on success or 0 on error.
 */
int OS_Alert_SendSyslog(alert_data *al_data, SyslogConfig *syslog_config)
{
    char *tstamp;
    char syslog_msg[OS_SIZE_2048];

    /* These will be Malloc'd, so no need to predeclare size, just remember to free! */
    char *json_safe_comment;
    char *json_safe_message;

    /* padding value */
    int padding = 0;

    /* Invalid socket. */
    if(syslog_config->socket < 0)
    {
        return(0);
    }


    /* Clearing the memory before insert */
    memset(syslog_msg, '\0', OS_SIZE_2048);


    /* Looking if location is set */
    if(syslog_config->location)
    {
        if(!OSMatch_Execute(al_data->location,
                            strlen(al_data->location),
                            syslog_config->location))
        {
            return(0);
        }
    }


    /* Looking for the level */
    if(syslog_config->level)
    {
        if(al_data->level < syslog_config->level)
        {
            return(0);
        }
    }


    /* Looking for rule id */
    if(syslog_config->rule_id)
    {
        int id_i = 0;
        while(syslog_config->rule_id[id_i] != 0)
        {
            if(syslog_config->rule_id[id_i] == al_data->rule)
            {
                break;
            }
            id_i++;
        }


        /* If we found, id is going to be a valid rule */
        if(!syslog_config->rule_id[id_i])
        {
            return(0);
        }
    }


    /* Looking for the group */
    if(syslog_config->group)
    {
        if(!OSMatch_Execute(al_data->group,
                            strlen(al_data->group),
                            syslog_config->group))
        {
            return(0);
        }
    }


    /* Fixing the timestamp to be syslog compatible.
     * We have 2008 Jul 10 10:11:23
     * Should be: Jul 10 10:11:23
     */
    tstamp = al_data->date;
    if(strlen(al_data->date) > 14)
    {
        tstamp+=5;

        /* Fixing first digit if the day is < 10 */
        if(tstamp[4] == '0')
            tstamp[4] = ' ';
    }


    /* Remove the double quotes from "dangerous" fields */
    if( (json_safe_comment = os_strip_char(al_data->comment, '"')) == NULL ) {
        return(0);
    }
    if( (json_safe_message = os_strip_char(al_data->log[0], '"')) == NULL ) {
        return(0);
    }

    /* Inserting data */
    if(syslog_config->format == DEFAULT_CSYSLOG)
    {
       	/* Building syslog message. */
       	snprintf(syslog_msg, OS_SIZE_2048,
                "<%d>%s %s ossec: Alert Level: %d; Rule: %d - %s; Location: %s;",
               	syslog_config->priority, tstamp, __shost,
                al_data->level,
                al_data->rule, al_data->comment,
                al_data->location
        );
        field_add_string(syslog_msg, OS_SIZE_2048, " srcip: %s;", al_data->srcip );
#ifdef GEOIP
        field_add_string(syslog_msg, OS_SIZE_2048, " srccity: %s;", al_data->geoipdatasrc );
        field_add_string(syslog_msg, OS_SIZE_2048, " dstcity: %s;", al_data->geoipdatadst );
#endif
        field_add_string(syslog_msg, OS_SIZE_2048, " dstip: %s;", al_data->dstip );
        field_add_string(syslog_msg, OS_SIZE_2048, " user: %s;", al_data->user );
        field_add_string(syslog_msg, OS_SIZE_2048, " Previous MD5: %s;", al_data->old_md5 );
        field_add_string(syslog_msg, OS_SIZE_2048, " Current MD5: %s;", al_data->new_md5 );
        field_add_string(syslog_msg, OS_SIZE_2048, " Previous SHA1: %s;", al_data->old_sha1 );
        field_add_string(syslog_msg, OS_SIZE_2048, " Current SHA1: %s;", al_data->new_sha1 );
        field_add_truncated(syslog_msg, OS_SIZE_2048, " %s", al_data->log[0], 2 );
    }
    else if(syslog_config->format == CEF_CSYSLOG)
    {
       	snprintf(syslog_msg, OS_SIZE_2048,

                "<%d>%s CEF:0|%s|%s|%s|%d|%s|%d|dvc=%s cs2=%s cs2Label=Location",
               	syslog_config->priority,
		tstamp,
		__author,
		__ossec_name,
		__version,
		al_data->rule,
		al_data->comment,
		(al_data->level > 10) ? 10 : al_data->level,
                __shost, al_data->location);

        field_add_string(syslog_msg, OS_SIZE_2048, " src=%s", al_data->srcip );
#ifdef GEOIP
        field_add_string(syslog_msg, OS_SIZE_2048, " cs3Label=SrcCity cs3=%s", al_data->geoipdatasrc );
        field_add_string(syslog_msg, OS_SIZE_2048, " cs4Label=DstCity cs4=%s", al_data->geoipdatadst );
#endif
        field_add_string(syslog_msg, OS_SIZE_2048, " suser=%s", al_data->user );
        field_add_string(syslog_msg, OS_SIZE_2048, " dst=%s", al_data->dstip );
        field_add_truncated(syslog_msg, OS_SIZE_2048, " msg=%s", al_data->log[0], 2 );
        if (al_data->new_md5 && al_data->new_sha1) {
            field_add_string(syslog_msg, OS_SIZE_2048, " Previous MD5: %s", al_data->old_md5 );
            field_add_string(syslog_msg, OS_SIZE_2048, " Current MD5: %s", al_data->new_md5 );
            field_add_string(syslog_msg, OS_SIZE_2048, " Previous SHA1: %s", al_data->old_sha1 );
            field_add_string(syslog_msg, OS_SIZE_2048, " Current SHA1: %s", al_data->new_sha1 );
        }
    }
    else if(syslog_config->format == JSON_CSYSLOG)
    {
        // Padding is two to make sure we can fit closign bracket
        padding = 2;
        /* Build a JSON Object for logging */
        snprintf(syslog_msg, OS_SIZE_2048 - padding,
                "<%d>%s %s ossec: { \"crit\": %d, \"id\": %d, \"description\": \"%s\", \"component\": \"%s\",",

                /* syslog header */
                syslog_config->priority, tstamp, __shost,

                /* OSSEC metadata */
                al_data->level, al_data->rule, json_safe_comment,
                al_data->location
        );
        /* Event specifics */
        field_add_string(syslog_msg, OS_SIZE_2048 - padding, " \"classification\": \"%s\",", al_data->group );

        if( field_add_string(syslog_msg, OS_SIZE_2048 - padding, " \"src_ip\": \"%s\",", al_data->srcip ) > 0 )
            field_add_int(syslog_msg, OS_SIZE_2048 - padding, " \"src_port\": %d,", al_data->srcport );

#ifdef GEOIP
        field_add_string(syslog_msg, OS_SIZE_2048 - padding, " \"src_city\": \"%s\",", al_data->geoipdatasrc );
        field_add_string(syslog_msg, OS_SIZE_2048 - padding, " \"dst_city\": \"%s\",", al_data->geoipdatadst );
#endif

        if ( field_add_string(syslog_msg, OS_SIZE_2048 - padding, " \"dst_ip\": \"%s\",", al_data->dstip ) > 0 )
            field_add_int(syslog_msg, OS_SIZE_2048 - padding, " \"dst_port\": %d,", al_data->dstport );

        field_add_string(syslog_msg, OS_SIZE_2048 - padding, " \"file\": \"%s\",", al_data->filename );
        field_add_string(syslog_msg, OS_SIZE_2048 - padding, " \"acct\": \"%s\",", al_data->user );
        field_add_string(syslog_msg, OS_SIZE_2048 - padding, " \"md5_old\": \"%s\",", al_data->old_md5 );
        field_add_string(syslog_msg, OS_SIZE_2048 - padding, " \"md5_new\": \"%s\",", al_data->new_md5 );
        field_add_string(syslog_msg, OS_SIZE_2048 - padding, " \"sha1_old\": \"%s\",", al_data->old_sha1 );
        field_add_string(syslog_msg, OS_SIZE_2048 - padding, " \"sha1_new\": \"%s\",", al_data->new_sha1 );
		/* Message */
        field_add_truncated(syslog_msg, OS_SIZE_2048 - padding, " \"message\": \"%s\"", json_safe_message, 2 );
        /* Closing brace */
        field_add_string(syslog_msg, OS_SIZE_2048, " }", "" );
    }
    else if(syslog_config->format == SPLUNK_CSYSLOG)
    {
        /* Build a Splunk Style Key/Value string for logging */
        snprintf(syslog_msg, OS_SIZE_2048,
                "<%d>%s %s ossec: crit=%d id=%d description=\"%s\" component=\"%s\",",

                /* syslog header */
                syslog_config->priority, tstamp, __shost,

                /* OSSEC metadata */
                al_data->level, al_data->rule, json_safe_comment,
                al_data->location
        );
        /* Event specifics */
        field_add_string(syslog_msg, OS_SIZE_2048, " classification=\"%s\",", al_data->group );

        if( field_add_string(syslog_msg, OS_SIZE_2048, " src_ip=\"%s\",", al_data->srcip ) > 0 )
            field_add_int(syslog_msg, OS_SIZE_2048, " src_port=%d,", al_data->srcport );

#ifdef GEOIP
        field_add_string(syslog_msg, OS_SIZE_2048, " src_city=\"%s\",", al_data->geoipdatasrc );
        field_add_string(syslog_msg, OS_SIZE_2048, " dst_city=\"%s\",", al_data->geoipdatadst );
#endif

        if( field_add_string(syslog_msg, OS_SIZE_2048, " dst_ip=\"%s\",", al_data->dstip ) > 0 )
            field_add_int(syslog_msg, OS_SIZE_2048, " dst_port=%d,", al_data->dstport );

        field_add_string(syslog_msg, OS_SIZE_2048, " file=\"%s\",", al_data->filename );
        field_add_string(syslog_msg, OS_SIZE_2048, " acct=\"%s\",", al_data->user );
        field_add_string(syslog_msg, OS_SIZE_2048, " md5_old=\"%s\",", al_data->old_md5 );
        field_add_string(syslog_msg, OS_SIZE_2048, " md5_new=\"%s\",", al_data->new_md5 );
        field_add_string(syslog_msg, OS_SIZE_2048, " sha1_old=\"%s\",", al_data->old_sha1 );
        field_add_string(syslog_msg, OS_SIZE_2048, " sha1_new=\"%s\",", al_data->new_sha1 );
        /* Message */
        field_add_truncated(syslog_msg, OS_SIZE_2048, " message=\"%s\"", json_safe_message, 2 );
    }


    OS_SendUDPbySize(syslog_config->socket, strlen(syslog_msg), syslog_msg);
    /* Free the malloc'd variables */
    free(json_safe_comment);
    free(json_safe_message);

    return(1);
}
/** 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);
}
Exemple #13
0
/* Send an alert via syslog
 * Returns 1 on success or 0 on error
 */
int OS_Alert_SendSyslog(alert_data *al_data, const SyslogConfig *syslog_config)
{
    char *tstamp;
    char *hostname;
    char syslog_msg[OS_SIZE_2048];

    /* Invalid socket */
    if (syslog_config->socket < 0) {
        return (0);
    }

    /* Clear the memory before insert */
    memset(syslog_msg, '\0', OS_SIZE_2048);

    /* Look if location is set */
    if (syslog_config->location) {
        if (!OSMatch_Execute(al_data->location,
                             strlen(al_data->location),
                             syslog_config->location)) {
            return (0);
        }
    }

    /* Look for the level */
    if (syslog_config->level) {
        if (al_data->level < syslog_config->level) {
            return (0);
        }
    }

    /* Look for rule id */
    if (syslog_config->rule_id) {
        int id_i = 0;
        while (syslog_config->rule_id[id_i] != 0) {
            if (syslog_config->rule_id[id_i] == al_data->rule) {
                break;
            }
            id_i++;
        }

        /* If we found, id is going to be a valid rule */
        if (!syslog_config->rule_id[id_i]) {
            return (0);
        }
    }

    /* Look for the group */
    if (syslog_config->group) {
        if (!OSMatch_Execute(al_data->group,
                             strlen(al_data->group),
                             syslog_config->group)) {
            return (0);
        }
    }

    /* Fix the timestamp to be syslog compatible
     * We have 2008 Jul 10 10:11:23
     * Should be: Jul 10 10:11:23
     */
    tstamp = al_data->date;
    if (strlen(al_data->date) > 14) {
        tstamp += 5;

        /* Fix first digit if the day is < 10 */
        if (tstamp[4] == '0') {
            tstamp[4] = ' ';
        }
    }

    if (syslog_config->use_fqdn) {
        hostname = __shost_long;
    } else {
        hostname = __shost;
    }

    /* Insert data */
    if (syslog_config->format == DEFAULT_CSYSLOG) {
        /* Build syslog message */
        snprintf(syslog_msg, OS_SIZE_2048,
                 "<%u>%s %s ossec: Alert Level: %u; Rule: %u - %s; Location: %s;",
                 syslog_config->priority, tstamp, hostname,
                 al_data->level,
                 al_data->rule, al_data->comment,
                 al_data->location
                );
        field_add_string(syslog_msg, OS_SIZE_2048, " classification: %s;", al_data->group );
        field_add_string(syslog_msg, OS_SIZE_2048, " srcip: %s;", al_data->srcip );
#ifdef LIBGEOIP_ENABLED
        field_add_string(syslog_msg, OS_SIZE_2048, " srccity: %s;", al_data->srcgeoip );
        field_add_string(syslog_msg, OS_SIZE_2048, " dstcity: %s;", al_data->dstgeoip );
#endif
        field_add_string(syslog_msg, OS_SIZE_2048, " dstip: %s;", al_data->dstip );
        field_add_string(syslog_msg, OS_SIZE_2048, " user: %s;", al_data->user );
        field_add_string(syslog_msg, OS_SIZE_2048, " Previous MD5: %s;", al_data->old_md5 );
        field_add_string(syslog_msg, OS_SIZE_2048, " Current MD5: %s;", al_data->new_md5 );
        field_add_string(syslog_msg, OS_SIZE_2048, " Previous SHA1: %s;", al_data->old_sha1 );
        field_add_string(syslog_msg, OS_SIZE_2048, " Current SHA1: %s;", al_data->new_sha1 );
     /* "9/19/2016 - Sivakumar Nellurandi - parsing additions" */
        field_add_string(syslog_msg, OS_SIZE_2048, " Size changed: from %s;", al_data->file_size );
        field_add_string(syslog_msg, OS_SIZE_2048, " User ownership: was %s;", al_data->owner_chg );
        field_add_string(syslog_msg, OS_SIZE_2048, " Group ownership: was %s;", al_data->group_chg );
        field_add_string(syslog_msg, OS_SIZE_2048, " Permissions changed: from %s;", al_data->perm_chg );
     /* "9/19/2016 - Sivakumar Nellurandi - parsing additions" */
        field_add_truncated(syslog_msg, OS_SIZE_2048, " %s", al_data->log[0], 2 );
    } else if (syslog_config->format == CEF_CSYSLOG) {
        snprintf(syslog_msg, OS_SIZE_2048,
                 "<%u>%s CEF:0|%s|%s|%s|%u|%s|%u|dvc=%s cs1=%s cs1Label=Location",
                 syslog_config->priority,
                 tstamp,
                 __author,
                 __ossec_name,
                 __version,
                 al_data->rule,
                 al_data->comment,
                 (al_data->level > 10) ? 10 : al_data->level,
                 hostname, al_data->location);
        field_add_string(syslog_msg, OS_SIZE_2048, " classification=%s", al_data->group );
        field_add_string(syslog_msg, OS_SIZE_2048, " src=%s", al_data->srcip );
        field_add_int(syslog_msg, OS_SIZE_2048, " dpt=%d", al_data->dstport );
        field_add_int(syslog_msg, OS_SIZE_2048, " spt=%d", al_data->srcport );
        field_add_string(syslog_msg, OS_SIZE_2048, " fname=%s", al_data->filename );
        field_add_string(syslog_msg, OS_SIZE_2048, " dhost=%s", al_data->dstip );
        field_add_string(syslog_msg, OS_SIZE_2048, " shost=%s", al_data->srcip );
        field_add_string(syslog_msg, OS_SIZE_2048, " suser=%s", al_data->user );
        field_add_string(syslog_msg, OS_SIZE_2048, " dst=%s", al_data->dstip );
#ifdef LIBGEOIP_ENABLED
        field_add_string(syslog_msg, OS_SIZE_2048, " cs4Label=SrcCity cs4=%s", al_data->srcgeoip );
        field_add_string(syslog_msg, OS_SIZE_2048, " cs5Label=DstCity cs5=%s", al_data->dstgeoip );
#endif
        field_add_string(syslog_msg, OS_SIZE_2048, " suser=%s", al_data->user );
        field_add_string(syslog_msg, OS_SIZE_2048, " dst=%s", al_data->dstip );
        field_add_truncated(syslog_msg, OS_SIZE_2048, " msg=%s", al_data->log[0], 2 );
        if (al_data->new_md5 && al_data->new_sha1) {
            field_add_string(syslog_msg, OS_SIZE_2048, " cs2Label=OldMD5 cs2=%s", al_data->old_md5);
            field_add_string(syslog_msg, OS_SIZE_2048, " cs3Label=NewMD5 cs3=%s", al_data->new_md5);
            field_add_string(syslog_msg, OS_SIZE_2048, " oldFileHash=%s", al_data->old_sha1 );
            field_add_string(syslog_msg, OS_SIZE_2048, " fhash=%s", al_data->new_sha1 );
            field_add_string(syslog_msg, OS_SIZE_2048, " fileHash=%s", al_data->new_sha1 );
        }
    } else if (syslog_config->format == JSON_CSYSLOG) {
        /* Build a JSON Object for logging */
        cJSON *root;
        char *json_string;
        root = cJSON_CreateObject();

        /* Data guaranteed to be there */
        cJSON_AddNumberToObject(root, "crit",      al_data->level);
        cJSON_AddNumberToObject(root, "id",        al_data->rule);
        cJSON_AddStringToObject(root, "component", al_data->location);

        /* Rule Meta Data */
        if (al_data->group) {
            cJSON_AddStringToObject(root, "classification", al_data->group);
        }
        if (al_data->comment) {
            cJSON_AddStringToObject(root, "description",    al_data->comment);
        }

        /* Raw log message generating event */
        if (al_data->log && al_data->log[0]) {
            cJSON_AddStringToObject(root, "message",        al_data->log[0]);
        }

        /* Add data if it exists */
        if (al_data->user) {
            cJSON_AddStringToObject(root,   "acct",       al_data->user);
        }
        if (al_data->srcip) {
            cJSON_AddStringToObject(root,   "src_ip",     al_data->srcip);
        }
        if (al_data->srcport) {
            cJSON_AddNumberToObject(root,   "src_port",   al_data->srcport);
        }
        if (al_data->dstip) {
            cJSON_AddStringToObject(root,   "dst_ip",     al_data->dstip);
        }
        if (al_data->dstport) {
            cJSON_AddNumberToObject(root,   "dst_port",   al_data->dstport);
        }
        if (al_data->filename) {
            cJSON_AddStringToObject(root,   "file",       al_data->filename);
        }
        if (al_data->old_md5) {
            cJSON_AddStringToObject(root,   "md5_old",    al_data->old_md5);
        }
        if (al_data->new_md5) {
            cJSON_AddStringToObject(root,   "md5_new",    al_data->new_md5);
        }
        if (al_data->old_sha1) {
            cJSON_AddStringToObject(root,   "sha1_old",   al_data->old_sha1);
        }
        if (al_data->new_sha1) {
            cJSON_AddStringToObject(root,   "sha1_new",   al_data->new_sha1);
        }
#ifdef LIBGEOIP_ENABLED
        if (al_data->srcgeoip) {
            cJSON_AddStringToObject(root, "src_city", al_data->srcgeoip);
        }
        if (al_data->dstgeoip) {
            cJSON_AddStringToObject(root, "dst_city", al_data->dstgeoip);
        }
#endif

        /* Create the JSON string */
        json_string = cJSON_PrintUnformatted(root);

        /* Create the syslog message */
        snprintf(syslog_msg, OS_SIZE_2048,
                 "<%u>%s %s ossec: %s",

                 /* syslog header */
                 syslog_config->priority, tstamp, hostname,

                 /* JSON Encoded Data */
                 json_string
                );
        /* Clean up the memory for the JSON structure */
        free(json_string);
        cJSON_Delete(root);
    } else if (syslog_config->format == SPLUNK_CSYSLOG) {
        /* Build a Splunk Style Key/Value string for logging */
        snprintf(syslog_msg, OS_SIZE_2048,
                 "<%u>%s %s ossec: crit=%u id=%u description=\"%s\" component=\"%s\",",

                 /* syslog header */
                 syslog_config->priority, tstamp, hostname,

                 /* OSSEC metadata */
                 al_data->level, al_data->rule, al_data->comment,
                 al_data->location
                );
        /* Event specifics */
        field_add_string(syslog_msg, OS_SIZE_2048, " classification=\"%s\",", al_data->group );

        if ( field_add_string(syslog_msg, OS_SIZE_2048, " src_ip=\"%s\",", al_data->srcip ) > 0 ) {
            field_add_int(syslog_msg, OS_SIZE_2048, " src_port=%d,", al_data->srcport );
        }

#ifdef LIBGEOIP_ENABLED
        field_add_string(syslog_msg, OS_SIZE_2048, " src_city=\"%s\",", al_data->srcgeoip );
        field_add_string(syslog_msg, OS_SIZE_2048, " dst_city=\"%s\",", al_data->dstgeoip );
#endif

        if ( field_add_string(syslog_msg, OS_SIZE_2048, " dst_ip=\"%s\",", al_data->dstip ) > 0 ) {
            field_add_int(syslog_msg, OS_SIZE_2048, " dst_port=%d,", al_data->dstport );
        }

        field_add_string(syslog_msg, OS_SIZE_2048, " file=\"%s\",", al_data->filename );
        field_add_string(syslog_msg, OS_SIZE_2048, " acct=\"%s\",", al_data->user );
        field_add_string(syslog_msg, OS_SIZE_2048, " md5_old=\"%s\",", al_data->old_md5 );
        field_add_string(syslog_msg, OS_SIZE_2048, " md5_new=\"%s\",", al_data->new_md5 );
        field_add_string(syslog_msg, OS_SIZE_2048, " sha1_old=\"%s\",", al_data->old_sha1 );
        field_add_string(syslog_msg, OS_SIZE_2048, " sha1_new=\"%s\",", al_data->new_sha1 );
        /* Message */
        field_add_truncated(syslog_msg, OS_SIZE_2048, " message=\"%s\"", al_data->log[0], 2 );
    }

    OS_SendUDPbySize(syslog_config->socket, strlen(syslog_msg), syslog_msg);
    return (1);
}
Exemple #14
0
void OS_Exec(int execq, int arq, const Eventinfo *lf, const active_response *ar)
{
    char exec_msg[OS_SIZE_1024 + 1];
    const char *ip;
    const char *user;
    char *filename = NULL;

    ip = user = "******";

    /* Clean the IP */
    if (lf->srcip && (ar->ar_cmd->expect & SRCIP)) {
        if (strncmp(lf->srcip, "::ffff:", 7) == 0) {
            ip = lf->srcip + 7;
        } else {
            ip = lf->srcip;
        }

        /* Check if IP is to be ignored */
        if (Config.white_list) {
            if (OS_IPFoundList(ip, Config.white_list)) {
                return;
            }
        }

        /* Check if it is a hostname */
        if (Config.hostname_white_list) {
            size_t srcip_size;
            OSMatch **wl;

            srcip_size = strlen(ip);

            wl = Config.hostname_white_list;
            while (*wl) {
                if (OSMatch_Execute(ip, srcip_size, *wl)) {
                    return;
                }
                wl++;
            }
        }
    }

    /* Get username */
    if (lf->dstuser && (ar->ar_cmd->expect & USERNAME)) {
        user = lf->dstuser;
    }

    /* Get filename */
    if (lf->filename && (ar->ar_cmd->expect & FILENAME)) {
        filename = os_shell_escape(lf->filename);
    }

    /* Active Response on the server
     * The response must be here if the ar->location is set to AS
     * or the ar->location is set to local (REMOTE_AGENT) and the
     * event location is from here.
     */
    if ((ar->location & AS_ONLY) ||
            ((ar->location & REMOTE_AGENT) && (lf->location[0] != '(')) ) {
        if (!(Config.ar & LOCAL_AR)) {
            goto cleanup;
        }

        snprintf(exec_msg, OS_SIZE_1024,
                 "%s %s %s %ld.%ld %d %s %s",
                 ar->name,
                 user,
                 ip,
                 (long int)lf->time,
                 __crt_ftell,
                 lf->generated_rule->sigid,
                 lf->location,
                 filename ? filename : "-");

        if (OS_SendUnix(execq, exec_msg, 0) < 0) {
            merror("%s: Error communicating with execd.", ARGV0);
        }
    }

    /* Active Response to the forwarder */
    else if ((Config.ar & REMOTE_AR)) {
        int rc;
        /* If lf->location start with a ( was generated by remote agent and its
         * ID is included in lf->location if missing then it must have been
         * generated by the local analysisd, so prepend a false id tag */
        if (lf->location[0] == '(') {
            snprintf(exec_msg, OS_SIZE_1024,
                     "%s %c%c%c %s %s %s %s %ld.%ld %d %s %s",
                     lf->location,
                     (ar->location & ALL_AGENTS) ? ALL_AGENTS_C : NONE_C,
                     (ar->location & REMOTE_AGENT) ? REMOTE_AGENT_C : NONE_C,
                     (ar->location & SPECIFIC_AGENT) ? SPECIFIC_AGENT_C : NONE_C,
                     ar->agent_id != NULL ? ar->agent_id : "(null)",
                     ar->name,
                     user,
                     ip,
                     (long int)lf->time,
                     __crt_ftell,
                     lf->generated_rule->sigid,
                     lf->location,
                     filename);
        } else {
            snprintf(exec_msg, OS_SIZE_1024,
                     "(local_source) %s %c%c%c %s %s %s %s %ld.%ld %d %s %s",
                     lf->location,
                     (ar->location & ALL_AGENTS) ? ALL_AGENTS_C : NONE_C,
                     (ar->location & REMOTE_AGENT) ? REMOTE_AGENT_C : NONE_C,
                     (ar->location & SPECIFIC_AGENT) ? SPECIFIC_AGENT_C : NONE_C,
                     ar->agent_id != NULL ? ar->agent_id : "(null)",
                     ar->name,
                     user,
                     ip,
                     (long int)lf->time,
                     __crt_ftell,
                     lf->generated_rule->sigid,
                     lf->location,
                     filename);
        }

        if ((rc = OS_SendUnix(arq, exec_msg, 0)) < 0) {
            if (rc == OS_SOCKBUSY) {
                merror("%s: AR socket busy.", ARGV0);
            } else {
                merror("%s: AR socket error (shutdown?).", ARGV0);
            }
            merror("%s: Error communicating with ar queue (%d).", ARGV0, rc);
        }
    }

    cleanup:

    /* Clean up Memory */
    free(filename);

    return;
}