1 /* @(#) $Id: ./src/analysisd/prelude.c, 2011/09/08 dcid Exp $
4 /* Copyright (C) 2009 Trend Micro Inc.
7 * This program is a free software; you can redistribute it
8 * and/or modify it under the terms of the GNU General Public
9 * License (version 2) as published by the FSF - Free Software
16 #include <libprelude/prelude.h>
17 #include <libprelude/prelude-log.h>
18 #include <libprelude/idmef-message-print.h>
22 #include "eventinfo.h"
25 #define DEFAULT_ANALYZER_NAME "OSSEC"
26 #define ANALYZER_CLASS "Host IDS, File Integrity Checker, Log Analyzer"
27 #define ANALYZER_MODEL "Ossec"
28 #define ANALYZER_MANUFACTURER __site
29 #define ANALYZER_VERSION __version
39 /** OSSEC to prelude severity mapping. **/
40 char *(ossec2prelude_sev[])={"info","info","info","info",
41 "low","low","low","low",
42 "medium", "medium", "medium", "medium",
43 "high", "high", "high", "high", "high"};
47 static prelude_client_t *prelude_client;
50 void prelude_idmef_debug(idmef_message_t *idmef)
55 prelude_io_set_file_io(pio, stderr);
56 idmef_message_print(idmef, pio);
57 prelude_io_destroy(pio);
63 add_idmef_object(idmef_message_t *msg, const char *object, const char *value)
69 /* Can value be null? better check in here. */
75 ret = idmef_path_new_fast(&path, object);
81 ret = idmef_value_new_from_path(&val, path, value);
84 idmef_path_destroy(path);
88 ret = idmef_path_set(path, msg, val);
91 merror("%s: OSSEC2Prelude: IDMEF: Cannot add object '%s': %s.",
92 ARGV0, object, prelude_strerror(ret));
95 idmef_value_destroy(val);
96 idmef_path_destroy(path);
103 setup_analyzer(idmef_analyzer_t *analyzer)
106 prelude_string_t *string;
108 ret = idmef_analyzer_new_model(analyzer, &string);
111 prelude_string_set_constant(string, ANALYZER_MODEL);
113 ret = idmef_analyzer_new_class(analyzer, &string);
116 prelude_string_set_constant(string, ANALYZER_CLASS);
118 ret = idmef_analyzer_new_manufacturer(analyzer, &string);
121 prelude_string_set_constant(string, ANALYZER_MANUFACTURER);
123 ret = idmef_analyzer_new_version(analyzer, &string);
126 prelude_string_set_constant(string, ANALYZER_VERSION);
132 merror("%s: OSSEC2Prelude: %s: IDMEF error: %s.",
133 ARGV0, prelude_strsource(ret), prelude_strerror(ret));
140 void prelude_start(char *profile, int argc, char **argv)
143 prelude_client = NULL;
146 ret = prelude_init(&argc, argv);
149 merror("%s: %s: Unable to initialize the Prelude library: %s.",
150 ARGV0, prelude_strsource(ret), prelude_strerror(ret));
154 ret = prelude_client_new(&prelude_client,
155 profile!=NULL?profile:DEFAULT_ANALYZER_NAME);
158 merror("%s: %s: Unable to create a prelude client object: %s.",
159 ARGV0, prelude_strsource(ret), prelude_strerror(ret));
165 ret = setup_analyzer(prelude_client_get_analyzer(prelude_client));
168 merror("%s: %s: Unable to setup analyzer: %s",
169 ARGV0, prelude_strsource(ret), prelude_strerror(ret));
171 prelude_client_destroy(prelude_client,
172 PRELUDE_CLIENT_EXIT_STATUS_FAILURE);
178 ret = prelude_client_set_flags(prelude_client,
179 prelude_client_get_flags(prelude_client)
180 | PRELUDE_CLIENT_FLAGS_ASYNC_TIMER);
183 merror("%s: %s: Unable to set prelude client flags: %s.",
184 ARGV0, prelude_strsource(ret), prelude_strerror(ret));
188 /* Setting uid and gid of ossec. */
189 prelude_client_profile_set_uid(prelude_client_get_profile(prelude_client),
190 Privsep_GetUser(USER));
191 prelude_client_profile_set_gid(prelude_client_get_profile(prelude_client),
192 Privsep_GetGroup(GROUPGLOBAL));
195 ret = prelude_client_start(prelude_client);
198 merror("%s: %s: Unable to initialize prelude client: %s.",
199 ARGV0, prelude_strsource(ret), prelude_strerror(ret));
201 prelude_client_destroy(prelude_client,
202 PRELUDE_CLIENT_EXIT_STATUS_FAILURE);
212 void FileAccess_PreludeLog(idmef_message_t *idmef,
221 int _checksum_counter = 0;
222 char _prelude_section[128];
223 _prelude_section[127] = '\0';
225 debug1("%s: DEBUG: filename = %s.", ARGV0, filename);
226 debug1("%s: DEBUG: filenum = %d.", ARGV0, filenum);
228 snprintf(_prelude_section,128,"alert.target(0).file(%d).name",filenum);
229 add_idmef_object(idmef, _prelude_section, filename);
230 snprintf(_prelude_section,128,"alert.target(0).file(%d).category",filenum);
231 add_idmef_object(idmef, _prelude_section, "original");
232 } else if (filenum == 1) {
233 snprintf(_prelude_section,128,"alert.target(0).file(%d).name",filenum);
234 add_idmef_object(idmef, _prelude_section, filename);
235 snprintf(_prelude_section,128,"alert.target(0).file(%d).category",filenum);
236 add_idmef_object(idmef, _prelude_section, "current");
244 snprintf(_prelude_section,128,"alert.target(0).file(%d).checksum(%d).algorithm",filenum, _checksum_counter);
245 add_idmef_object(idmef, _prelude_section, "MD5");
246 snprintf(_prelude_section,128,"alert.target(0).file(%d).checksum(%d).value",filenum, _checksum_counter);
247 add_idmef_object(idmef, _prelude_section, md5);
251 snprintf(_prelude_section,128,"alert.target(0).file(%d).checksum(%d).algorithm",filenum, _checksum_counter);
252 add_idmef_object(idmef, _prelude_section, "SHA1");
253 snprintf(_prelude_section,128,"alert.target(0).file(%d).checksum(%d).value",filenum, _checksum_counter);
254 add_idmef_object(idmef, _prelude_section, sha1);
260 debug1("%s: DEBUG: owner = %s.", ARGV0, owner);
261 snprintf(_prelude_section,128,"alert.target(0).file(%d).File_Access(%d).user_id.number",filenum,FILE_USER);
262 add_idmef_object(idmef, _prelude_section,owner);
263 snprintf(_prelude_section,128,"alert.target(0).file(%d).File_Access(%d).user_id.type",filenum,FILE_USER);
264 add_idmef_object(idmef, _prelude_section, "user-privs");
266 /*add the group owner */
268 debug1("%s: DEBUG: gowner = %s.", ARGV0, gowner);
269 snprintf(_prelude_section,128,"alert.target(0).file(%d).File_Access(%d).user_id.number",filenum,FILE_GROUP);
270 add_idmef_object(idmef, _prelude_section,gowner);
271 snprintf(_prelude_section,128,"alert.target(0).file(%d).File_Access(%d).user_id.type",filenum,FILE_GROUP);
272 add_idmef_object(idmef, _prelude_section, "group-privs");
274 /*add the permissions */
276 if (perm & S_IWUSR) {
277 snprintf(_prelude_section,128,"alert.target(0).file(%d).File_Access(%d).permission(0)",filenum,FILE_USER);
278 add_idmef_object(idmef, _prelude_section,"write");
279 snprintf(_prelude_section,128,"alert.target(0).file(%d).File_Access(%d).permission(1)",filenum,FILE_USER);
280 add_idmef_object(idmef, _prelude_section,"delete");
282 if (perm & S_IXUSR) {
283 snprintf(_prelude_section,128,"alert.target(0).file(%d).File_Access(%d).permission(2)",filenum,FILE_USER);
284 add_idmef_object(idmef, _prelude_section,"execute");
286 if (perm & S_IRUSR ) {
287 snprintf(_prelude_section,128,"alert.target(0).file(%d).File_Access(%d).permission(3)",filenum,FILE_USER);
288 add_idmef_object(idmef, _prelude_section,"read");
290 if (perm & S_ISUID) {
291 snprintf(_prelude_section,128,"alert.target(0).file(%d).File_Access(%d).permission(4)",filenum,FILE_USER);
292 add_idmef_object(idmef, _prelude_section,"executeAs");
295 if (perm & S_IWGRP) {
296 snprintf(_prelude_section,128,"alert.target(0).file(%d).File_Access(%d).permission(0)",filenum,FILE_GROUP);
297 add_idmef_object(idmef, _prelude_section,"write");
298 snprintf(_prelude_section,128,"alert.target(0).file(%d).File_Access(%d).permission(1)",filenum,FILE_GROUP);
299 add_idmef_object(idmef, _prelude_section,"delete");
301 if (perm & S_IXGRP) {
302 snprintf(_prelude_section,128,"alert.target(0).file(%d).File_Access(%d).permission(2)",filenum,FILE_GROUP);
303 add_idmef_object(idmef, _prelude_section,"execute");
305 if (perm & S_IRGRP ) {
306 snprintf(_prelude_section,128,"alert.target(0).file(%d).File_Access(%d).permission(3)",filenum,FILE_GROUP);
307 add_idmef_object(idmef, _prelude_section,"read");
309 if (perm & S_ISGID) {
310 snprintf(_prelude_section,128,"alert.target(0).file(%d).File_Access(%d).permission(4)",filenum,FILE_GROUP);
311 add_idmef_object(idmef, _prelude_section,"executeAs");
313 if (perm & S_IWOTH) {
314 snprintf(_prelude_section,128,"alert.target(0).file(%d).File_Access(%d).permission(0)",filenum,FILE_OTHER);
315 add_idmef_object(idmef, _prelude_section,"write");
316 snprintf(_prelude_section,128,"alert.target(0).file(%d).File_Access(%d).permission(1)",filenum,FILE_OTHER);
317 add_idmef_object(idmef, _prelude_section,"delete");
319 if (perm & S_IXOTH) {
320 snprintf(_prelude_section,128,"alert.target(0).file(%d).File_Access(%d).permission(2)",filenum,FILE_OTHER);
321 add_idmef_object(idmef, _prelude_section,"execute");
323 if (perm & S_IROTH ) {
324 snprintf(_prelude_section,128,"alert.target(0).file(%d).File_Access(%d).permission(3)",filenum,FILE_OTHER);
325 add_idmef_object(idmef, _prelude_section,"read");
332 void OS_PreludeLog(Eventinfo *lf)
335 int classification_counter = 0;
336 int additional_data_counter = 0;
337 char _prelude_section[128];
338 char _prelude_data[256];
339 idmef_message_t *idmef;
340 RuleInfoDetail *last_info_detail;
343 /* Generate prelude alert */
344 ret = idmef_message_new(&idmef);
346 merror("%s: OSSEC2Prelude: Cannot create IDMEF message", ARGV0);
351 add_idmef_object(idmef, "alert.assessment.impact.description",
352 lf->generated_rule->comment);
354 add_idmef_object(idmef, "alert.assessment.impact.severity",
355 (lf->generated_rule->level > 15) ? "high":
356 ossec2prelude_sev[lf->generated_rule->level]);
358 add_idmef_object(idmef, "alert.assessment.impact.completion", "succeeded");
364 /* discard, drop, deny, */
373 snprintf(_prelude_data,256,"DROP: %s", lf->action);
381 snprintf(_prelude_data,256,"CLOSED: %s", lf->action);
392 snprintf(_prelude_data,256,"ALLOW: %s", lf->action);
395 snprintf(_prelude_data,256,"%s", lf->action);
398 add_idmef_object(idmef, "alert.assessment.action(0).category", "3");
399 add_idmef_object(idmef, "alert.assessment.action(0).description", _prelude_data);
407 /* Begin Classification Infomations */
409 add_idmef_object(idmef, "alert.classification.text",
410 lf->generated_rule->comment);
413 /* The Common Vulnerabilities and Exposures (CVE) (http://www.cve.mitre.org/)
414 * infomation if present in the triggering rule
416 if(lf->generated_rule->cve)
418 snprintf(_prelude_section,128,"alert.classification.reference(%d).origin",
419 classification_counter);
420 add_idmef_object(idmef, _prelude_section, "cve");
421 snprintf(_prelude_section,128,"alert.classification.reference(%d).name",
422 classification_counter);
423 add_idmef_object(idmef, _prelude_section, lf->generated_rule->cve);
424 snprintf(_prelude_section,128,"alert.classification.reference(%d).meaning",
425 classification_counter);
426 snprintf(_prelude_data,256,"CVE:%s", lf->generated_rule->cve);
427 add_idmef_object(idmef, _prelude_section, _prelude_data);
428 classification_counter++;
431 /* Rule sid is used to create a link to the rule on the OSSEC wiki */
432 if(lf->generated_rule->sigid)
434 snprintf(_prelude_section,128,"alert.classification.reference(%d).origin",
435 classification_counter);
436 add_idmef_object(idmef, _prelude_section, "vendor-specific");
438 snprintf(_prelude_section,128,"alert.classification.reference(%d).name",
439 classification_counter);
440 snprintf(_prelude_data,256,"Rule:%d",lf->generated_rule->sigid);
441 add_idmef_object(idmef, _prelude_section, _prelude_data);
443 snprintf(_prelude_section,128,"alert.classification.reference(%d).meaning",
444 classification_counter);
445 add_idmef_object(idmef, _prelude_section, "OSSEC Rule Wiki Documentation");
447 snprintf(_prelude_section,128,"alert.classification.reference(%d).url",
448 classification_counter);
449 snprintf(_prelude_data, 256,"http://www.ossec.net/wiki/Rule:%d",
450 lf->generated_rule->sigid);
451 add_idmef_object(idmef, _prelude_section, _prelude_data);
453 classification_counter++;
456 /* Extended Info Details */
457 for (last_info_detail = lf->generated_rule->info_details;
458 last_info_detail != NULL;
459 last_info_detail = last_info_detail->next)
461 if (last_info_detail->type == RULEINFODETAIL_LINK)
463 snprintf(_prelude_section,128,"alert.classification.reference(%d).origin",
464 classification_counter);
465 add_idmef_object(idmef, _prelude_section, "vendor-specific");
467 snprintf(_prelude_section,128,"alert.classification.reference(%d).name",
468 classification_counter);
469 snprintf(_prelude_data,256,"Rule:%d link",lf->generated_rule->sigid);
470 add_idmef_object(idmef, _prelude_section, _prelude_data);
471 snprintf(_prelude_section,128,"alert.classification.reference(%d).url",
472 classification_counter);
473 add_idmef_object(idmef, _prelude_section, last_info_detail->data);
475 classification_counter++;
477 else if(last_info_detail->type == RULEINFODETAIL_TEXT)
479 snprintf(_prelude_section,128,"alert.classification.reference(%d).origin",
480 classification_counter);
481 add_idmef_object(idmef, _prelude_section, "vendor-specific");
483 snprintf(_prelude_section,128,"alert.classification.reference(%d).name",
484 classification_counter);
485 snprintf(_prelude_data,256,"Rule:%d info",lf->generated_rule->sigid);
486 add_idmef_object(idmef, _prelude_section, _prelude_data);
488 snprintf(_prelude_section,128,"alert.classification.reference(%d).meaning",
489 classification_counter);
490 add_idmef_object(idmef, _prelude_section, last_info_detail->data);
491 classification_counter++;
495 snprintf(_prelude_section,128,"alert.classification.reference(%d).origin",
496 classification_counter);
497 switch(last_info_detail->type)
499 case RULEINFODETAIL_CVE:
500 add_idmef_object(idmef, _prelude_section, "cve");
502 case RULEINFODETAIL_OSVDB:
503 add_idmef_object(idmef, _prelude_section, "osvdb");
505 case RULEINFODETAIL_BUGTRACK:
506 add_idmef_object(idmef, _prelude_section, "bugtraqid");
509 add_idmef_object(idmef, _prelude_section, "vendor-specific");
512 snprintf(_prelude_section,128,"alert.classification.reference(%d).name",
513 classification_counter);
514 add_idmef_object(idmef, _prelude_section, last_info_detail->data);
519 /* Break ok the list of groups on the "," boundry
520 * For each section create a prelude reference classification
521 * that points back to the the OSSEC wiki for more infomation.
523 if(lf->generated_rule->group)
526 char new_generated_rule_group[256];
527 new_generated_rule_group[255] = '\0';
528 strncpy(new_generated_rule_group, lf->generated_rule->group, 255);
529 copy_group = strtok(new_generated_rule_group, ",");
531 snprintf(_prelude_section,128,"alert.classification.reference(%d).origin",
532 classification_counter);
533 add_idmef_object(idmef, _prelude_section, "vendor-specific");
535 snprintf(_prelude_section,128,"alert.classification.reference(%d).name",
536 classification_counter);
537 snprintf(_prelude_data,256,"Group:%s",copy_group);
538 add_idmef_object(idmef, _prelude_section, _prelude_data);
540 snprintf(_prelude_section,128,"alert.classification.reference(%d).meaning",
541 classification_counter);
542 add_idmef_object(idmef, _prelude_section, "OSSEC Group Wiki Documenation");
544 snprintf(_prelude_section,128,"alert.classification.reference(%d).url",
545 classification_counter);
546 snprintf(_prelude_data,256,"http://www.ossec.net/wiki/Group:%s",
548 add_idmef_object(idmef, _prelude_section, _prelude_data);
550 classification_counter++;
551 copy_group = strtok(NULL, ",");
554 } /* end classification block */
558 /* Begin Node infomation block */
560 /* Setting source info. */
561 add_idmef_object(idmef, "alert.source(0).Spoofed", "no");
562 add_idmef_object(idmef, "alert.source(0).Node.Address(0).address",
564 add_idmef_object(idmef, "alert.source(0).Service.port", lf->srcport);
568 add_idmef_object(idmef, "alert.source(0).User.UserId(0).name", lf->srcuser);
573 add_idmef_object(idmef, "alert.target(0).Service.name", lf->program_name);
574 add_idmef_object(idmef, "alert.target(0).Spoofed", "no");
578 add_idmef_object(idmef, "alert.target(0).Node.Address(0).address",
584 char new_prelude_target[256];
586 new_prelude_target[255] = '\0';
587 strncpy(new_prelude_target, lf->hostname, 255);
589 /* The messages can have the file, so we need to remove it.
591 * enigma->/var/log/authlog
592 * (esqueleto2) 192.168.2.99->/var/log/squid/access.log
594 tmp_str = strstr(new_prelude_target, "->");
599 add_idmef_object(idmef, "alert.target(0).Node.Address(0).address",
602 add_idmef_object(idmef, "alert.target(0).Service.name", lf->hostname);
603 add_idmef_object(idmef, "alert.target(0).Service.port", lf->dstport);
607 add_idmef_object(idmef, "alert.target(0).User.category", "2");
608 add_idmef_object(idmef, "alert.target(0).User.UserId(0).name", lf->dstuser);
610 } /* end Node infomation block */
613 /* Setting source file. */
614 add_idmef_object(idmef, "alert.additional_data(0).type", "string");
615 add_idmef_object(idmef, "alert.additional_data(0).meaning", "Source file");
616 add_idmef_object(idmef, "alert.additional_data(0).data", lf->location);
617 additional_data_counter++;
620 /* Setting full log. */
621 add_idmef_object(idmef, "alert.additional_data(1).type", "string");
622 add_idmef_object(idmef, "alert.additional_data(1).meaning", "Full Log");
623 add_idmef_object(idmef, "alert.additional_data(1).data", lf->full_log);
624 additional_data_counter++;
626 idmef_alert_set_analyzer(idmef_message_get_alert(idmef),
628 (prelude_client_get_analyzer(prelude_client)),
630 debug1("%s: DEBUG: lf->filename = %s.", ARGV0, lf->filename);
632 FileAccess_PreludeLog(idmef,
640 FileAccess_PreludeLog(idmef,
648 debug1("%s: DEBUG: done with alert.target(0).file(1)", ARGV0);
651 debug1("%s: DEBUG: Sending IDMEF alert", ARGV0);
652 prelude_client_send_idmef(prelude_client, idmef);
653 debug1("%s: DEBUG: destroying IDMEF alert", ARGV0);
654 idmef_message_destroy(idmef);