OSSEC Daily Reports

As with any user of OSSEC, analyzing and working with the data is the key to successfully managing your environment.  From a prior post you can see we are monitoring events as they occur which is good for catching serious issues as they occur; however, it is not usually the best way to document what was identified and track what is being done to correct it.

Until OSSEC can have a better UI, I have decided to use the built in daily reports to automatically create tickets in our ticket system to be manually reviewed by security engineers documenting the steps taken to resolve what was identified.

In setting up the daily reports google helped me find the v2.5 documentation on the configuration options for daily reports (ossec.conf).  Some reports shown in the examples google found show access attempts or file integrity changes (examples).  This and other examples were very helpful in providing examples on how OSSEC could handle daily reports.

When setting up daily reports, the first thing to do is determine what variables will determine the report creation and the best way to do this is to use the ossec-reportd to  quickly test the various fields needed to search & create your reports.

For example, say you wanted to get the reports for file integrity changes in the 192.168.1 subnet, you would execute:

cat logs/alerts/2011/Jun/ossec-alerts-20.log | bin/ossec-reportsd -f group syscheck -f location 192.168.1

Valid ossec-reportd filters include: group, rule, level, location,user, srcip

Now to convert this into a daily report, edit: etc/ossec.conf, and add the following:

<title>Daily OSSEC report: ZZ Syscheck Test Location</title>

Rules can have the following options: group, categories, rule, level, location, srcip, user, title, email_to and showlogs.

The <showlogs> option is not listed on the ossec wiki and other documentation.  I only noticed it while reading through the source code trying to identify why the daily reports were not working for me.  It is a great option and determines whether the reports include or do not include the log items found when creating the report.

You can setup as many <reports></reports> as you need to within the ossec_config and they will all be generated when the ossec logs rotate at the change of every day.

However you may want to test your config or run reports without waiting for the automatic run at midnight. For those needing that functionality I have created the attached patch that can be applied within the ossec directory (cd ossec-hids-2.5.1; patch -p1 < ossec-dmz-forcedailyreports.diff).

This patch enables a “-R” option to ossec-monitord allowing it to be run from the command line processing all of the defined daily reports.  You may want to include the -d (debug) option if you are having problems or want to see what it is doing.

Please note that the -f (force foreground) is enabled by default when -R is selected.

Also, when researching what was needed for this patch I identified that the outgoing mail did not have 2 \r\n (\r\n\r\n) between the subject and the messages so the patch updates that so messages will be sent cleanly.

I also noticed that when ossec loads up the ossec.conf file it only accepts a-z,A-Z,0-9, – and _.  I had made the assumption that ossec-reportd used the same input details as ossec-monitord, however after hours of tracing I realized that the ossec.conf file was loaded with the prior mentioned input characters only.  So the config function was updated to allow “.” and “/” allowing for full neworks and log paths be entered.

Please let me know if I missed anything or if there are problems with my patch.

– David
– dmz


diff -Naur -x ‘*.a’ -x ‘*.o’ ossec-hids-2.5.1/src/config/reports-config.c ossec-hids-2.5.1-manualreports/src/config/reports-config.c
— ossec-hids-2.5.1/src/config/reports-config.c    2010-10-12 19:17:37.000000000 +0000
+++ ossec-hids-2.5.1-manualreports/src/config/reports-config.c    2011-06-19 04:45:56.000000000 +0000
@@ -30,7 +30,7 @@
if((*mystr >= ‘a’ && *mystr <= ‘z’) ||
(*mystr >= ‘A’ && *mystr <= ‘Z’) ||
(*mystr >= ‘0’ && *mystr <= ‘9’) ||
–           *mystr == ‘-‘ || *mystr == ‘_’)
+           *mystr == ‘-‘ || *mystr == ‘_’ || *mystr == ‘.’ || *mystr == ‘/’)
diff -Naur -x ‘*.a’ -x ‘*.o’ ossec-hids-2.5.1/src/monitord/main.c ossec-hids-2.5.1-manualreports/src/monitord/main.c
— ossec-hids-2.5.1/src/monitord/main.c    2010-10-12 19:17:37.000000000 +0000
+++ ossec-hids-2.5.1-manualreports/src/monitord/main.c    2011-06-19 02:50:33.000000000 +0000
@@ -18,13 +18,19 @@

