X-Git-Url: http://ftp.carnet.hr/carnet-debian/scm?a=blobdiff_plain;f=src%2Fanalysisd%2Fdecoders%2Fsyscheck.c;h=a6d675892a05324ea675714beb2e5c7a37e02963;hb=3f728675941dc69d4e544d3a880a56240a6e394a;hp=26350f3cdb44c2b014bd0f5ee8f0a264085fbf13;hpb=789cbc8e52da68eba3517b920ef22e000cf3c9fd;p=ossec-hids.git diff --git a/src/analysisd/decoders/syscheck.c b/src/analysisd/decoders/syscheck.c old mode 100755 new mode 100644 index 26350f3..a6d6758 --- a/src/analysisd/decoders/syscheck.c +++ b/src/analysisd/decoders/syscheck.c @@ -1,6 +1,3 @@ -/* @(#) $Id: ./src/analysisd/decoders/syscheck.c, 2012/02/07 dcid Exp $ - */ - /* Copyright (C) 2009 Trend Micro Inc. * All right reserved. * @@ -10,7 +7,6 @@ * Foundation */ - /* Syscheck decoder */ #include "eventinfo.h" @@ -19,26 +15,27 @@ #include "alerts/alerts.h" #include "decoder.h" +#ifdef SQLITE_ENABLED +#include "syscheck-sqlite.h" +#endif -typedef struct __sdb -{ +typedef struct __sdb { char buf[OS_MAXSTR + 1]; - char comment[OS_MAXSTR +1]; + char comment[OS_MAXSTR + 1]; - char size[OS_FLSIZE +1]; - char perm[OS_FLSIZE +1]; - char owner[OS_FLSIZE +1]; - char gowner[OS_FLSIZE +1]; - char md5[OS_FLSIZE +1]; - char sha1[OS_FLSIZE +1]; + char size[OS_FLSIZE + 1]; + char perm[OS_FLSIZE + 1]; + char owner[OS_FLSIZE + 1]; + char gowner[OS_FLSIZE + 1]; + char md5[OS_FLSIZE + 1]; + char sha1[OS_FLSIZE + 1]; - char agent_cp[MAX_AGENTS +1][1]; - char *agent_ips[MAX_AGENTS +1]; - FILE *agent_fps[MAX_AGENTS +1]; + char agent_cp[MAX_AGENTS + 1][1]; + char *agent_ips[MAX_AGENTS + 1]; + FILE *agent_fps[MAX_AGENTS + 1]; int db_err; - /* Ids for decoder */ int id1; int id2; @@ -46,51 +43,74 @@ typedef struct __sdb int idn; int idd; - /* Syscheck rule */ OSDecoderInfo *syscheck_dec; - /* File search variables */ fpos_t init_pos; -}_sdb; /* syscheck db information */ - +} _sdb; /* syscheck db information */ + +/* Local variables */ +static _sdb sdb; + +/* Extract a token from a string */ +char *extract_token(const char *s, char *delim, int position) { + int count = 0; + char tmp[OS_MAXSTR + 1]; + char *token; + strncpy(tmp,s, OS_MAXSTR); + token = strtok(tmp, delim); + while (token != NULL) { + count++; + token = strtok(NULL, delim); + if (count == position) { + return(token); + } + } + return(NULL); +} -/* Global variable */ -_sdb sdb; +/* Validate a MD5 string format */ +int validate_md5(char *s) { + unsigned int i; + char *hex_chars = "abcdefABCDEF0123456789"; + if (strlen(s) != 32) { + return(0); + } + for (i = 0; i < strlen(s); i++) { + if (!strchr(hex_chars, s[i])) return(0); + } + return(1); +} -/* SyscheckInit - * Initialize the necessary information to process the syscheck information - */ +/* Initialize the necessary information to process the syscheck information */ void SyscheckInit() { int i = 0; sdb.db_err = 0; - for(;i <= MAX_AGENTS;i++) - { + for (; i <= MAX_AGENTS; i++) { sdb.agent_ips[i] = NULL; sdb.agent_fps[i] = NULL; sdb.agent_cp[i][0] = '0'; } - /* Clearing db memory */ - memset(sdb.buf, '\0', OS_MAXSTR +1); - memset(sdb.comment, '\0', OS_MAXSTR +1); + /* Clear db memory */ + memset(sdb.buf, '\0', OS_MAXSTR + 1); + memset(sdb.comment, '\0', OS_MAXSTR + 1); - memset(sdb.size, '\0', OS_FLSIZE +1); - memset(sdb.perm, '\0', OS_FLSIZE +1); - memset(sdb.owner, '\0', OS_FLSIZE +1); - memset(sdb.gowner, '\0', OS_FLSIZE +1); - memset(sdb.md5, '\0', OS_FLSIZE +1); - memset(sdb.sha1, '\0', OS_FLSIZE +1); + memset(sdb.size, '\0', OS_FLSIZE + 1); + memset(sdb.perm, '\0', OS_FLSIZE + 1); + memset(sdb.owner, '\0', OS_FLSIZE + 1); + memset(sdb.gowner, '\0', OS_FLSIZE + 1); + memset(sdb.md5, '\0', OS_FLSIZE + 1); + memset(sdb.sha1, '\0', OS_FLSIZE + 1); - - /* Creating decoder */ + /* Create decoder */ os_calloc(1, sizeof(OSDecoderInfo), sdb.syscheck_dec); sdb.syscheck_dec->id = getDecoderfromlist(SYSCHECK_MOD); sdb.syscheck_dec->name = SYSCHECK_MOD; @@ -107,67 +127,54 @@ void SyscheckInit() return; } -/* DB_IsCompleted - * Checks if the db is completed for that specific agent. - */ +/* Check if the db is completed for that specific agent */ #define DB_IsCompleted(x) (sdb.agent_cp[x][0] == '1')?1:0 - -void __setcompleted(char *agent) +static void __setcompleted(const char *agent) { FILE *fp; - /* Getting agent file */ + /* Get agent file */ snprintf(sdb.buf, OS_FLSIZE , "%s/.%s.cpt", SYSCHECK_DIR, agent); - fp = fopen(sdb.buf,"w"); - if(fp) - { + fp = fopen(sdb.buf, "w"); + if (fp) { fprintf(fp, "#!X"); fclose(fp); } } - -int __iscompleted(char *agent) +static int __iscompleted(const char *agent) { FILE *fp; - /* Getting agent file */ + /* Get agent file */ snprintf(sdb.buf, OS_FLSIZE , "%s/.%s.cpt", SYSCHECK_DIR, agent); - fp = fopen(sdb.buf,"r"); - if(fp) - { + fp = fopen(sdb.buf, "r"); + if (fp) { fclose(fp); - return(1); + return (1); } - return(0); + return (0); } - -/* void DB_SetCompleted(Eventinfo *lf). - * Set the database of a specific agent as completed. - */ -void DB_SetCompleted(Eventinfo *lf) +/* Set the database of a specific agent as completed */ +static void DB_SetCompleted(const Eventinfo *lf) { int i = 0; - /* Finding file pointer */ - while(sdb.agent_ips[i] != NULL && i < MAX_AGENTS) - { - if(strcmp(sdb.agent_ips[i], lf->location) == 0) - { - /* Return if already set as completed. */ - if(DB_IsCompleted(i)) - { + /* Find file pointer */ + while (sdb.agent_ips[i] != NULL && i < MAX_AGENTS) { + if (strcmp(sdb.agent_ips[i], lf->location) == 0) { + /* Return if already set as completed */ + if (DB_IsCompleted(i)) { return; } __setcompleted(lf->location); - - /* Setting as completed in memory */ + /* Set as completed in memory */ sdb.agent_cp[i][0] = '1'; return; } @@ -177,87 +184,71 @@ void DB_SetCompleted(Eventinfo *lf) } -/* DB_File - * Return the file pointer to be used to verify the integrity - */ -FILE *DB_File(char *agent, int *agent_id) +/* Return the file pointer to be used to verify the integrity */ +static FILE *DB_File(const char *agent, int *agent_id) { int i = 0; - /* Finding file pointer */ - while(sdb.agent_ips[i] != NULL && i < MAX_AGENTS) - { - if(strcmp(sdb.agent_ips[i], agent) == 0) - { - /* Pointing to the beginning of the file */ - fseek(sdb.agent_fps[i],0, SEEK_SET); + /* Find file pointer */ + while (sdb.agent_ips[i] != NULL && i < MAX_AGENTS) { + if (strcmp(sdb.agent_ips[i], agent) == 0) { + /* Point to the beginning of the file */ + fseek(sdb.agent_fps[i], 0, SEEK_SET); *agent_id = i; - return(sdb.agent_fps[i]); + return (sdb.agent_fps[i]); } i++; } /* If here, our agent wasn't found */ - if (i == MAX_AGENTS) - { - merror("%s: Unable to open integrity file. Increase MAX_AGENTS.",ARGV0); - return(NULL); + if (i == MAX_AGENTS) { + merror("%s: Unable to open integrity file. Increase MAX_AGENTS.", ARGV0); + return (NULL); } os_strdup(agent, sdb.agent_ips[i]); - - /* Getting agent file */ - snprintf(sdb.buf, OS_FLSIZE , "%s/%s", SYSCHECK_DIR,agent); - + /* Get agent file */ + snprintf(sdb.buf, OS_FLSIZE , "%s/%s", SYSCHECK_DIR, agent); /* r+ to read and write. Do not truncate */ - sdb.agent_fps[i] = fopen(sdb.buf,"r+"); - if(!sdb.agent_fps[i]) - { - /* try opening with a w flag, file probably does not exist */ + sdb.agent_fps[i] = fopen(sdb.buf, "r+"); + if (!sdb.agent_fps[i]) { + /* Try opening with a w flag, file probably does not exist */ sdb.agent_fps[i] = fopen(sdb.buf, "w"); - if(sdb.agent_fps[i]) - { + if (sdb.agent_fps[i]) { fclose(sdb.agent_fps[i]); sdb.agent_fps[i] = fopen(sdb.buf, "r+"); } } - /* Checking again */ - if(!sdb.agent_fps[i]) - { - merror("%s: Unable to open '%s'",ARGV0, sdb.buf); + /* Check again */ + if (!sdb.agent_fps[i]) { + merror("%s: Unable to open '%s'", ARGV0, sdb.buf); free(sdb.agent_ips[i]); sdb.agent_ips[i] = NULL; - return(NULL); + return (NULL); } - - /* Returning the opened pointer (the beginning of it) */ - fseek(sdb.agent_fps[i],0, SEEK_SET); + /* Return the opened pointer (the beginning of it) */ + fseek(sdb.agent_fps[i], 0, SEEK_SET); *agent_id = i; - - /* Getting if the agent was completed */ - if(__iscompleted(agent)) - { + /* Check if the agent was completed */ + if (__iscompleted(agent)) { sdb.agent_cp[i][0] = '1'; } - return(sdb.agent_fps[i]); + return (sdb.agent_fps[i]); } - -/* DB_Search - * Search the DB for any entry related to the file being received - */ -int DB_Search(char *f_name, char *c_sum, Eventinfo *lf) +/* Search the DB for any entry related to the file being received */ +static int DB_Search(const char *f_name, const char *c_sum, Eventinfo *lf) { int p = 0; - int sn_size; + size_t sn_size; int agent_id; char *saved_sum; @@ -265,181 +256,159 @@ int DB_Search(char *f_name, char *c_sum, Eventinfo *lf) FILE *fp; + /* Expose filename variable for active response */ + os_strdup(f_name, lf->filename); + - /* Getting db pointer */ + + /* Get db pointer */ fp = DB_File(lf->location, &agent_id); - if(!fp) - { - merror("%s: Error handling integrity database.",ARGV0); - sdb.db_err++; /* Increment db error */ + if (!fp) { + merror("%s: Error handling integrity database.", ARGV0); + sdb.db_err++; lf->data = NULL; - return(0); + return (0); } - - /* Reads the integrity file and search for a possible - * entry - */ - if(fgetpos(fp, &sdb.init_pos) == -1) - { - merror("%s: Error handling integrity database (fgetpos).",ARGV0); - return(0); + /* Read the integrity file and search for a possible entry */ + if (fgetpos(fp, &sdb.init_pos) == -1) { + merror("%s: Error handling integrity database (fgetpos).", ARGV0); + return (0); } - - /* Looping the file */ - while(fgets(sdb.buf, OS_MAXSTR, fp) != NULL) - { + /* Loop over the file */ + while (fgets(sdb.buf, OS_MAXSTR, fp) != NULL) { /* Ignore blank lines and lines with a comment */ - if(sdb.buf[0] == '\n' || sdb.buf[0] == '#') - { - fgetpos(fp, &sdb.init_pos); /* getting next location */ + if (sdb.buf[0] == '\n' || sdb.buf[0] == '#') { + fgetpos(fp, &sdb.init_pos); /* Get next location */ continue; } - - /* Getting name */ + /* Get name */ saved_name = strchr(sdb.buf, ' '); - if(saved_name == NULL) - { - merror("%s: Invalid integrity message in the database.",ARGV0); - fgetpos(fp, &sdb.init_pos); /* getting next location */ + if (saved_name == NULL) { + merror("%s: Invalid integrity message in the database.", ARGV0); + fgetpos(fp, &sdb.init_pos); /* Get next location */ continue; } *saved_name = '\0'; saved_name++; - /* New format - with a timestamp */ - if(*saved_name == '!') - { + if (*saved_name == '!') { saved_name = strchr(saved_name, ' '); - if(saved_name == NULL) - { - merror("%s: Invalid integrity message in the database",ARGV0); - fgetpos(fp, &sdb.init_pos); /* getting next location */ + if (saved_name == NULL) { + merror("%s: Invalid integrity message in the database", ARGV0); + fgetpos(fp, &sdb.init_pos); /* Get next location */ continue; } saved_name++; } - - /* Removing new line from saved_name */ + /* Remove newline from saved_name */ sn_size = strlen(saved_name); sn_size -= 1; - if(saved_name[sn_size] == '\n') + if (saved_name[sn_size] == '\n') { saved_name[sn_size] = '\0'; + } - - /* If name is different, go to next one. */ - if(strcmp(f_name,saved_name) != 0) - { - /* Saving currently location */ + /* If name is different, go to next one */ + if (strcmp(f_name, saved_name) != 0) { + /* Save current location */ fgetpos(fp, &sdb.init_pos); continue; } - saved_sum = sdb.buf; - /* First three bytes are for frequency check */ - saved_sum+=3; - + saved_sum += 3; - /* checksum match, we can just return and keep going */ - if(strcmp(saved_sum, c_sum) == 0) - { + /* Checksum match, we can just return and keep going */ + if (strcmp(saved_sum, c_sum) == 0) { lf->data = NULL; - return(0); + return (0); } + + /* If we reached here, the checksum of the file has changed */ - if(saved_sum[-3] == '!') - { + if (saved_sum[-3] == '!') { p++; - if(saved_sum[-2] == '!') - { + if (saved_sum[-2] == '!') { p++; - if(saved_sum[-1] == '!') + if (saved_sum[-1] == '!') { p++; - else if(saved_sum[-1] == '?') - p+=2; + } else if (saved_sum[-1] == '?') { + p += 2; + } } } - - /* Checking the number of changes */ - if(!Config.syscheck_auto_ignore) - { + /* Check the number of changes */ + if (!Config.syscheck_auto_ignore) { sdb.syscheck_dec->id = sdb.id1; - } - else - { - switch(p) - { + } else { + switch (p) { case 0: - sdb.syscheck_dec->id = sdb.id1; - break; + sdb.syscheck_dec->id = sdb.id1; + break; case 1: - sdb.syscheck_dec->id = sdb.id2; - break; + sdb.syscheck_dec->id = sdb.id2; + break; case 2: - sdb.syscheck_dec->id = sdb.id3; - break; + sdb.syscheck_dec->id = sdb.id3; + break; default: - lf->data = NULL; - return(0); - break; + lf->data = NULL; + return (0); + break; } } + /* Add new checksum to the database */ + /* Commenting the file entry and adding a new one later */ + if (fsetpos(fp, &sdb.init_pos)) { + merror("%s: Error handling integrity database (fsetpos).", ARGV0); + return (0); + } + fputc('#', fp); - /* Adding new checksum to the database */ - /* Commenting the file entry and adding a new one latter */ - fsetpos(fp, &sdb.init_pos); - fputc('#',fp); - - - /* Adding the new entry at the end of the file */ + /* Add the new entry at the end of the file */ fseek(fp, 0, SEEK_END); - fprintf(fp,"%c%c%c%s !%d %s\n", + fprintf(fp, "%c%c%c%s !%ld %s\n", '!', - p >= 1? '!' : '+', - p == 2? '!' : (p > 2)?'?':'+', + p >= 1 ? '!' : '+', + p == 2 ? '!' : (p > 2) ? '?' : '+', c_sum, - lf->time, + (long int)lf->time, f_name); fflush(fp); - /* File deleted */ - if(c_sum[0] == '-' && c_sum[1] == '1') - { + if (c_sum[0] == '-' && c_sum[1] == '1') { sdb.syscheck_dec->id = sdb.idd; snprintf(sdb.comment, OS_MAXSTR, - "File '%.756s' was deleted. Unable to retrieve " - "checksum.", f_name); + "File '%.756s' was deleted. Unable to retrieve " + "checksum.", f_name); } /* If file was re-added, do not compare changes */ - else if(saved_sum[0] == '-' && saved_sum[1] == '1') - { + else if (saved_sum[0] == '-' && saved_sum[1] == '1') { sdb.syscheck_dec->id = sdb.idn; snprintf(sdb.comment, OS_MAXSTR, "File '%.756s' was re-added.", f_name); } - else - { + else { int oldperm = 0, newperm = 0; - /* Providing more info about the file change */ - char *oldsize = NULL, *newsize = NULL; + /* Provide more info about the file change */ + const char *oldsize = NULL, *newsize = NULL; char *olduid = NULL, *newuid = NULL; char *c_oldperm = NULL, *c_newperm = NULL; char *oldgid = NULL, *newgid = NULL; @@ -453,8 +422,7 @@ int DB_Search(char *f_name, char *c_sum, Eventinfo *lf) c_newperm = strchr(c_sum, ':'); /* Get old/new permissions */ - if(c_oldperm && c_newperm) - { + if (c_oldperm && c_newperm) { *c_oldperm = '\0'; c_oldperm++; @@ -465,47 +433,38 @@ int DB_Search(char *f_name, char *c_sum, Eventinfo *lf) olduid = strchr(c_oldperm, ':'); newuid = strchr(c_newperm, ':'); - if(olduid && newuid) - { + if (olduid && newuid) { *olduid = '\0'; *newuid = '\0'; - olduid++; newuid++; oldgid = strchr(olduid, ':'); newgid = strchr(newuid, ':'); - if(oldgid && newgid) - { + if (oldgid && newgid) { *oldgid = '\0'; *newgid = '\0'; - oldgid++; newgid++; - - /* Getting md5 */ + /* Get MD5 */ oldmd5 = strchr(oldgid, ':'); newmd5 = strchr(newgid, ':'); - if(oldmd5 && newmd5) - { + if (oldmd5 && newmd5) { *oldmd5 = '\0'; *newmd5 = '\0'; - oldmd5++; newmd5++; - /* getting sha1 */ + /* Get SHA-1 */ oldsha1 = strchr(oldmd5, ':'); newsha1 = strchr(newmd5, ':'); - if(oldsha1 && newsha1) - { + if (oldsha1 && newsha1) { *oldsha1 = '\0'; *newsha1 = '\0'; - oldsha1++; newsha1++; } @@ -514,290 +473,253 @@ int DB_Search(char *f_name, char *c_sum, Eventinfo *lf) } } - /* Getting integer values */ - if(c_newperm && c_oldperm) - { + /* Get integer values */ + if (c_newperm && c_oldperm) { newperm = atoi(c_newperm); oldperm = atoi(c_oldperm); } - /* Generating size message */ - if(!oldsize || !newsize || strcmp(oldsize, newsize) == 0) - { + /* Generate size message */ + if (!oldsize || !newsize || strcmp(oldsize, newsize) == 0) { sdb.size[0] = '\0'; - } - else - { + } else { snprintf(sdb.size, OS_FLSIZE, - "Size changed from '%s' to '%s'\n", - oldsize, newsize); + "Size changed from '%s' to '%s'\n", + oldsize, newsize); os_strdup(oldsize, lf->size_before); os_strdup(newsize, lf->size_after); } /* Permission message */ - if(oldperm == newperm) - { + if (oldperm == newperm) { sdb.perm[0] = '\0'; - } - else if(oldperm > 0 && newperm > 0) - { - - snprintf(sdb.perm, OS_FLSIZE, "Permissions changed from " - "'%c%c%c%c%c%c%c%c%c' " - "to '%c%c%c%c%c%c%c%c%c'\n", - (oldperm & S_IRUSR)? 'r' : '-', - (oldperm & S_IWUSR)? 'w' : '-', - - (oldperm & S_ISUID)? 's' : - (oldperm & S_IXUSR)? 'x' : '-', - - (oldperm & S_IRGRP)? 'r' : '-', - (oldperm & S_IWGRP)? 'w' : '-', - - (oldperm & S_ISGID)? 's' : - (oldperm & S_IXGRP)? 'x' : '-', + } else if (oldperm > 0 && newperm > 0) { + char opstr[10]; + char npstr[10]; - (oldperm & S_IROTH)? 'r' : '-', - (oldperm & S_IWOTH)? 'w' : '-', + strncpy(opstr, agent_file_perm(c_oldperm), sizeof(opstr) - 1); + strncpy(npstr, agent_file_perm(c_newperm), sizeof(npstr) - 1); - (oldperm & S_ISVTX)? 't' : - (oldperm & S_IXOTH)? 'x' : '-', - - - - (newperm & S_IRUSR)? 'r' : '-', - (newperm & S_IWUSR)? 'w' : '-', - - (newperm & S_ISUID)? 's' : - (newperm & S_IXUSR)? 'x' : '-', - - - (newperm & S_IRGRP)? 'r' : '-', - (newperm & S_IWGRP)? 'w' : '-', - - (newperm & S_ISGID)? 's' : - (newperm & S_IXGRP)? 'x' : '-', - - (newperm & S_IROTH)? 'r' : '-', - (newperm & S_IWOTH)? 'w' : '-', - - (newperm & S_ISVTX)? 't' : - (newperm & S_IXOTH)? 'x' : '-'); + snprintf(sdb.perm, OS_FLSIZE, "Permissions changed from " + "'%9.9s' to '%9.9s'\n", opstr, npstr); lf->perm_before = oldperm; lf->perm_after = newperm; } /* Ownership message */ - if(!newuid || !olduid || strcmp(newuid, olduid) == 0) - { + if (!newuid || !olduid || strcmp(newuid, olduid) == 0) { sdb.owner[0] = '\0'; - } - else - { + } else { snprintf(sdb.owner, OS_FLSIZE, "Ownership was '%s', " - "now it is '%s'\n", - olduid, newuid); + "now it is '%s'\n", + olduid, newuid); os_strdup(olduid, lf->owner_before); os_strdup(newuid, lf->owner_after); } - /* group ownership message */ - if(!newgid || !oldgid || strcmp(newgid, oldgid) == 0) - { + /* Group ownership message */ + if (!newgid || !oldgid || strcmp(newgid, oldgid) == 0) { sdb.gowner[0] = '\0'; - } - else - { - snprintf(sdb.gowner, OS_FLSIZE,"Group ownership was '%s', " - "now it is '%s'\n", - oldgid, newgid); + } else { + snprintf(sdb.gowner, OS_FLSIZE, "Group ownership was '%s', " + "now it is '%s'\n", + oldgid, newgid); os_strdup(oldgid, lf->gowner_before); os_strdup(newgid, lf->gowner_after); } - /* md5 message */ - if(!newmd5 || !oldmd5 || strcmp(newmd5, oldmd5) == 0) - { + /* MD5 message */ + if (!newmd5 || !oldmd5 || strcmp(newmd5, oldmd5) == 0) { sdb.md5[0] = '\0'; - } - else - { + } else { snprintf(sdb.md5, OS_FLSIZE, "Old md5sum was: '%s'\n" - "New md5sum is : '%s'\n", - oldmd5, newmd5); + "New md5sum is : '%s'\n", + oldmd5, newmd5); os_strdup(oldmd5, lf->md5_before); os_strdup(newmd5, lf->md5_after); } - /* sha1 */ - if(!newsha1 || !oldsha1 || strcmp(newsha1, oldsha1) == 0) - { + /* SHA-1 message */ + if (!newsha1 || !oldsha1 || strcmp(newsha1, oldsha1) == 0) { sdb.sha1[0] = '\0'; - } - else - { + } else { snprintf(sdb.sha1, OS_FLSIZE, "Old sha1sum was: '%s'\n" - "New sha1sum is : '%s'\n", - oldsha1, newsha1); + "New sha1sum is : '%s'\n", + oldsha1, newsha1); os_strdup(oldsha1, lf->sha1_before); os_strdup(newsha1, lf->sha1_after); } - os_strdup(f_name, lf->filename); - /* Provide information about the file */ snprintf(sdb.comment, OS_MAXSTR, "Integrity checksum changed for: " - "'%.756s'\n" - "%s" - "%s" - "%s" - "%s" - "%s" - "%s" - "%s%s", - f_name, - sdb.size, - sdb.perm, - sdb.owner, - sdb.gowner, - sdb.md5, - sdb.sha1, - lf->data == NULL?"":"What changed:\n", - lf->data == NULL?"":lf->data + "'%.756s'\n" + "%s" + "%s" + "%s" + "%s" + "%s" + "%s" + "%s%s", + f_name, + sdb.size, + sdb.perm, + sdb.owner, + sdb.gowner, + sdb.md5, + sdb.sha1, + lf->data == NULL ? "" : "What changed:\n", + lf->data == NULL ? "" : lf->data ); } - - /* Creating a new log message */ + /* Create a new log message */ free(lf->full_log); os_strdup(sdb.comment, lf->full_log); lf->log = lf->full_log; lf->data = NULL; - - /* Setting decoder */ + /* Set decoder */ lf->decoder_info = sdb.syscheck_dec; + return (1); - return(1); + } /* Continue */ - } /* continuiing... */ - - - /* If we reach here, this file is not present on our database */ + /* If we reach here, this file is not present in our database */ fseek(fp, 0, SEEK_END); - - fprintf(fp,"+++%s !%d %s\n", c_sum, lf->time, f_name); - + fprintf(fp, "+++%s !%ld %s\n", c_sum, (long int)lf->time, f_name); fflush(fp); /* Alert if configured to notify on new files */ - if((Config.syscheck_alert_new == 1) && (DB_IsCompleted(agent_id))) - { + /* TODO: debugging this - Scott */ + /* if ((Config.syscheck_alert_new == 1) && (DB_IsCompleted(agent_id))) { */ + if (Config.syscheck_alert_new == 1) { sdb.syscheck_dec->id = sdb.idn; /* New file message */ snprintf(sdb.comment, OS_MAXSTR, - "New file '%.756s' " - "added to the file system.", f_name); + "New file '%.756s' " + "added to the file system.", f_name); - /* Creating a new log message */ + /* Create a new log message */ free(lf->full_log); os_strdup(sdb.comment, lf->full_log); lf->log = lf->full_log; - - /* Setting decoder */ + /* Set decoder */ lf->decoder_info = sdb.syscheck_dec; lf->data = NULL; - return(1); + return (1); } lf->data = NULL; - return(0); + return (0); } - /* Special decoder for syscheck * Not using the default decoding lib for simplicity * and to be less resource intensive */ int DecodeSyscheck(Eventinfo *lf) { - char *c_sum; + const char *c_sum; char *f_name; +#ifdef SQLITE_ENABLED + char *p; + char stmt[OS_MAXSTR + 1]; + sqlite3_stmt *res; + int error = 0; + int rec_count = 0; + const char *tail; +#endif // SQLITE_ENABLED /* Every syscheck message must be in the following format: * checksum filename */ f_name = strchr(lf->log, ' '); - if(f_name == NULL) - { + if (f_name == NULL) { /* If we don't have a valid syscheck message, it may be - * a database completed message. + * a database completed message */ - if(strcmp(lf->log, HC_SK_DB_COMPLETED) == 0) - { + if (strcmp(lf->log, HC_SK_DB_COMPLETED) == 0) { DB_SetCompleted(lf); - return(0); + return (0); } merror(SK_INV_MSG, ARGV0); - return(0); + return (0); } - - /* Zeroing to get the check sum */ + /* Zero to get the check sum */ *f_name = '\0'; f_name++; - - /* Getting diff. */ + /* Get diff */ lf->data = strchr(f_name, '\n'); - if(lf->data) - { + if (lf->data) { *lf->data = '\0'; lf->data++; - } - else - { + } else { lf->data = NULL; } - - - /* Checking if file is supposed to be ignored */ - if(Config.syscheck_ignore) - { + /* Check if file is supposed to be ignored */ + if (Config.syscheck_ignore) { char **ff_ig = Config.syscheck_ignore; - while(*ff_ig) - { - if(strncasecmp(*ff_ig, f_name, strlen(*ff_ig)) == 0) - { + while (*ff_ig) { + if (strncasecmp(*ff_ig, f_name, strlen(*ff_ig)) == 0) { lf->data = NULL; - return(0); + return (0); } ff_ig++; } } - /* Checksum is at the beginning of the log */ c_sum = lf->log; + /* Extract the MD5 hash and search for it in the allowlist + * Sample message: + * 0:0:0:0:78f5c869675b1d09ddad870adad073f9:bd6c8d7a58b462aac86475e59af0e22954039c50 + */ +#ifdef SQLITE_ENABLED + if (Config.md5_allowlist) { + extern sqlite3 *conn; + if ((p = extract_token(c_sum, ":", 4))) { + if (!validate_md5(p)) { /* Never trust input from other origin */ + merror("%s: Not a valid MD5 hash: '%s'", ARGV0, p); + return(0); + } + debug1("%s: Checking MD5 '%s' in %s", ARGV0, p, Config.md5_allowlist); + sprintf(stmt, "select md5sum from files where md5sum = \"%s\"", p); + error = sqlite3_prepare_v2(conn, stmt, 1000, &res, &tail); + if (error == SQLITE_OK) { + while (sqlite3_step(res) == SQLITE_ROW) { + rec_count++; + } + if (rec_count) { + sqlite3_finalize(res); + //sqlite3_close(conn); + merror(MD5_NOT_CHECKED, ARGV0, p); + return(0); + } + } + sqlite3_finalize(res); + } + } +#endif + - /* Searching for file changes */ - return(DB_Search(f_name, c_sum, lf)); + /* Search for file changes */ + return (DB_Search(f_name, c_sum, lf)); } -/* EOF */