From 3ebc3b4e073c235589307f2ff03230fdd0e21ca8 Mon Sep 17 00:00:00 2001 From: calve Date: Mon, 14 Mar 2016 19:20:50 +0100 Subject: [PATCH 01/13] Stubs --- src/analysisd/decoders/syscheck.c | 17 ++++++++++++++++- src/analysisd/rules.h | 1 + src/headers/defs.h | 1 + src/headers/mq_op.h | 1 + 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/analysisd/decoders/syscheck.c b/src/analysisd/decoders/syscheck.c index 10c8432eb..7c9b3b3a7 100644 --- a/src/analysisd/decoders/syscheck.c +++ b/src/analysisd/decoders/syscheck.c @@ -38,6 +38,7 @@ typedef struct __sdb { int id3; int idn; int idd; + int id_allowed; /* Syscheck rule */ OSDecoderInfo *syscheck_dec; @@ -87,6 +88,7 @@ void SyscheckInit() sdb.id3 = getDecoderfromlist(SYSCHECK_MOD3); sdb.idn = getDecoderfromlist(SYSCHECK_NEW); sdb.idd = getDecoderfromlist(SYSCHECK_DEL); + sdb.id_allowed = getDecoderfromlist(SYSCHECK_ALLOWED); debug1("%s: SyscheckInit completed.", ARGV0); return; @@ -124,6 +126,12 @@ static int __iscompleted(const char *agent) return (0); } + +static int consumeAllow(const char *filename){ + verbose("is %s allowed ?\n", filename); + return 0; +} + /* Set the database of a specific agent as completed */ static void DB_SetCompleted(const Eventinfo *lf) { @@ -619,6 +627,7 @@ int DecodeSyscheck(Eventinfo *lf) { const char *c_sum; char *f_name; + int status; /* Every syscheck message must be in the following format: * checksum filename @@ -668,6 +677,12 @@ int DecodeSyscheck(Eventinfo *lf) c_sum = lf->log; /* Search for file changes */ - return (DB_Search(f_name, c_sum, lf)); + status = DB_Search(f_name, c_sum, lf); + + /* Check if the file have been allowed to change */ + if (consumeAllow(f_name)){ + lf->decoder_info = sdb.id_allowed; + } + return status; } diff --git a/src/analysisd/rules.h b/src/analysisd/rules.h index 2a9a9c972..ec2ee799d 100644 --- a/src/analysisd/rules.h +++ b/src/analysisd/rules.h @@ -232,6 +232,7 @@ int _setlevels(RuleNode *node, int nnode); #define SYSCHECK_MOD3 "syscheck_integrity_changed_3rd" #define SYSCHECK_NEW "syscheck_new_entry" #define SYSCHECK_DEL "syscheck_deleted" +#define SYSCHECK_ALLOWED "syscheck_allowed" /* Global variables */ extern int _max_freq; diff --git a/src/headers/defs.h b/src/headers/defs.h index d2b1d5e13..596377b50 100644 --- a/src/headers/defs.h +++ b/src/headers/defs.h @@ -126,6 +126,7 @@ published by the Free Software Foundation. For more details, go to \n\ /* Syscheck data */ #define SYSCHECK "syscheck" #define SYSCHECK_REG "syscheck-registry" +#define ALLOWCHANGE "syscheck-allowchange" /* Rule path */ #define RULEPATH "/rules" diff --git a/src/headers/mq_op.h b/src/headers/mq_op.h index b425c53c1..af04b20dc 100644 --- a/src/headers/mq_op.h +++ b/src/headers/mq_op.h @@ -17,6 +17,7 @@ #define SECURE_MQ '4' #define SYSCHECK_MQ '8' #define ROOTCHECK_MQ '9' +#define ALLOWCHANGE_MQ 'c' /* Queues for additional log types */ #define MYSQL_MQ 'a' From e171885a9937570a536acd7d88f827273d47b3ef Mon Sep 17 00:00:00 2001 From: calve Date: Mon, 14 Mar 2016 19:21:03 +0100 Subject: [PATCH 02/13] Non working allow change command --- src/syscheckd/syscheck.c | 67 ++++++++++++++++++++++++++++++++++------ 1 file changed, 57 insertions(+), 10 deletions(-) diff --git a/src/syscheckd/syscheck.c b/src/syscheckd/syscheck.c index 6c07aaa0e..df30f2586 100644 --- a/src/syscheckd/syscheck.c +++ b/src/syscheckd/syscheck.c @@ -66,6 +66,23 @@ static void read_internal(int debug_level) return; } +/* Send a message to the monitor that we allow one change events on + this file until timestamp + */ +static int allowChange(char* filename, time_t timestamp) +{ + + if ((syscheck.queue = StartMQ(DEFAULTQPATH, WRITE)) < 0) { + ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQPATH); + } + sleep(1); + if (SendMSG(syscheck.queue, filename, SYSCHECK, ALLOWCHANGE_MQ) < 0) { + merror(QUEUE_SEND, ARGV0); + } + printf("send_allowchange_msg: %s to %s\n", filename, DEFAULTQPATH); + return 0; +} + #ifdef WIN32 /* syscheck main for Windows */ int Start_win32_Syscheck() @@ -167,15 +184,17 @@ int Start_win32_Syscheck() static void help_syscheckd() { print_header(); - print_out(" %s: -[Vhdtf] [-c config]", ARGV0); - print_out(" -V Version and license message"); - print_out(" -h This help message"); - print_out(" -d Execute in debug mode. This parameter"); - print_out(" can be specified multiple times"); - print_out(" to increase the debug level."); - print_out(" -t Test configuration"); - print_out(" -f Run in foreground"); - print_out(" -c Configuration file to use (default: %s)", DEFAULTCPATH); + print_out(" %s: -[Vhdtf] [-c config] [-a filename -u timestamp]", ARGV0); + print_out(" -V Version and license message"); + print_out(" -h This help message"); + print_out(" -d Execute in debug mode. This parameter"); + print_out(" can be specified multiple times"); + print_out(" to increase the debug level."); + print_out(" -t Test configuration"); + print_out(" -f Run in foreground"); + print_out(" -c Configuration file to use (default: %s)", DEFAULTCPATH); + print_out(" -a Allow changes on filename"); + print_out(" -u Allow changes until timestamp"); print_out(" "); exit(1); } @@ -187,12 +206,15 @@ int main(int argc, char **argv) int c, r; int debug_level = 0; int test_config = 0, run_foreground = 0; + int allow_change = 0; const char *cfg = DEFAULTCPATH; + char *allow_filename = NULL; + time_t allow_timestamp = 0; /* Set the name */ OS_SetName(ARGV0); - while ((c = getopt(argc, argv, "Vtdhfc:")) != -1) { + while ((c = getopt(argc, argv, "Vtdhfc:a:u:")) != -1) { switch (c) { case 'V': print_version(); @@ -213,6 +235,20 @@ int main(int argc, char **argv) } cfg = optarg; break; + case 'a': + if (!optarg) { + ErrorExit("%s: -a needs a filename", ARGV0); + } + allow_filename = optarg; + allow_change = 1; + break; + case 'u': + if (!optarg) { + ErrorExit("%s: -w needs a timestamp", ARGV0); + } + allow_timestamp = atoi(optarg); + allow_change = 1; + break; case 't': test_config = 1; break; @@ -252,6 +288,17 @@ int main(int argc, char **argv) } } + + if (allow_change){ + if (allow_filename && allow_timestamp != 0) { + allowChange(allow_filename, allow_timestamp); + exit(0); + } else { + merror("%s: WARN: Missing parameter for allow change", ARGV0); + exit(1); + } + } + /* Rootcheck config */ if (rootcheck_init(test_config) == 0) { syscheck.rootcheck = 1; From ced08cebaba0ce2e5cd943d1278ad39ce1b33cd2 Mon Sep 17 00:00:00 2001 From: calve Date: Mon, 14 Mar 2016 19:36:06 +0100 Subject: [PATCH 03/13] Fix segfault --- src/syscheckd/syscheck.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/syscheckd/syscheck.c b/src/syscheckd/syscheck.c index df30f2586..bf6fe6b97 100644 --- a/src/syscheckd/syscheck.c +++ b/src/syscheckd/syscheck.c @@ -407,4 +407,3 @@ int main(int argc, char **argv) } #endif /* !WIN32 */ - From 6674edf4a0b67dfe73c8fc258da44bae5cb81722 Mon Sep 17 00:00:00 2001 From: calve Date: Mon, 14 Mar 2016 20:23:49 +0100 Subject: [PATCH 04/13] AllowChange events communication ! --- src/analysisd/analysisd.c | 9 +++++++++ src/analysisd/decoders/syscheck.c | 28 +++++++++++++++++++++++++++- src/syscheckd/syscheck.c | 7 ++++--- 3 files changed, 40 insertions(+), 4 deletions(-) diff --git a/src/analysisd/analysisd.c b/src/analysisd/analysisd.c index d63cddf0f..59d84c09d 100644 --- a/src/analysisd/analysisd.c +++ b/src/analysisd/analysisd.c @@ -755,6 +755,15 @@ void OS_ReadMSG_analysisd(int m_queue) lf->size = strlen(lf->log); } + /* Allowchange event decoding */ + else if (msg[0] == ALLOWCHANGE_MQ) { + if (!DecodeAllowchange(lf)) { + /* We don't process allowchange events further */ + goto CLMEM; + } + lf->size = strlen(lf->log); + } + /* Host information special decoder */ else if (msg[0] == HOSTINFO_MQ) { if (!DecodeHostinfo(lf)) { diff --git a/src/analysisd/decoders/syscheck.c b/src/analysisd/decoders/syscheck.c index 7c9b3b3a7..5207f2d4d 100644 --- a/src/analysisd/decoders/syscheck.c +++ b/src/analysisd/decoders/syscheck.c @@ -128,7 +128,7 @@ static int __iscompleted(const char *agent) static int consumeAllow(const char *filename){ - verbose("is %s allowed ?\n", filename); + verbose("is %s allowed ?", filename); return 0; } @@ -686,3 +686,29 @@ int DecodeSyscheck(Eventinfo *lf) return status; } +/* A special decoder to read an AllowChange event */ +int DecodeAllowchange(Eventinfo *lf) +{ + int status; + int timestamp; + char *f_name; + + verbose("incoming %s", lf->log); + /* Every allow change message must be in the following format: + * timestamp filename + */ + f_name = strchr(lf->log, ' '); + if (f_name == NULL) { + merror(SK_INV_MSG, ARGV0); + return (0); + } + + /* Zero to get the timestamp */ + *f_name = '\0'; + f_name++; + + /* Get timestamp */ + timestamp = atoi(lf->log); + verbose("successfully read allowchange for %s until %d from %s", f_name, timestamp, lf->hostname); + return timestamp; +} diff --git a/src/syscheckd/syscheck.c b/src/syscheckd/syscheck.c index bf6fe6b97..9695a231d 100644 --- a/src/syscheckd/syscheck.c +++ b/src/syscheckd/syscheck.c @@ -71,15 +71,16 @@ static void read_internal(int debug_level) */ static int allowChange(char* filename, time_t timestamp) { - + char msg[1024*2]; + sprintf(msg, "%d %s", timestamp, filename); if ((syscheck.queue = StartMQ(DEFAULTQPATH, WRITE)) < 0) { ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQPATH); } sleep(1); - if (SendMSG(syscheck.queue, filename, SYSCHECK, ALLOWCHANGE_MQ) < 0) { + if (SendMSG(syscheck.queue, msg, ALLOWCHANGE, ALLOWCHANGE_MQ) < 0) { merror(QUEUE_SEND, ARGV0); } - printf("send_allowchange_msg: %s to %s\n", filename, DEFAULTQPATH); + printf("send_allowchange_msg: %s to %s\n", msg, DEFAULTQPATH); return 0; } From 07e858b471dc2f805eb1890e32f394abc9c8cfb9 Mon Sep 17 00:00:00 2001 From: calve Date: Tue, 15 Mar 2016 00:34:18 +0100 Subject: [PATCH 05/13] Produce and consume allow changes events --- src/Makefile | 1 + src/analysisd/decoders/syscheck-allow.c | 110 ++++++++++++++++++++++++ src/analysisd/decoders/syscheck.c | 37 +------- src/headers/defs.h | 3 + 4 files changed, 117 insertions(+), 34 deletions(-) create mode 100644 src/analysisd/decoders/syscheck-allow.c diff --git a/src/Makefile b/src/Makefile index 9b308fa63..87ea73cb8 100644 --- a/src/Makefile +++ b/src/Makefile @@ -379,6 +379,7 @@ install-common: build install -d -m 0770 -o ${OSSEC_USER} -g ${OSSEC_GROUP} ${PREFIX}/queue/alerts install -d -m 0750 -o ${OSSEC_USER} -g ${OSSEC_GROUP} ${PREFIX}/queue/ossec install -d -m 0750 -o ${OSSEC_USER} -g ${OSSEC_GROUP} ${PREFIX}/queue/syscheck + install -d -m 0750 -o ${OSSEC_USER} -g ${OSSEC_GROUP} ${PREFIX}/queue/syscheck-allowchange install -d -m 0750 -o ${OSSEC_USER} -g ${OSSEC_GROUP} ${PREFIX}/queue/diff install -d -m 0550 -o root -g ${OSSEC_GROUP} ${PREFIX}/etc diff --git a/src/analysisd/decoders/syscheck-allow.c b/src/analysisd/decoders/syscheck-allow.c new file mode 100644 index 000000000..c401a7fe4 --- /dev/null +++ b/src/analysisd/decoders/syscheck-allow.c @@ -0,0 +1,110 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All right reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +/* Syscheck decoder */ + +#include "eventinfo.h" +#include "os_regex/os_regex.h" +#include "config.h" +#include "decoder.h" + +/* We write allowed filenames in a database located at /queue/syscheck-allowchange/ + * Each line represents an entry which is structured as + * + * where is either the char '0' or '1', + * and indicate whereas this entry have already been consummed. + */ + + +/* Determine if this filename have at least one allowed change, and + consumme it */ +static int consumeAllowchange(const char *filename, Eventinfo *lf){ + FILE *db_file; + char db_filename[OS_FLSIZE]; + char line[OS_FLSIZE*2]; + int allowed = 0; + time_t current; + snprintf(db_filename, OS_FLSIZE , "%s/%s", ALLOWCHANGE_DIR, lf->hostname); + db_file = fopen(db_filename, "r+"); + rewind(db_file); + if (!db_file) { + verbose("failed to open %s", db_filename); + return 0; + } + current = time(0); + + + while (fgets(line, OS_FLSIZE*2, db_file) != NULL) { + /* Attempt to parse the line */ + int validity; + time_t until; + char path[OS_FLSIZE]; + sscanf(line, "%d %d %s", &validity, &until, path); + if (validity) { + if (until > current) { + if (strcmp(path, filename) == 0){ + int len = strlen(line); + /* Rewrite current entry */ + fseek(db_file, -len, SEEK_CUR); + fprintf(db_file, "0"); + fclose(db_file); + return until; + } + } + } + } + + fclose(db_file); + return allowed; +} + +/* Save an Allowchange record in our "database" +*/ +static int produceAllowchange(time_t timestamp, const char *filename, Eventinfo *lf){ + FILE *db_file; + char db_filename[OS_FLSIZE]; + snprintf(db_filename, OS_FLSIZE , "%s/%s", ALLOWCHANGE_DIR, lf->hostname); + verbose("opening %s", db_filename); + db_file = fopen(db_filename, "a"); + if (db_file) { + fprintf(db_file, "%d %d %s\n", 1, timestamp, filename); + fclose(db_file); + return timestamp; + } + verbose("failed to write to %s", db_filename); + return 0; +} + + + +/* A special decoder to read an AllowChange event */ +int DecodeAllowchange(Eventinfo *lf) +{ + int status; + time_t timestamp; + char *f_name; + + /* Allowchange messages must be in the following format: + * timestamp filename + */ + f_name = strchr(lf->log, ' '); + if (f_name == NULL) { + merror(SK_INV_MSG, ARGV0); + return (0); + } + + /* Zero to get the timestamp */ + *f_name = '\0'; + f_name++; + + /* Get timestamp */ + timestamp = atoi(lf->log); + produceAllowchange(timestamp, f_name, lf); + return timestamp; +} diff --git a/src/analysisd/decoders/syscheck.c b/src/analysisd/decoders/syscheck.c index 5207f2d4d..70f0d860d 100644 --- a/src/analysisd/decoders/syscheck.c +++ b/src/analysisd/decoders/syscheck.c @@ -14,6 +14,7 @@ #include "config.h" #include "alerts/alerts.h" #include "decoder.h" +#include "syscheck-allow.c" /* I don't like this either */ typedef struct __sdb { char buf[OS_MAXSTR + 1]; @@ -127,11 +128,6 @@ static int __iscompleted(const char *agent) } -static int consumeAllow(const char *filename){ - verbose("is %s allowed ?", filename); - return 0; -} - /* Set the database of a specific agent as completed */ static void DB_SetCompleted(const Eventinfo *lf) { @@ -184,7 +180,7 @@ static FILE *DB_File(const char *agent, int *agent_id) /* Get agent file */ snprintf(sdb.buf, OS_FLSIZE , "%s/%s", SYSCHECK_DIR, agent); - + verbose("opening %s", sdb.buf); /* r+ to read and write. Do not truncate */ sdb.agent_fps[i] = fopen(sdb.buf, "r+"); if (!sdb.agent_fps[i]) { @@ -680,35 +676,8 @@ int DecodeSyscheck(Eventinfo *lf) status = DB_Search(f_name, c_sum, lf); /* Check if the file have been allowed to change */ - if (consumeAllow(f_name)){ + if (consumeAllowchange(f_name, lf)){ lf->decoder_info = sdb.id_allowed; } return status; } - -/* A special decoder to read an AllowChange event */ -int DecodeAllowchange(Eventinfo *lf) -{ - int status; - int timestamp; - char *f_name; - - verbose("incoming %s", lf->log); - /* Every allow change message must be in the following format: - * timestamp filename - */ - f_name = strchr(lf->log, ' '); - if (f_name == NULL) { - merror(SK_INV_MSG, ARGV0); - return (0); - } - - /* Zero to get the timestamp */ - *f_name = '\0'; - f_name++; - - /* Get timestamp */ - timestamp = atoi(lf->log); - verbose("successfully read allowchange for %s until %d from %s", f_name, timestamp, lf->hostname); - return timestamp; -} diff --git a/src/headers/defs.h b/src/headers/defs.h index 596377b50..6440a1739 100644 --- a/src/headers/defs.h +++ b/src/headers/defs.h @@ -117,6 +117,9 @@ published by the Free Software Foundation. For more details, go to \n\ /* Rootcheck directory */ #define ROOTCHECK_DIR "/queue/rootcheck" +/* Allowchange directory */ +#define ALLOWCHANGE_DIR "/queue/syscheck-allowchange" + /* Diff queue */ #define DIFF_DIR "/queue/diff" #define DIFF_DIR_PATH DEFAULTDIR DIFF_DIR From db43bb2b6ef7352ffa4386da691f3c7b6b1d8352 Mon Sep 17 00:00:00 2001 From: calve Date: Thu, 24 Mar 2016 19:36:57 +0100 Subject: [PATCH 06/13] Set SYSCHECK_ALLOWED decoder --- etc/rules/ossec_rules.xml | 7 +++++++ src/analysisd/decoders/decode-xml.c | 1 + src/analysisd/decoders/syscheck.c | 5 ++--- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/etc/rules/ossec_rules.xml b/etc/rules/ossec_rules.xml index fa2c7da55..ab2adb115 100755 --- a/etc/rules/ossec_rules.xml +++ b/etc/rules/ossec_rules.xml @@ -211,6 +211,13 @@ syscheck,agentless + + ossec + syscheck_allowed + Integrity checksum changed (allowed). + syscheck, + + ossec diff --git a/src/analysisd/decoders/decode-xml.c b/src/analysisd/decoders/decode-xml.c index 6e99c330e..5cd89801e 100644 --- a/src/analysisd/decoders/decode-xml.c +++ b/src/analysisd/decoders/decode-xml.c @@ -691,6 +691,7 @@ int SetDecodeXML() addDecoder2list(SYSCHECK_MOD); addDecoder2list(SYSCHECK_MOD2); addDecoder2list(SYSCHECK_MOD3); + addDecoder2list(SYSCHECK_ALLOWED); addDecoder2list(SYSCHECK_NEW); addDecoder2list(SYSCHECK_DEL); addDecoder2list(HOSTINFO_NEW); diff --git a/src/analysisd/decoders/syscheck.c b/src/analysisd/decoders/syscheck.c index 70f0d860d..faa7cc4d9 100644 --- a/src/analysisd/decoders/syscheck.c +++ b/src/analysisd/decoders/syscheck.c @@ -39,7 +39,6 @@ typedef struct __sdb { int id3; int idn; int idd; - int id_allowed; /* Syscheck rule */ OSDecoderInfo *syscheck_dec; @@ -89,7 +88,6 @@ void SyscheckInit() sdb.id3 = getDecoderfromlist(SYSCHECK_MOD3); sdb.idn = getDecoderfromlist(SYSCHECK_NEW); sdb.idd = getDecoderfromlist(SYSCHECK_DEL); - sdb.id_allowed = getDecoderfromlist(SYSCHECK_ALLOWED); debug1("%s: SyscheckInit completed.", ARGV0); return; @@ -677,7 +675,8 @@ int DecodeSyscheck(Eventinfo *lf) /* Check if the file have been allowed to change */ if (consumeAllowchange(f_name, lf)){ - lf->decoder_info = sdb.id_allowed; + lf->decoder_info->id = getDecoderfromlist(SYSCHECK_ALLOWED); + lf->decoder_info->name = SYSCHECK_ALLOWED; } return status; } From 991836f207fb648846fef15d38fff21ee2816f7f Mon Sep 17 00:00:00 2001 From: calve Date: Thu, 24 Mar 2016 20:29:57 +0100 Subject: [PATCH 07/13] Create the ALLOWCHANGE file if not exists --- src/analysisd/decoders/syscheck-allow.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/analysisd/decoders/syscheck-allow.c b/src/analysisd/decoders/syscheck-allow.c index c401a7fe4..b39625ccd 100644 --- a/src/analysisd/decoders/syscheck-allow.c +++ b/src/analysisd/decoders/syscheck-allow.c @@ -32,14 +32,16 @@ static int consumeAllowchange(const char *filename, Eventinfo *lf){ time_t current; snprintf(db_filename, OS_FLSIZE , "%s/%s", ALLOWCHANGE_DIR, lf->hostname); db_file = fopen(db_filename, "r+"); - rewind(db_file); if (!db_file) { - verbose("failed to open %s", db_filename); - return 0; + db_file = fopen(db_filename, "w+"); + if (!db_file) { + verbose("failed to open %s", db_filename); + return 0; + } } + rewind(db_file); current = time(0); - while (fgets(line, OS_FLSIZE*2, db_file) != NULL) { /* Attempt to parse the line */ int validity; From f6d8e9b4e9226c8b074d7c40048abc60d0fd3eaa Mon Sep 17 00:00:00 2001 From: calve Date: Thu, 24 Mar 2016 20:31:11 +0100 Subject: [PATCH 08/13] Raise rule 556 level to write an alert in alerts.log --- etc/rules/ossec_rules.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/rules/ossec_rules.xml b/etc/rules/ossec_rules.xml index ab2adb115..2c2ce565a 100755 --- a/etc/rules/ossec_rules.xml +++ b/etc/rules/ossec_rules.xml @@ -211,7 +211,7 @@ syscheck,agentless - + ossec syscheck_allowed Integrity checksum changed (allowed). From df8a38ae9b2868d5a2731841394269041649418f Mon Sep 17 00:00:00 2001 From: calve Date: Thu, 24 Mar 2016 20:31:41 +0100 Subject: [PATCH 09/13] Parse time as long --- src/analysisd/decoders/syscheck-allow.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/analysisd/decoders/syscheck-allow.c b/src/analysisd/decoders/syscheck-allow.c index b39625ccd..25e7f6e49 100644 --- a/src/analysisd/decoders/syscheck-allow.c +++ b/src/analysisd/decoders/syscheck-allow.c @@ -47,7 +47,7 @@ static int consumeAllowchange(const char *filename, Eventinfo *lf){ int validity; time_t until; char path[OS_FLSIZE]; - sscanf(line, "%d %d %s", &validity, &until, path); + sscanf(line, "%d %ld %s", &validity, &until, path); if (validity) { if (until > current) { if (strcmp(path, filename) == 0){ From 3810cd92b3f2d936c512a04cea72b1b455465696 Mon Sep 17 00:00:00 2001 From: calve Date: Thu, 24 Mar 2016 20:45:39 +0100 Subject: [PATCH 10/13] Fix compilation --- src/analysisd/analysisd.c | 1 + src/analysisd/decoders/syscheck-allow.c | 10 ++++------ src/analysisd/decoders/syscheck.c | 8 +++----- src/syscheckd/syscheck.c | 2 +- 4 files changed, 9 insertions(+), 12 deletions(-) diff --git a/src/analysisd/analysisd.c b/src/analysisd/analysisd.c index 59d84c09d..a2f199cf7 100644 --- a/src/analysisd/analysisd.c +++ b/src/analysisd/analysisd.c @@ -32,6 +32,7 @@ #include "cleanevent.h" #include "dodiff.h" #include "output/jsonout.h" +#include "decoders/syscheck-allow.h" #ifdef PICVIZ_OUTPUT_ENABLED #include "output/picviz.h" diff --git a/src/analysisd/decoders/syscheck-allow.c b/src/analysisd/decoders/syscheck-allow.c index 25e7f6e49..22cd403b7 100644 --- a/src/analysisd/decoders/syscheck-allow.c +++ b/src/analysisd/decoders/syscheck-allow.c @@ -24,7 +24,7 @@ /* Determine if this filename have at least one allowed change, and consumme it */ -static int consumeAllowchange(const char *filename, Eventinfo *lf){ +int consumeAllowchange(const char *filename, Eventinfo *lf){ FILE *db_file; char db_filename[OS_FLSIZE]; char line[OS_FLSIZE*2]; @@ -68,18 +68,17 @@ static int consumeAllowchange(const char *filename, Eventinfo *lf){ /* Save an Allowchange record in our "database" */ -static int produceAllowchange(time_t timestamp, const char *filename, Eventinfo *lf){ +int produceAllowchange(time_t timestamp, const char *filename, Eventinfo *lf){ FILE *db_file; char db_filename[OS_FLSIZE]; snprintf(db_filename, OS_FLSIZE , "%s/%s", ALLOWCHANGE_DIR, lf->hostname); - verbose("opening %s", db_filename); db_file = fopen(db_filename, "a"); if (db_file) { - fprintf(db_file, "%d %d %s\n", 1, timestamp, filename); + fprintf(db_file, "%d %ld %s\n", 1, timestamp, filename); fclose(db_file); return timestamp; } - verbose("failed to write to %s", db_filename); + verbose("Failed to open %s", db_filename); return 0; } @@ -88,7 +87,6 @@ static int produceAllowchange(time_t timestamp, const char *filename, Eventinfo /* A special decoder to read an AllowChange event */ int DecodeAllowchange(Eventinfo *lf) { - int status; time_t timestamp; char *f_name; diff --git a/src/analysisd/decoders/syscheck.c b/src/analysisd/decoders/syscheck.c index faa7cc4d9..fcd18089f 100644 --- a/src/analysisd/decoders/syscheck.c +++ b/src/analysisd/decoders/syscheck.c @@ -14,7 +14,7 @@ #include "config.h" #include "alerts/alerts.h" #include "decoder.h" -#include "syscheck-allow.c" /* I don't like this either */ +#include "syscheck-allow.h" typedef struct __sdb { char buf[OS_MAXSTR + 1]; @@ -178,7 +178,6 @@ static FILE *DB_File(const char *agent, int *agent_id) /* Get agent file */ snprintf(sdb.buf, OS_FLSIZE , "%s/%s", SYSCHECK_DIR, agent); - verbose("opening %s", sdb.buf); /* r+ to read and write. Do not truncate */ sdb.agent_fps[i] = fopen(sdb.buf, "r+"); if (!sdb.agent_fps[i]) { @@ -306,9 +305,8 @@ static int DB_Search(const char *f_name, const char *c_sum, Eventinfo *lf) } /* Check the number of changes */ - if (!Config.syscheck_auto_ignore) { - sdb.syscheck_dec->id = sdb.id1; - } else { + sdb.syscheck_dec->id = sdb.id1; + if (Config.syscheck_auto_ignore) { switch (p) { case 0: sdb.syscheck_dec->id = sdb.id1; diff --git a/src/syscheckd/syscheck.c b/src/syscheckd/syscheck.c index 9695a231d..fbb8e7116 100644 --- a/src/syscheckd/syscheck.c +++ b/src/syscheckd/syscheck.c @@ -72,7 +72,7 @@ static void read_internal(int debug_level) static int allowChange(char* filename, time_t timestamp) { char msg[1024*2]; - sprintf(msg, "%d %s", timestamp, filename); + sprintf(msg, "%ld %s", timestamp, filename); if ((syscheck.queue = StartMQ(DEFAULTQPATH, WRITE)) < 0) { ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQPATH); } From 4b63d9124e181491fd2aba02bbbf3c1aba1c5898 Mon Sep 17 00:00:00 2001 From: calve Date: Wed, 30 Mar 2016 20:10:41 +0200 Subject: [PATCH 11/13] Less sleep(), more debug() --- src/syscheckd/syscheck.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/syscheckd/syscheck.c b/src/syscheckd/syscheck.c index fbb8e7116..fa45c5dc6 100644 --- a/src/syscheckd/syscheck.c +++ b/src/syscheckd/syscheck.c @@ -76,11 +76,10 @@ static int allowChange(char* filename, time_t timestamp) if ((syscheck.queue = StartMQ(DEFAULTQPATH, WRITE)) < 0) { ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQPATH); } - sleep(1); if (SendMSG(syscheck.queue, msg, ALLOWCHANGE, ALLOWCHANGE_MQ) < 0) { merror(QUEUE_SEND, ARGV0); } - printf("send_allowchange_msg: %s to %s\n", msg, DEFAULTQPATH); + debug1("%s: send_allowchange_msg: %s to %s\n", ARGV0, msg, DEFAULTQPATH); return 0; } From 11880da30bee0c26b1b4fedabd4e05868c7d24dd Mon Sep 17 00:00:00 2001 From: calve Date: Wed, 30 Mar 2016 20:11:21 +0200 Subject: [PATCH 12/13] Read allowed change paths from stdin --- src/headers/defs.h | 1 + src/syscheckd/syscheck.c | 27 +++++++++++++++++++-------- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/headers/defs.h b/src/headers/defs.h index 6440a1739..65541bc75 100644 --- a/src/headers/defs.h +++ b/src/headers/defs.h @@ -32,6 +32,7 @@ #define OS_FLSIZE OS_SIZE_256 /* Maximum file size */ #define OS_HEADER_SIZE OS_SIZE_128 /* Maximum header size */ #define OS_LOG_HEADER OS_SIZE_256 /* Maximum log header size */ +#define OS_MAXPATH OS_SIZE_1024 /* Maximum filepath length */ #define IPSIZE INET6_ADDRSTRLEN /* IP Address size */ /* Some global names */ diff --git a/src/syscheckd/syscheck.c b/src/syscheckd/syscheck.c index fa45c5dc6..f68d9989e 100644 --- a/src/syscheckd/syscheck.c +++ b/src/syscheckd/syscheck.c @@ -71,7 +71,7 @@ static void read_internal(int debug_level) */ static int allowChange(char* filename, time_t timestamp) { - char msg[1024*2]; + char msg[OS_MAXPATH*2]; sprintf(msg, "%ld %s", timestamp, filename); if ((syscheck.queue = StartMQ(DEFAULTQPATH, WRITE)) < 0) { ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQPATH); @@ -208,11 +208,12 @@ int main(int argc, char **argv) int test_config = 0, run_foreground = 0; int allow_change = 0; const char *cfg = DEFAULTCPATH; - char *allow_filename = NULL; + char allow_filename[OS_MAXPATH]; time_t allow_timestamp = 0; /* Set the name */ OS_SetName(ARGV0); + *allow_filename = '\0'; while ((c = getopt(argc, argv, "Vtdhfc:a:u:")) != -1) { switch (c) { @@ -239,7 +240,7 @@ int main(int argc, char **argv) if (!optarg) { ErrorExit("%s: -a needs a filename", ARGV0); } - allow_filename = optarg; + strncpy(allow_filename, optarg, OS_MAXPATH); allow_change = 1; break; case 'u': @@ -290,12 +291,22 @@ int main(int argc, char **argv) if (allow_change){ - if (allow_filename && allow_timestamp != 0) { - allowChange(allow_filename, allow_timestamp); - exit(0); - } else { - merror("%s: WARN: Missing parameter for allow change", ARGV0); + if (allow_timestamp == 0){ + merror("%s: WARN: Missing timestamp for allow change", ARGV0); exit(1); + } else if (*allow_filename != '\0') { + allowChange(allow_filename, allow_timestamp); + exit(0); + } else { + debug1("%s: Reading filenames from stdin, one path per line", ARGV0); + while (fgets(allow_filename, OS_MAXPATH, stdin)) { + /* Remove the newline character */ + if (allow_filename[strlen(allow_filename) - 1] == '\n') { + allow_filename[strlen(allow_filename) - 1] = '\0'; + } + allowChange(allow_filename, allow_timestamp); + } + exit(0); } } From bfa8770cb8dfdf690c86d0aff319da11b1b72e3e Mon Sep 17 00:00:00 2001 From: calve Date: Sat, 2 Apr 2016 13:46:26 +0200 Subject: [PATCH 13/13] Add missing syscheck-allowchange.h --- src/analysisd/decoders/syscheck-allow.h | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 src/analysisd/decoders/syscheck-allow.h diff --git a/src/analysisd/decoders/syscheck-allow.h b/src/analysisd/decoders/syscheck-allow.h new file mode 100644 index 000000000..362580bab --- /dev/null +++ b/src/analysisd/decoders/syscheck-allow.h @@ -0,0 +1,10 @@ +#ifndef __SYSCHECK_ALLOW_H +#define __SYSCHECK_ALLOW_H + +#include "shared.h" + +int consumeAllowchange(const char *filename, Eventinfo *lf); +int produceAllowchange(time_t timestamp, const char *filename, Eventinfo *lf); +int DecodeAllowchange(Eventinfo *lf); + +#endif