Thank you Pedro. That's good information.
With that in mind, I've decided to give this a
try:
https://blog.rootshell.be/2013/05/13/improving-file-integrity-monitoring-with-ossec/
Basically, he patched the code to make it look at a sqlite3 database prior
to alerting.
Unfortunately, the code is a bit old, and I'm not sure he included all of
the steps. I couldn't use his patch because I wanted the latest code, so I
created my own based on his (attached). And although I have installed
libsqlite3-dev, it fails to compile. I keep getting the following, which
suggests it isn't pulling the code in from sqlite3.h for some reason.
/usr/local/src/ossec-hids-2.8.3/src/analysisd/decoders/syscheck.c:845:
undefined reference to `debug0'
/usr/local/src/ossec-hids-2.8.3/src/analysisd/decoders/syscheck.c:849:
undefined reference to `sqlite3_open'
/usr/local/src/ossec-hids-2.8.3/src/analysisd/decoders/syscheck.c:852:
undefined reference to `sqlite3_prepare_v2'
/usr/local/src/ossec-hids-2.8.3/src/analysisd/decoders/syscheck.c:854:
undefined reference to `sqlite3_step'
/usr/local/src/ossec-hids-2.8.3/src/analysisd/decoders/syscheck.c:859:
undefined reference to `sqlite3_finalize'
/usr/local/src/ossec-hids-2.8.3/src/analysisd/decoders/syscheck.c:860:
undefined reference to `sqlite3_close'
/usr/local/src/ossec-hids-2.8.3/src/analysisd/decoders/syscheck.c:861:
undefined reference to `debug0'
/usr/local/src/ossec-hids-2.8.3/src/analysisd/decoders/syscheck.c:865:
undefined reference to `sqlite3_finalize'
/usr/local/src/ossec-hids-2.8.3/src/analysisd/decoders/syscheck.c:866:
undefined reference to `sqlite3_close'
Now, I haven't coded in C since.... high school? Like 20 years ago. I
remember some things, and have googled others, but I'm in over my head. I
can't seem to figure out how to fix this, or what I might have done wrong.
FYI, I'm on Ubuntu 16.04.
If anyone could help me, I'd appreciate it.
Thanks,
BJ
On Wednesday, March 8, 2017 at 9:14:45 AM UTC-7, Pedro Sanchez wrote:
>
> Hi,
>
> I like your intention to create a whitelist for checksum using CDB lists,
> I think it will be a great functionality. Unfortunately you won't be able
> to do it, since OSSEC lists does not allow to match using
> "syscheck.md5_after" field.
> You can check here the available fields for matching a CDB List:
> https://github.com/wazuh/wazuh/blob/master/src/analysisd/rules.c#L665
> (srcip, srcport, dstip, dstport, user, url, id, hostname, program_name,
> status and action)
>
> Beside that, if somehow we add the funcionallity to match for that field,
> you could use a negative key match, adding the list sentence to syscheck
> rule 550.
>
> Negative key match:
> http://ossec-docs.readthedocs.io/en/latest/manual/rules-decoders/rule-lists.html#negative-key-match
>
> Rule 550 for syscheck integrity checksum changed, will trigger only if
> they md5 checksum is not present on the CDB list, how it would look like:
>
> <rule id="550" level="7">
>> <category>ossec</category>
>> <decoded_as>syscheck_integrity_changed</decoded_as>
>> *<list field="syscheck.md5_after"
>> lookup="not_match_key">etc/lists/whitelist_md5</list>*
>> <description>Integrity checksum changed.</description>
>> <group>syscheck,pci_dss_11.5,</group>
>> </rule>
>
>
> *whitelist_md5*
>
> d41d8cd98f00b204e9800998ecf8427a:file1
>> d41d8cd98f00b204e9800998ecf8427b:file2
>> d41d8cd98f00b204e9800998ecf8427c:file3
>> d41d8cd98f00b204e9800998ecf8427d:file4
>
>
> ossec.conf
>
>> *<list>etc/lists/whitelist_md5</list>*
>
>
> *Compile CDB List*
>
>> /var/ossec/bin/ossec-makelists
>
>
>
> Maybe someone figure out a different way to do this.
>
> Regards,
> Pedro Sanchez.
>
>
>
> On Wed, Mar 8, 2017 at 1:13 AM, BJ <[email protected] <javascript:>>
> wrote:
>
>> I've seen the possibility mentioned in this forum a couple of times
>> regarding adding the ability to check an MD5sum CDB list with rules. Right
>> now, I'm in a situation where I could use that ability. However, I can't
>> see anywhere that describes how to use it. Was that ever implemented?
>> Frankly, I'm interested enough in this feature that I'd do it myself if I
>> could, but I don't know C/C++, and only do scripting in Python.
>>
>> I'm trying to monitor a web folder for changes, but of course I don't
>> want to be alerted on every file when a releases is done (they can be done
>> at any time of day too). I can get md5 sums of each of the files prior to
>> the release to whitelist them for ossec, but I can't seem to figure out how
>> to tell ossec to use that database. Any help would be appreciated.
>>
>> Thanks.
>>
>> --
>>
>> ---
>> You received this message because you are subscribed to the Google Groups
>> "ossec-list" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to [email protected] <javascript:>.
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>
--
---
You received this message because you are subscribed to the Google Groups
"ossec-list" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.
Only in ossec-hids-2.8.3/src/analysisd/compiled_rules: compiled_rules.h
diff -r -u ossec-hids-2.8.3-orig/src/analysisd/decoders/syscheck.c ossec-hids-2.8.3/src/analysisd/decoders/syscheck.c
--- ossec-hids-2.8.3-orig/src/analysisd/decoders/syscheck.c 2015-10-12 15:21:06.000000000 -0600
+++ ossec-hids-2.8.3/src/analysisd/decoders/syscheck.c 2017-03-08 16:32:48.743388280 -0700
@@ -19,6 +19,7 @@
#include "alerts/alerts.h"
#include "decoder.h"
+#include <sqlite3.h>
typedef struct __sdb
{
@@ -60,7 +61,37 @@
/* Global variable */
_sdb sdb;
-
+/* Extract a token from a string */
+char *extract_token(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);
+}
+
+/* Validate a MD5 string format */
+int validate_md5(char *s)
+{
+ 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
@@ -734,6 +765,13 @@
char *c_sum;
char *f_name;
+ char *p;
+ char stmt[OS_MAXSTR + 1];
+ sqlite3 *conn;
+ sqlite3_stmt *res;
+ int error = 0;
+ int rec_count = 0;
+ const char *tail;
/* Every syscheck message must be in the following format:
* checksum filename
@@ -795,6 +833,44 @@
/* Checksum is at the beginning of the log */
c_sum = lf->log;
+ /* Extract the MD5 hash and search for it in the whitelist
+ * Sample message:
+ * 0:0:0:0:78f5c869675b1d09ddad870adad073f9:bd6c8d7a58b462aac86475e59af0e22954039c50
+ */
+ if (Config.md5db)
+ {
+ if ((p = extract_token(c_sum, ":", 4)))
+ {
+ if (!validate_md5(p)) { /* Never trust input from other origin */
+ debug0("%s: Not a valid MD5 hash: '%s'", ARGV0, p);
+ return(0);
+ }
+ debug1("%s: Checking MD5 '%s' in %s", ARGV0, p, Config.md5db);
+ if (!(error = sqlite3_open(Config.md5db, &conn)))
+ {
+ 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);
+ debug0(MD5_NOT_CHECKED, ARGV0, p);
+ return(0);
+ }
+ }
+ sqlite3_finalize(res);
+ sqlite3_close(conn);
+ }
+ else
+ {
+ merror(INVALID_IGNORE_MD5DB, ARGV0, Config.md5db);
+ }
+ }
+ }
/* Searching for file changes */
return(DB_Search(f_name, c_sum, lf));
diff -r -u ossec-hids-2.8.3-orig/src/config/global-config.c ossec-hids-2.8.3/src/config/global-config.c
--- ossec-hids-2.8.3-orig/src/config/global-config.c 2015-10-12 15:21:06.000000000 -0600
+++ ossec-hids-2.8.3/src/config/global-config.c 2017-03-08 14:51:13.737091164 -0700
@@ -175,6 +175,9 @@
char *xml_geoip6_db_path = "geoip6_db_path";
#endif
+ /* MD5 DB */
+ char *xml_md5db = "md5db";
+
_Config *Config;
MailConfig *Mail;
@@ -591,6 +594,14 @@
}
}
#endif
+ /* MD5 DB */
+ else if(strcmp(node[i]->element, xml_md5db) == 0)
+ {
+ if(Config)
+ {
+ os_strdup(node[i]->content, Config->md5db);
+ }
+ }
else
{
merror(XML_INVELEM, ARGV0, node[i]->element);
diff -r -u ossec-hids-2.8.3-orig/src/config/global-config.h ossec-hids-2.8.3/src/config/global-config.h
--- ossec-hids-2.8.3-orig/src/config/global-config.h 2015-10-12 15:21:06.000000000 -0600
+++ ossec-hids-2.8.3/src/config/global-config.h 2017-03-08 14:52:18.247636490 -0700
@@ -90,6 +90,8 @@
char *geoip6_db_path;
#endif
+ /* MD5 DB support */
+ char *md5db;
}_Config;
diff -r -u ossec-hids-2.8.3-orig/src/Config.Make ossec-hids-2.8.3/src/Config.Make
--- ossec-hids-2.8.3-orig/src/Config.Make 2015-10-12 15:21:06.000000000 -0600
+++ ossec-hids-2.8.3/src/Config.Make 2017-03-08 17:14:16.724605164 -0700
@@ -8,7 +8,7 @@
include ${PT}Config.OS
CC?=cc
-CFLAGS = -g -Wall -I${PT} -I${PT}headers ${CPATH} ${CEXTRA} ${DEXTRA} ${EEXTRA} ${FEXTRA} ${GEXTRA} ${HEXTRA} ${MEXTRA} ${CGEOIP} -DARGV0=\"${NAME}\" -DOSSECHIDS
+CFLAGS = -g -Wall -I${PT} -I${PT}headers ${CPATH} ${CEXTRA} ${DEXTRA} ${EEXTRA} ${FEXTRA} ${GEXTRA} ${HEXTRA} ${MEXTRA} ${CGEOIP} -lsqlite3 -DARGV0=\"${NAME}\" -DOSSECHIDS
SOURCES = *.c
OBJECTS = *.o
diff -r -u ossec-hids-2.8.3-orig/src/error_messages/error_messages.h ossec-hids-2.8.3/src/error_messages/error_messages.h
--- ossec-hids-2.8.3-orig/src/error_messages/error_messages.h 2015-10-12 15:21:06.000000000 -0600
+++ ossec-hids-2.8.3/src/error_messages/error_messages.h 2017-03-08 15:01:17.663894822 -0700
@@ -135,7 +135,8 @@
#ifdef GEOIP
#define INVALID_GEOIP_DB "%s(1276): ERROR: Cannot open GeoIP database: '%s'."
#endif
-
+#define INVALID_IGNORE_MD5DB "%s(1277) ERROR: Cannot open MD5 database: '%s'."
+#define MD5_NOT_CHECKED "%s(1278) WARN: File with MD5 '%s' not processed."
/* Log collector */