int main(int argc, char **argv)
–    int c, test_config = 0, run_foreground = 0;
+    time_t tm;
+    struct tm *p;
+    int c, test_config = 0, run_foreground = 0, generate_manual_reports = 0;
int uid=0,gid=0;
+    int today = 0;
+    int thismonth = 0;
+    int thisyear = 0;
char *dir  = DEFAULTDIR;
char *user = USER;
char *group = GROUPGLOBAL;
char *cfg = DEFAULTCPATH;

/* Initializing global variables */
mond.a_queue = 0;

@@ -32,11 +38,15 @@

–    while((c = getopt(argc, argv, “Vdhtfu:g:D:c:”)) != -1){
+    while((c = getopt(argc, argv, “RVdhtfu:g:D:c:”)) != -1){
case ‘V’:
+            case ‘R’:
+                generate_manual_reports = 1;
+                run_foreground = 1;
+                break;
case ‘h’:
@@ -198,6 +207,19 @@
/* Start up message */
verbose(STARTUP_MSG, ARGV0, (int)getpid());

+    if(generate_manual_reports)
+    {
+        /* Getting currently time before starting */
+        tm = time(NULL);
+        p = localtime(&tm);
+        today = p->tm_mday;
+        thismonth = p->tm_mon;
+        thisyear = p->tm_year+1900;
+       generate_reports(today, thismonth, thisyear, p);
+       exit(0);
+    }

/* the real daemon now */
diff -Naur -x ‘*.a’ -x ‘*.o’ ossec-hids-2.5.1/src/os_maild/sendcustomemail.c ossec-hids-2.5.1-manualreports/src/os_maild/sendcustomemail.c
— ossec-hids-2.5.1/src/os_maild/sendcustomemail.c    2010-10-12 19:17:37.000000000 +0000
+++ ossec-hids-2.5.1-manualreports/src/os_maild/sendcustomemail.c    2011-06-19 04:12:35.000000000 +0000
@@ -33,7 +33,7 @@
#define FROM            “From: OSSEC HIDS <%s>\r\n”
#define TO                “To: <%s>\r\n”
#define CC                “Cc: <%s>\r\n”
-#define SUBJECT            “Subject: %s\r\n”
+#define SUBJECT            “Subject: %s\r\n\r\n”
#define ENDDATA            “\r\n.\r\n”
#define QUITMSG         “QUIT\r\n”

diff -Naur -x ‘*.a’ -x ‘*.o’ ossec-hids-2.5.1/src/shared/help.c ossec-hids-2.5.1-manualreports/src/shared/help.c
— ossec-hids-2.5.1/src/shared/help.c    2010-10-12 19:17:37.000000000 +0000
+++ ossec-hids-2.5.1-manualreports/src/shared/help.c    2011-06-20 04:13:07.000000000 +0000
@@ -21,12 +21,24 @@

void help(const char *prog)
+    int ismonitord = 0;
+    char helpopts[6];
+    helpopts[5] = ‘\0’;
+    snprintf(helpopts, 5, “Vhdt”);
+    if (strstr(prog, “monitord”))
+    {
+      ismonitord = 1;
+      snprintf(helpopts, 5, “VRhdt”);
+    }
print_out(” “);
print_out(“%s %s – %s (%s)”, __name, __version, __author, __contact);
print_out(“%s”, __site);
print_out(” “);
–    print_out(”  %s: -[Vhdt] [-u user] [-g group] [-c config] [-D dir]”, prog);
+    print_out(”  %s: -[%s] [-u user] [-g group] [-c config] [-D dir]”, prog,helpopts);
print_out(”    -V          Version and license message”);
+    if (ismonitord)
+       print_out(”    -R          Run daily report”);
print_out(”    -h          This help message”);
print_out(”    -d          Execute in debug mode”);
print_out(”    -t          Test configuration”);