Created
September 15, 2010 20:50
-
-
Save sethhall/581458 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/configure.in b/configure.in | |
index c820a9a..d754ed9 100644 | |
--- a/configure.in | |
+++ b/configure.in | |
@@ -928,6 +928,43 @@ if test "x$enable_aruba" = "xyes"; then | |
CPPFLAGS="$CPPFLAGS -DARUBA" | |
fi | |
+AC_ARG_ENABLE(bro, | |
+[ --enable-bro Enable Bro output plugin], | |
+ enable_bro="$enableval", enable_bro="no") | |
+AC_ARG_WITH(broccoli, | |
+[ --with-broccoli=DIR Prefix where libbroccoli is installed | |
+ for Bro output plugin support (optional)], | |
+ [ with_broccoli="$withval" ], | |
+ [ with_broccoli="no" ]) | |
+if test "x$enable_bro" = "xyes"; then | |
+ if test -d $withval; then | |
+ broccoli_directory="$withval $default_directory"; | |
+ else | |
+ broccoli_directory="$default_directory /usr/local/bro"; | |
+ fi | |
+ | |
+ AC_MSG_CHECKING(for broccoli) | |
+ | |
+ for i in $broccoli_directory; do | |
+ if test -x "$i/bin/broccoli-config"; then | |
+ BROCCOLI_DIR="$i" | |
+ fi | |
+ done | |
+ | |
+ if test -z "$BROCCOLI_DIR"; then | |
+ tmp="" | |
+ for i in $broccoli_directory; do | |
+ tmp="$tmp $i/include" | |
+ done | |
+ FAIL_MESSAGE("Broccoli header file (broccoli.h)", $tmp) | |
+ fi | |
+ | |
+ AC_MSG_RESULT(yes) | |
+ LDFLAGS="${LDFLAGS} `${BROCCOLI_DIR}/bin/broccoli-config --libs`" | |
+ CPPFLAGS="${CPPFLAGS} `${BROCCOLI_DIR}/bin/broccoli-config --cflags`" | |
+ LIBS="${LIBS} -lbroccoli" | |
+fi | |
+ | |
# let's make some fixes.. | |
CFLAGS=`echo $CFLAGS | sed -e 's/-I\/usr\/include //g'` | |
diff --git a/etc/barnyard2.conf b/etc/barnyard2.conf | |
index 8499235..3009dc5 100644 | |
--- a/etc/barnyard2.conf | |
+++ b/etc/barnyard2.conf | |
@@ -189,6 +189,15 @@ input unified2 | |
# output alert_cef: LOG_AUTH LOG_INFO | |
# | |
+# alert_bro | |
+#----------------------------- | |
+# | |
+# Purpose: Send alerts to a Bro-IDS instance. | |
+# | |
+# Arguments: hostname:port | |
+# | |
+# Examples: | |
+# output alert_bro: 127.0.0.1:47757 | |
# alert_fast | |
#----------------------------- | |
diff --git a/src/output-plugins/Makefile.am b/src/output-plugins/Makefile.am | |
index 9e8cc06..6636edd 100644 | |
--- a/src/output-plugins/Makefile.am | |
+++ b/src/output-plugins/Makefile.am | |
@@ -5,6 +5,7 @@ noinst_LIBRARIES = libspo.a | |
libspo_a_SOURCES = \ | |
spo_alert_arubaaction.c spo_alert_arubaaction.h \ | |
+spo_alert_bro.c spo_alert_bro.h \ | |
spo_alert_cef.c spo_alert_cef.h \ | |
spo_alert_fast.c spo_alert_fast.h \ | |
spo_alert_full.c spo_alert_full.h \ | |
diff --git a/src/output-plugins/spo_alert_bro.c b/src/output-plugins/spo_alert_bro.c | |
new file mode 100644 | |
index 0000000..2a9f727 | |
--- /dev/null | |
+++ b/src/output-plugins/spo_alert_bro.c | |
@@ -0,0 +1,274 @@ | |
+/* | |
+** Copyright (C) 2010 Seth Hall <seth@icir.org> | |
+** | |
+** This program is 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 Free Software Foundation. You may not use, modify or | |
+** distribute this program under any other version of the GNU General | |
+** Public License. | |
+** | |
+** This program is distributed in the hope that it will be useful, | |
+** but WITHOUT ANY WARRANTY; without even the implied warranty of | |
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
+** GNU General Public License for more details. | |
+** | |
+** You should have received a copy of the GNU General Public License | |
+** along with this program; if not, write to the Free Software | |
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
+*/ | |
+/* $Id$ */ | |
+ | |
+/* spo_alert_Bro | |
+ * | |
+ * This module sends alerts to the Bro-IDS as Bro events using the Bro | |
+ * communications protocol. | |
+ * | |
+ */ | |
+ | |
+#ifdef HAVE_CONFIG_H | |
+#include "config.h" | |
+#endif | |
+ | |
+#ifdef BROCCOLI | |
+ | |
+#include <sys/types.h> | |
+#include <stdlib.h> | |
+#ifdef HAVE_STRINGS_H | |
+#include <strings.h> | |
+#endif | |
+ | |
+#include "broccoli.h" | |
+ | |
+#include "barnyard2.h" | |
+#include "decode.h" | |
+#include "debug.h" | |
+#include "map.h" | |
+#include "mstring.h" | |
+#include "parser.h" | |
+#include "strlcatu.h" | |
+#include "strlcpyu.h" | |
+#include "plugbase.h" | |
+#include "unified2.h" | |
+#include "util.h" | |
+ | |
+extern OptTreeNode *otn_tmp; | |
+ | |
+void AlertBroSetup(void); | |
+void AlertBroInit(char *); | |
+void AlertBro(Packet *, void *, u_int32_t, void *); | |
+void AlertBroCleanExit(int, void *); | |
+void AlertBroRestart(int, void *); | |
+ | |
+static BroConn *bro_conn; | |
+ | |
+/* | |
+ * Function: AlertBroSetup() | |
+ * | |
+ * Purpose: Registers the output plugin keyword and initialization | |
+ * function into the output plugin list. This is the function that | |
+ * gets called from InitOutputPlugins() in plugbase.c. | |
+ * | |
+ * Arguments: None. | |
+ * | |
+ * Returns: void function | |
+ * | |
+ */ | |
+void AlertBroSetup(void) | |
+{ | |
+ /* link the preprocessor keyword to the init function in | |
+ the preproc list */ | |
+ RegisterOutputPlugin("alert_bro", OUTPUT_TYPE_FLAG__ALERT, AlertBroInit); | |
+ DEBUG_WRAP(DebugMessage(DEBUG_INIT,"Output plugin: Alert-Bro is setup...\n");); | |
+} | |
+ | |
+ | |
+/* | |
+ * Function: AlertBroInit(char *) | |
+ * | |
+ * Purpose: Makes the connection to Bro, links the preproc function | |
+ * into the function list. | |
+ * | |
+ * Arguments: args => ptr to argument string | |
+ * | |
+ * Returns: void function | |
+ * | |
+ */ | |
+void AlertBroInit(char *args) | |
+{ | |
+ char *host_string = args; | |
+ | |
+ bro_init(NULL); | |
+ DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Output: Alert-Bro Initialized\n");); | |
+ | |
+ if ( !(bro_conn = bro_conn_new_str(host_string, | |
+ BRO_CFLAG_RECONNECT | BRO_CFLAG_ALWAYS_QUEUE )) ) | |
+ { | |
+ FatalError("Could not get Bro connection handle.\n", host_string); | |
+ } | |
+ bro_conn_set_class(bro_conn, "barnyard"); | |
+ LogMessage("alert_bro Connecting to Bro (%s)...", host_string); | |
+ if ( !bro_conn_connect(bro_conn) ) | |
+ { | |
+ FatalError("failed!\nCould not connect to Bro!\n"); | |
+ } | |
+ LogMessage("done.\n"); | |
+ | |
+ DEBUG_WRAP(DebugMessage(DEBUG_INIT,"Linking Bro alert function to call list...\n");); | |
+ /* Set the preprocessor function into the function list */ | |
+ AddFuncToOutputList(AlertBro, OUTPUT_TYPE__ALERT, 0); | |
+ AddFuncToCleanExitList(AlertBroCleanExit, 0); | |
+ AddFuncToRestartList(AlertBroRestart, 0); | |
+} | |
+ | |
+ | |
+/* | |
+ * Function: AlertBro(Packet *) | |
+ * | |
+ * Arguments: p => pointer to the current packet data struct | |
+ * | |
+ * Returns: void function | |
+ * | |
+ */ | |
+void AlertBro(Packet *p, void *event, u_int32_t event_type, void *arg) | |
+{ | |
+ BroEvent *ev; | |
+ SigNode *sn; | |
+ ClassType *cn; | |
+ ReferenceNode *rn; | |
+ | |
+ Unified2EventCommon *uevent = (Unified2EventCommon *) event; | |
+ BroPort src_p; | |
+ BroPort dst_p; | |
+ | |
+ if ( p == NULL || event == NULL ) | |
+ { | |
+ return; | |
+ } | |
+ | |
+ sn = GetSigByGidSid(ntohl(uevent->generator_id), | |
+ ntohl(uevent->signature_id)); | |
+ | |
+ if(p && IPH_IS_VALID(p)) | |
+ { | |
+ ev = bro_event_new("barnyard_alert"); | |
+ | |
+ // First value | |
+ BroRecord *packet_id = bro_record_new(); | |
+ src_p.port_num = dst_p.port_num = 0; | |
+ // Broccoli's protocol handling is sort of broken at the moment | |
+ // it segfaults when doing bro_record_add_val if not tcp, udp, or icmp | |
+ // waiting on ticket: http://tracker.icir.org/bro/ticket/278 | |
+ src_p.port_proto = dst_p.port_proto = IPPROTO_TCP; | |
+ if(GET_IPH_PROTO(p) != 255) | |
+ { | |
+ src_p.port_proto = dst_p.port_proto = GET_IPH_PROTO(p); | |
+ if((GET_IPH_PROTO(p) == IPPROTO_ICMP) && p->icmph) | |
+ { | |
+ src_p.port_num = htons(p->icmph->type); | |
+ dst_p.port_num = htons(p->icmph->code); | |
+ } else { | |
+ src_p.port_num = p->sp; | |
+ dst_p.port_num = p->dp; | |
+ } | |
+ } | |
+ | |
+ bro_record_add_val(packet_id, "src_ip", BRO_TYPE_IPADDR, NULL, &GET_SRC_ADDR(p)); | |
+ bro_record_add_val(packet_id, "src_p", BRO_TYPE_PORT, NULL, &src_p); | |
+ bro_record_add_val(packet_id, "dst_ip", BRO_TYPE_IPADDR, NULL, &GET_DST_ADDR(p)); | |
+ bro_record_add_val(packet_id, "dst_p", BRO_TYPE_PORT, NULL, &dst_p); | |
+ bro_event_add_val(ev, BRO_TYPE_RECORD, "packet_id", packet_id); | |
+ bro_record_free(packet_id); | |
+ | |
+ // Second value | |
+ BroRecord *sad = bro_record_new(); | |
+ uint32_t sensor_id_hl = ntohl(uevent->sensor_id); | |
+ bro_record_add_val(sad, "sensor_id", BRO_TYPE_COUNT, NULL, &sensor_id_hl); | |
+ double ts = (double) ntohl(uevent->event_second) + (((double) ntohl(uevent->event_microsecond))/1000000); | |
+ bro_record_add_val(sad, "ts", BRO_TYPE_TIME, NULL, &ts); | |
+ uint32_t signature_id_hl = ntohl(uevent->signature_id); | |
+ bro_record_add_val(sad, "signature_id", BRO_TYPE_COUNT, NULL, &signature_id_hl); | |
+ uint32_t generator_id_hl = ntohl(uevent->generator_id); | |
+ bro_record_add_val(sad, "generator_id", BRO_TYPE_COUNT, NULL, &generator_id_hl); | |
+ uint32_t signature_revision_hl = ntohl(uevent->signature_revision); | |
+ bro_record_add_val(sad, "signature_revision", BRO_TYPE_COUNT, NULL, &signature_revision_hl); | |
+ uint32_t classification_id_hl = ntohl(uevent->classification_id); | |
+ bro_record_add_val(sad, "classification_id", BRO_TYPE_COUNT, NULL, &classification_id_hl); | |
+ BroString class_bs; | |
+ cn = ClassTypeLookupById(barnyard2_conf, ntohl(uevent->classification_id)); | |
+ bro_string_init(&class_bs); | |
+ bro_string_set(&class_bs, cn->name); | |
+ bro_record_add_val(sad, "classification", BRO_TYPE_STRING, NULL, &class_bs); | |
+ bro_string_cleanup(&class_bs); | |
+ uint32_t priority_id_hl = ntohl(uevent->priority_id); | |
+ bro_record_add_val(sad, "priority_id", BRO_TYPE_COUNT, NULL, &priority_id_hl); | |
+ uint32_t event_id_hl = ntohl(uevent->event_id); | |
+ bro_record_add_val(sad, "event_id", BRO_TYPE_COUNT, NULL, &event_id_hl); | |
+ //BroSet *ref_set = bro_set_new(); | |
+ //BroString ref_name_bs; | |
+ //rn = sn->refs; | |
+ //while(rn) | |
+ //{ | |
+ // bro_string_init(&ref_name_bs); | |
+ // bro_string_set(&ref_name_bs, rn->system->name); | |
+ // bro_set_insert(ref_set, BRO_TYPE_STRING, &ref_name_bs); | |
+ // bro_string_cleanup(&ref_name_bs); | |
+ // rn = rn->next; | |
+ //} | |
+ //bro_record_add_val(sad, "references", BRO_TYPE_SET, NULL, ref_set); | |
+ //bro_set_free(ref_set); | |
+ | |
+ bro_event_add_val(ev, BRO_TYPE_RECORD, "barnyard_alert_data", sad); | |
+ bro_record_free(sad); | |
+ | |
+ // Third value | |
+ BroString msg_bs; | |
+ bro_string_init(&msg_bs); | |
+ bro_string_set(&msg_bs, sn->msg); | |
+ bro_event_add_val(ev, BRO_TYPE_STRING, NULL, &msg_bs); | |
+ bro_string_cleanup(&msg_bs); | |
+ | |
+ // Fourth value | |
+ BroString contents_bs; | |
+ bro_string_init(&contents_bs); | |
+ bro_string_set_data(&contents_bs, (uchar *) p->data, p->dsize); | |
+ bro_event_add_val(ev, BRO_TYPE_STRING, NULL, &contents_bs); | |
+ bro_string_cleanup(&contents_bs); | |
+ | |
+ // send and free the event | |
+ bro_event_send(bro_conn, ev); | |
+ bro_event_free(ev); | |
+ } | |
+ else | |
+ { | |
+ // Not bothering with alerts using faked or undecodeable packets. | |
+ LogMessage("WARNING (Bro) faked or undecodeable packet: %s\n", sn->msg); | |
+ } | |
+ | |
+} | |
+ | |
+void AlertBroCleanExit(int signal, void *arg) | |
+{ | |
+ DEBUG_WRAP(DebugMessage(DEBUG_LOG, "AlertBroCleanExit\n");); | |
+ int remaining=0; | |
+ while (bro_event_queue_length(bro_conn) > 0) | |
+ { | |
+ remaining = bro_event_queue_flush(bro_conn); | |
+ LogMessage("(Bro) %d events left to flush.\n", remaining); | |
+ } | |
+ bro_conn_delete(bro_conn); | |
+} | |
+ | |
+void AlertBroRestart(int signal, void *arg) | |
+{ | |
+ DEBUG_WRAP(DebugMessage(DEBUG_LOG, "AlertBroRestartFunc\n");); | |
+ int remaining=0; | |
+ while (bro_event_queue_length(bro_conn) > 0) | |
+ { | |
+ remaining = bro_event_queue_flush(bro_conn); | |
+ LogMessage("(Bro) %d events left to flush.\n", remaining); | |
+ } | |
+ if(!bro_conn_reconnect(bro_conn)) | |
+ FatalError("Could not connect to Bro!\n"); | |
+} | |
+ | |
+#endif /* BROCCOLI */ | |
\ No newline at end of file | |
diff --git a/src/output-plugins/spo_alert_bro.h b/src/output-plugins/spo_alert_bro.h | |
new file mode 100644 | |
index 0000000..1b4c567 | |
--- /dev/null | |
+++ b/src/output-plugins/spo_alert_bro.h | |
@@ -0,0 +1,27 @@ | |
+/* | |
+** Copyright (C) 2010 Seth Hall <seth@icir.org> | |
+** | |
+** This program is 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 Free Software Foundation. You may not use, modify or | |
+** distribute this program under any other version of the GNU General | |
+** Public License. | |
+** | |
+** This program is distributed in the hope that it will be useful, | |
+** but WITHOUT ANY WARRANTY; without even the implied warranty of | |
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
+** GNU General Public License for more details. | |
+** | |
+** You should have received a copy of the GNU General Public License | |
+** along with this program; if not, write to the Free Software | |
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
+*/ | |
+ | |
+/* $Id$ */ | |
+ | |
+#ifndef __SPO_BROCCOLI_H__ | |
+#define __SPO_BROCCOLI_H__ | |
+ | |
+void AlertBroSetup(void); | |
+ | |
+#endif /* __SPO_BROCOLLI_H__ */ | |
diff --git a/src/plugbase.c b/src/plugbase.c | |
index 20a79a1..af99a27 100644 | |
--- a/src/plugbase.c | |
+++ b/src/plugbase.c | |
@@ -56,6 +56,7 @@ | |
/* built-in output plugins */ | |
#include "output-plugins/spo_alert_arubaaction.h" | |
+#include "output-plugins/spo_alert_bro.h" | |
#include "output-plugins/spo_alert_cef.h" | |
#include "output-plugins/spo_alert_fast.h" | |
#include "output-plugins/spo_alert_full.h" | |
@@ -340,6 +341,10 @@ void RegisterOutputPlugins(void) | |
AlertPreludeSetup(); | |
#endif | |
+#ifdef BROCCOLI | |
+ AlertBroSetup(); | |
+#endif | |
+ | |
AlertTestSetup(); | |
PlatypusSetup(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment