3 /* Copyright (C) 2009 Trend Micro Inc.
6 * This program is a free software; you can redistribute it
7 * and/or modify it under the terms of the GNU General Public
8 * License (version 2) as published by the FSF - Free Software
15 #include <libprelude/prelude.h>
16 #include <libprelude/prelude-log.h>
17 #include <libprelude/idmef-message-print.h>
21 #include "eventinfo.h"
24 #define DEFAULT_ANALYZER_NAME "OSSEC"
25 #define ANALYZER_CLASS "Host IDS, File Integrity Checker, Log Analyzer"
26 #define ANALYZER_MODEL "Ossec"
27 #define ANALYZER_MANUFACTURER __site
28 #define ANALYZER_VERSION __version
38 /** OSSEC to prelude severity mapping. **/
39 char *(ossec2prelude_sev[])={"info","info","info","info",
40 "low","low","low","low",
41 "medium", "medium", "medium", "medium",
42 "high", "high", "high", "high", "high"};
46 static prelude_client_t *prelude_client;
49 void prelude_idmef_debug(idmef_message_t *idmef)
54 prelude_io_set_file_io(pio, stderr);
55 idmef_message_print(idmef, pio);
56 prelude_io_destroy(pio);
62 add_idmef_object(idmef_message_t *msg, const char *object, const char *value)
68 /* Can value be null? better check in here. */
74 ret = idmef_path_new_fast(&path, object);
80 ret = idmef_value_new_from_path(&val, path, value);
83 idmef_path_destroy(path);
87 ret = idmef_path_set(path, msg, val);
90 merror("%s: OSSEC2Prelude: IDMEF: Cannot add object '%s': %s.",
91 ARGV0, object, prelude_strerror(ret));
94 idmef_value_destroy(val);
95 idmef_path_destroy(path);
102 setup_analyzer(idmef_analyzer_t *analyzer)
105 prelude_string_t *string;
107 ret = idmef_analyzer_new_model(analyzer, &string);
110 prelude_string_set_constant(string, ANALYZER_MODEL);
112 ret = idmef_analyzer_new_class(analyzer, &string);
115 prelude_string_set_constant(string, ANALYZER_CLASS);
117 ret = idmef_analyzer_new_manufacturer(analyzer, &string);
120 prelude_string_set_constant(string, ANALYZER_MANUFACTURER);
122 ret = idmef_analyzer_new_version(analyzer, &string);
125 prelude_string_set_constant(string, ANALYZER_VERSION);
131 merror("%s: OSSEC2Prelude: %s: IDMEF error: %s.",
132 ARGV0, prelude_strsource(ret), prelude_strerror(ret));
139 void prelude_start(char *profile, int argc, char **argv)
142 prelude_client = NULL;
145 ret = prelude_init(&argc, argv);
148 merror("%s: %s: Unable to initialize the Prelude library: %s.",
149 ARGV0, prelude_strsource(ret), prelude_strerror(ret));
153 ret = prelude_client_new(&prelude_client,
154 profile!=NULL?profile:DEFAULT_ANALYZER_NAME);
157 merror("%s: %s: Unable to create a prelude client object: %s.",
158 ARGV0, prelude_strsource(ret), prelude_strerror(ret));
164 ret = setup_analyzer(prelude_client_get_analyzer(prelude_client));
167 merror("%s: %s: Unable to setup analyzer: %s",
168 ARGV0, prelude_strsource(ret), prelude_strerror(ret));
170 prelude_client_destroy(prelude_client,
171 PRELUDE_CLIENT_EXIT_STATUS_FAILURE);
177 ret = prelude_client_set_flags(prelude_client,
178 prelude_client_get_flags(prelude_client)
179 | PRELUDE_CLIENT_FLAGS_ASYNC_TIMER);
182 merror("%s: %s: Unable to set prelude client flags: %s.",
183 ARGV0, prelude_strsource(ret), prelude_strerror(ret));
187 /* Setting uid and gid of ossec. */
188 prelude_client_profile_set_uid(prelude_client_get_profile(prelude_client),
189 Privsep_GetUser(USER));
190 prelude_client_profile_set_gid(prelude_client_get_profile(prelude_client),
191 Privsep_GetGroup(GROUPGLOBAL));
194 ret = prelude_client_start(prelude_client);
197 merror("%s: %s: Unable to initialize prelude client: %s.",
198 ARGV0, prelude_strsource(ret), prelude_strerror(ret));
200 prelude_client_destroy(prelude_client,
201 PRELUDE_CLIENT_EXIT_STATUS_FAILURE);
211 void FileAccess_PreludeLog(idmef_message_t *idmef,
220 int _checksum_counter = 0;
221 char _prelude_section[128];
222 _prelude_section[127] = '\0';
224 debug1("%s: DEBUG: filename = %s.", ARGV0, filename);
225 debug1("%s: DEBUG: filenum = %d.", ARGV0, filenum);
227 snprintf(_prelude_section,128,"alert.target(0).file(%d).name",filenum);
228 add_idmef_object(idmef, _prelude_section, filename);
229 snprintf(_prelude_section,128,"alert.target(0).file(%d).category",filenum);
230 add_idmef_object(idmef, _prelude_section, "original");
231 } else if (filenum == 1) {
232 snprintf(_prelude_section,128,"alert.target(0).file(%d).name",filenum);
233 add_idmef_object(idmef, _prelude_section, filename);
234 snprintf(_prelude_section,128,"alert.target(0).file(%d).category",filenum);
235 add_idmef_object(idmef, _prelude_section, "current");
243 snprintf(_prelude_section,128,"alert.target(0).file(%d).checksum(%d).algorithm",filenum, _checksum_counter);
244 add_idmef_object(idmef, _prelude_section, "MD5");
245 snprintf(_prelude_section,128,"alert.target(0).file(%d).checksum(%d).value",filenum, _checksum_counter);
246 add_idmef_object(idmef, _prelude_section, md5);
250 snprintf(_prelude_section,128,"alert.target(0).file(%d).checksum(%d).algorithm",filenum, _checksum_counter);
251 add_idmef_object(idmef, _prelude_section, "SHA1");
252 snprintf(_prelude_section,128,"alert.target(0).file(%d).checksum(%d).value",filenum, _checksum_counter);
253 add_idmef_object(idmef, _prelude_section, sha1);
259 debug1("%s: DEBUG: owner = %s.", ARGV0, owner);
260 snprintf(_prelude_section,128,"alert.target(0).file(%d).File_Access(%d).user_id.number",filenum,FILE_USER);
261 add_idmef_object(idmef, _prelude_section,owner);
262 snprintf(_prelude_section,128,"alert.target(0).file(%d).File_Access(%d).user_id.type",filenum,FILE_USER);
263 add_idmef_object(idmef, _prelude_section, "user-privs");
265 /*add the group owner */
267 debug1("%s: DEBUG: gowner = %s.", ARGV0, gowner);
268 snprintf(_prelude_section,128,"alert.target(0).file(%d).File_Access(%d).user_id.number",filenum,FILE_GROUP);
269 add_idmef_object(idmef, _prelude_section,gowner);
270 snprintf(_prelude_section,128,"alert.target(0).file(%d).File_Access(%d).user_id.type",filenum,FILE_GROUP);
271 add_idmef_object(idmef, _prelude_section, "group-privs");
273 /*add the permissions */
275 if (perm & S_IWUSR) {
276 snprintf(_prelude_section,128,"alert.target(0).file(%d).File_Access(%d).permission(0)",filenum,FILE_USER);
277 add_idmef_object(idmef, _prelude_section,"write");
278 snprintf(_prelude_section,128,"alert.target(0).file(%d).File_Access(%d).permission(1)",filenum,FILE_USER);
279 add_idmef_object(idmef, _prelude_section,"delete");
281 if (perm & S_IXUSR) {
282 snprintf(_prelude_section,128,"alert.target(0).file(%d).File_Access(%d).permission(2)",filenum,FILE_USER);
283 add_idmef_object(idmef, _prelude_section,"execute");
285 if (perm & S_IRUSR ) {
286 snprintf(_prelude_section,128,"alert.target(0).file(%d).File_Access(%d).permission(3)",filenum,FILE_USER);
287 add_idmef_object(idmef, _prelude_section,"read");
289 if (perm & S_ISUID) {
290 snprintf(_prelude_section,128,"alert.target(0).file(%d).File_Access(%d).permission(4)",filenum,FILE_USER);
291 add_idmef_object(idmef, _prelude_section,"executeAs");
294 if (perm & S_IWGRP) {
295 snprintf(_prelude_section,128,"alert.target(0).file(%d).File_Access(%d).permission(0)",filenum,FILE_GROUP);
296 add_idmef_object(idmef, _prelude_section,"write");
297 snprintf(_prelude_section,128,"alert.target(0).file(%d).File_Access(%d).permission(1)",filenum,FILE_GROUP);
298 add_idmef_object(idmef, _prelude_section,"delete");
300 if (perm & S_IXGRP) {
301 snprintf(_prelude_section,128,"alert.target(0).file(%d).File_Access(%d).permission(2)",filenum,FILE_GROUP);
302 add_idmef_object(idmef, _prelude_section,"execute");
304 if (perm & S_IRGRP ) {
305 snprintf(_prelude_section,128,"alert.target(0).file(%d).File_Access(%d).permission(3)",filenum,FILE_GROUP);
306 add_idmef_object(idmef, _prelude_section,"read");
308 if (perm & S_ISGID) {
309 snprintf(_prelude_section,128,"alert.target(0).file(%d).File_Access(%d).permission(4)",filenum,FILE_GROUP);
310 add_idmef_object(idmef, _prelude_section,"executeAs");
312 if (perm & S_IWOTH) {
313 snprintf(_prelude_section,128,"alert.target(0).file(%d).File_Access(%d).permission(0)",filenum,FILE_OTHER);
314 add_idmef_object(idmef, _prelude_section,"write");
315 snprintf(_prelude_section,128,"alert.target(0).file(%d).File_Access(%d).permission(1)",filenum,FILE_OTHER);
316 add_idmef_object(idmef, _prelude_section,"delete");
318 if (perm & S_IXOTH) {
319 snprintf(_prelude_section,128,"alert.target(0).file(%d).File_Access(%d).permission(2)",filenum,FILE_OTHER);
320 add_idmef_object(idmef, _prelude_section,"execute");
322 if (perm & S_IROTH ) {
323 snprintf(_prelude_section,128,"alert.target(0).file(%d).File_Access(%d).permission(3)",filenum,FILE_OTHER);
324 add_idmef_object(idmef, _prelude_section,"read");
331 void OS_PreludeLog(Eventinfo *lf)
334 int classification_counter = 0;
335 int additional_data_counter = 0;
336 char _prelude_section[128];
337 char _prelude_data[256];
338 idmef_message_t *idmef;
339 RuleInfoDetail *last_info_detail;
342 /* Generate prelude alert */
343 ret = idmef_message_new(&idmef);
345 merror("%s: OSSEC2Prelude: Cannot create IDMEF message", ARGV0);
350 add_idmef_object(idmef, "alert.assessment.impact.description",
351 lf->generated_rule->comment);
353 add_idmef_object(idmef, "alert.assessment.impact.severity",
354 (lf->generated_rule->level > 15) ? "high":
355 ossec2prelude_sev[lf->generated_rule->level]);
357 add_idmef_object(idmef, "alert.assessment.impact.completion", "succeeded");
363 /* discard, drop, deny, */
372 snprintf(_prelude_data,256,"DROP: %s", lf->action);
380 snprintf(_prelude_data,256,"CLOSED: %s", lf->action);
391 snprintf(_prelude_data,256,"ALLOW: %s", lf->action);
394 snprintf(_prelude_data,256,"%s", lf->action);
397 add_idmef_object(idmef, "alert.assessment.action(0).category", "3");
398 add_idmef_object(idmef, "alert.assessment.action(0).description", _prelude_data);
406 /* Begin Classification Infomations */
408 add_idmef_object(idmef, "alert.classification.text",
409 lf->generated_rule->comment);
412 /* The Common Vulnerabilities and Exposures (CVE) (http://www.cve.mitre.org/)
413 * infomation if present in the triggering rule
415 if(lf->generated_rule->cve)
417 snprintf(_prelude_section,128,"alert.classification.reference(%d).origin",
418 classification_counter);
419 add_idmef_object(idmef, _prelude_section, "cve");
420 snprintf(_prelude_section,128,"alert.classification.reference(%d).name",
421 classification_counter);
422 add_idmef_object(idmef, _prelude_section, lf->generated_rule->cve);
423 snprintf(_prelude_section,128,"alert.classification.reference(%d).meaning",
424 classification_counter);
425 snprintf(_prelude_data,256,"CVE:%s", lf->generated_rule->cve);
426 add_idmef_object(idmef, _prelude_section, _prelude_data);
427 classification_counter++;
430 /* Rule sid is used to create a link to the rule on the OSSEC wiki */
431 if(lf->generated_rule->sigid)
433 snprintf(_prelude_section,128,"alert.classification.reference(%d).origin",
434 classification_counter);
435 add_idmef_object(idmef, _prelude_section, "vendor-specific");
437 snprintf(_prelude_section,128,"alert.classification.reference(%d).name",
438 classification_counter);
439 snprintf(_prelude_data,256,"Rule:%d",lf->generated_rule->sigid);
440 add_idmef_object(idmef, _prelude_section, _prelude_data);
442 snprintf(_prelude_section,128,"alert.classification.reference(%d).meaning",
443 classification_counter);
444 add_idmef_object(idmef, _prelude_section, "OSSEC Rule Wiki Documentation");
446 snprintf(_prelude_section,128,"alert.classification.reference(%d).url",
447 classification_counter);
448 snprintf(_prelude_data, 256,"http://www.ossec.net/wiki/Rule:%d",
449 lf->generated_rule->sigid);
450 add_idmef_object(idmef, _prelude_section, _prelude_data);
452 classification_counter++;
455 /* Extended Info Details */
456 for (last_info_detail = lf->generated_rule->info_details;
457 last_info_detail != NULL;
458 last_info_detail = last_info_detail->next)
460 if (last_info_detail->type == RULEINFODETAIL_LINK)
462 snprintf(_prelude_section,128,"alert.classification.reference(%d).origin",
463 classification_counter);
464 add_idmef_object(idmef, _prelude_section, "vendor-specific");
466 snprintf(_prelude_section,128,"alert.classification.reference(%d).name",
467 classification_counter);
468 snprintf(_prelude_data,256,"Rule:%d link",lf->generated_rule->sigid);
469 add_idmef_object(idmef, _prelude_section, _prelude_data);
470 snprintf(_prelude_section,128,"alert.classification.reference(%d).url",
471 classification_counter);
472 add_idmef_object(idmef, _prelude_section, last_info_detail->data);
474 classification_counter++;
476 else if(last_info_detail->type == RULEINFODETAIL_TEXT)
478 snprintf(_prelude_section,128,"alert.classification.reference(%d).origin",
479 classification_counter);
480 add_idmef_object(idmef, _prelude_section, "vendor-specific");
482 snprintf(_prelude_section,128,"alert.classification.reference(%d).name",
483 classification_counter);
484 snprintf(_prelude_data,256,"Rule:%d info",lf->generated_rule->sigid);
485 add_idmef_object(idmef, _prelude_section, _prelude_data);
487 snprintf(_prelude_section,128,"alert.classification.reference(%d).meaning",
488 classification_counter);
489 add_idmef_object(idmef, _prelude_section, last_info_detail->data);
490 classification_counter++;
494 snprintf(_prelude_section,128,"alert.classification.reference(%d).origin",
495 classification_counter);
496 switch(last_info_detail->type)
498 case RULEINFODETAIL_CVE:
499 add_idmef_object(idmef, _prelude_section, "cve");
501 case RULEINFODETAIL_OSVDB:
502 add_idmef_object(idmef, _prelude_section, "osvdb");
504 case RULEINFODETAIL_BUGTRACK:
505 add_idmef_object(idmef, _prelude_section, "bugtraqid");
508 add_idmef_object(idmef, _prelude_section, "vendor-specific");
511 snprintf(_prelude_section,128,"alert.classification.reference(%d).name",
512 classification_counter);
513 add_idmef_object(idmef, _prelude_section, last_info_detail->data);
518 /* Break ok the list of groups on the "," boundry
519 * For each section create a prelude reference classification
520 * that points back to the the OSSEC wiki for more infomation.
522 if(lf->generated_rule->group)
525 char new_generated_rule_group[256];
526 new_generated_rule_group[255] = '\0';
527 strncpy(new_generated_rule_group, lf->generated_rule->group, 255);
528 copy_group = strtok(new_generated_rule_group, ",");
530 snprintf(_prelude_section,128,"alert.classification.reference(%d).origin",
531 classification_counter);
532 add_idmef_object(idmef, _prelude_section, "vendor-specific");
534 snprintf(_prelude_section,128,"alert.classification.reference(%d).name",
535 classification_counter);
536 snprintf(_prelude_data,256,"Group:%s",copy_group);
537 add_idmef_object(idmef, _prelude_section, _prelude_data);
539 snprintf(_prelude_section,128,"alert.classification.reference(%d).meaning",
540 classification_counter);
541 add_idmef_object(idmef, _prelude_section, "OSSEC Group Wiki Documenation");
543 snprintf(_prelude_section,128,"alert.classification.reference(%d).url",
544 classification_counter);
545 snprintf(_prelude_data,256,"http://www.ossec.net/wiki/Group:%s",
547 add_idmef_object(idmef, _prelude_section, _prelude_data);
549 classification_counter++;
550 copy_group = strtok(NULL, ",");
553 } /* end classification block */
557 /* Begin Node infomation block */
559 /* Setting source info. */
560 add_idmef_object(idmef, "alert.source(0).Spoofed", "no");
561 add_idmef_object(idmef, "alert.source(0).Node.Address(0).address",
563 add_idmef_object(idmef, "alert.source(0).Service.port", lf->srcport);
567 add_idmef_object(idmef, "alert.source(0).User.UserId(0).name", lf->srcuser);
572 add_idmef_object(idmef, "alert.target(0).Service.name", lf->program_name);
573 add_idmef_object(idmef, "alert.target(0).Spoofed", "no");
577 add_idmef_object(idmef, "alert.target(0).Node.Address(0).address",
583 char new_prelude_target[256];
585 new_prelude_target[255] = '\0';
586 strncpy(new_prelude_target, lf->hostname, 255);
588 /* The messages can have the file, so we need to remove it.
590 * enigma->/var/log/authlog
591 * (esqueleto2) 192.168.2.99->/var/log/squid/access.log
593 tmp_str = strstr(new_prelude_target, "->");
598 add_idmef_object(idmef, "alert.target(0).Node.Address(0).address",
601 add_idmef_object(idmef, "alert.target(0).Service.name", lf->hostname);
602 add_idmef_object(idmef, "alert.target(0).Service.port", lf->dstport);
606 add_idmef_object(idmef, "alert.target(0).User.category", "2");
607 add_idmef_object(idmef, "alert.target(0).User.UserId(0).name", lf->dstuser);
609 } /* end Node infomation block */
612 /* Setting source file. */
613 add_idmef_object(idmef, "alert.additional_data(0).type", "string");
614 add_idmef_object(idmef, "alert.additional_data(0).meaning", "Source file");
615 add_idmef_object(idmef, "alert.additional_data(0).data", lf->location);
616 additional_data_counter++;
619 /* Setting full log. */
620 add_idmef_object(idmef, "alert.additional_data(1).type", "string");
621 add_idmef_object(idmef, "alert.additional_data(1).meaning", "Full Log");
622 add_idmef_object(idmef, "alert.additional_data(1).data", lf->full_log);
623 additional_data_counter++;
625 idmef_alert_set_analyzer(idmef_message_get_alert(idmef),
627 (prelude_client_get_analyzer(prelude_client)),
629 debug1("%s: DEBUG: lf->filename = %s.", ARGV0, lf->filename);
631 FileAccess_PreludeLog(idmef,
639 FileAccess_PreludeLog(idmef,
647 debug1("%s: DEBUG: done with alert.target(0).file(1)", ARGV0);
650 debug1("%s: DEBUG: Sending IDMEF alert", ARGV0);
651 prelude_client_send_idmef(prelude_client, idmef);
652 debug1("%s: DEBUG: destroying IDMEF alert", ARGV0);
653 idmef_message_destroy(idmef);