Tải bản đầy đủ (.pdf) (76 trang)

snort 2.1 intrusion detection second edition phần 9 pot

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (1.52 MB, 76 trang )

295_Snort2e_11.qxd 5/5/04 6:58 PM Page 578
578 Chapter 11 • Mucking Around with Barnyard
configuration files that will allow us to occasionally extract specific data from the
unified files. Finally, we will add the configurations necessary to view alerts on
the console in real-time.
Remote Syslog Alerting
The first capability our system needs is to be able to send alerts to a remote
syslog server. While this could be accomplished by enabling syslog alerting
directly in Snort, we want to make use of some of the additional features found
in the alert_syslog2 output plug-in in Barnyard. For this output, we will be using
a syslog server with the hostname “chips.” However, this particular syslog server
has been configured to listen for syslog messages on a nondefault port; instead of
using UDP port 514, it listens for messages on port 25451. In addition, instead of
using the default tag for the alerts, we want to use the string IDS-Alert.
Additionally, instead of the default location, gen-msg.map and sid-msg.map are
installed in /var/snort/rules. We are going to specify these files in the Barnyard
configuration file instead of using the command-line options. For this configura-
tion, our Barnyard configuration file looks like:
config sid-msg-map: /var/snort/rules/sid-msg.map
config gen-msg-map: /var/snort/rules/gen-msg.map
output alert_syslog2: syslog_host: chips; syslog_port: 25451; \
tag: IDS-Alert;
Since we anticipate having multiple Barnyard configurations, we have saved
this configuration to the file /etc/snort/bysyslog.conf.To verify that we config-
ured the output plug-in correctly, we run Barnyard with the –R command and
look at the section for the output plug-ins enabled for alert records. Doing so, we
get the following output:
OpAlertSyslog2 configured
Syslog Host/Port: chips:25451/udp
Syslog Facility: LOCAL7(23)
Syslog Severity: NOTICE(5)


Hostname: phlegethon
Tag: IDS-Alert
This matches what we want for our syslog configuration so we know we
have the output plug-in configured correctly. If we wanted to verify that the
www.syngress.com
Simpo PDF Merge and Split Unregistered Version -
295_Snort2e_11.qxd 5/5/04 6:58 PM Page 579
Mucking Around with Barnyard • Chapter 11 579
configuration works correctly, we could run Barnyard in batch-processing mode
to test it.
OINK!
When using batch-processing mode to test a configuration, it is wise to
use a test unified file that only has a small number of records in it. The
last thing that most administrators want is to test a particular alerting
configuration by sending thousands of alerts through it. Therefore, it is
recommended to generate some unified files that only have a handful of
records in them for testing purposes.
Now we need to determine the command-line options that we need to
specify. From our Snort configuration, we know that the base filename for the
unified alert files is unified.alert. We will need to specify this value as the argu-
ment to the –f option. Additionally, since we plan to run multiple Barnyard pro-
cesses simultaneously in the future, we are going to want to specify a nondefault
PID file. We are going to use /var/snort/run/bysyslog.pid for our PID file. Finally,
since we want Barnyard to run as a daemon process, we will specify the –D
option. Combining all of this with the option to specify the configuration file,
we get the following command line:
barnyard –c /etc/snort/bysyslog.conf –X /var/snort/run/bysyslog.pid –D \
–f unified.alert
Unfortunately, after trying to use this command we notice a problem. In par-
ticular, every time we start it, all of the old alerts are also sent to the syslog server,

which is definitely not what we want.To solve this problem we need to either
enable bookmark support or configure Barnyard to only process new records (or
both). Deciding which we want to use depends on what data we want the syslog
server to see. For this scenario, our syslog server, chips, wants to see all of the
events since we installed this configuration.Thus, if this process is not running
for some reason, we still want to receive the events received during that time
period. However, we do not want to receive any events that existed before we
first added this alerting type.To accomplish this we will enable both the new
records only option and the bookmark option.This way, if there is no bookmark
file, as would be the case when we first install this configuration, Barnyard will
start processing at the most recently received event, and if there is a bookmark
www.syngress.com
Simpo PDF Merge and Split Unregistered Version -
295_Snort2e_11.qxd 5/5/04 6:58 PM Page 580
580 Chapter 11 • Mucking Around with Barnyard
file, Barnyard will start processing at the first event after the ones it has already
processed. Keeping with the file naming we have used so far, we are going to use
/var/snort/run/bysyslog.bookmark as the bookmark file for this configuration.
Updating our command line accordingly gives us:
barnyard –c /etc/snort/bysyslog.conf –X /var/snort/run/bysyslog.pid –D \
-f unified.alert –w /var/snort/run/bysyslog.bookmark –n
This command line gives us exactly what we want for our syslog reporting
and we can now add it to our system startup scripts. If we ever need to stop this
Barnyard process from running, we can send a signal to tell it to exit. Since the
process ID is stored in the PID file, we can read it from there instead of having
to find it in a process listing.To stop the Barnyard process we’ve started, use this
command:
kill `cat /var/snort/run/bysyslog.pid`
Database Logging
After receiving syslog alerts for a while, we have decided that we want to start

using some of the analysis tools that require the data to be stored in a database.
While we still want to keep our syslog alerts, we now also need to insert the
alerts into a database using the standard Snort database schema. We have read the
Snort documentation and have managed to load the schema onto our MySQL
database server.The server is running on the host named pizza and we named
the database snort. Additionally, we created a database user named snortdb with a
password of abc123. We have used the mysql command-line tool to connect to
the remote database to verify that we can connect to the database server and
access the database. Now, all that is left is to configure Barnyard to send data to
the database. We have decided that in addition to the alert information, we also
want to have full packet details inserted into the database.
Creating the appropriate configuration file for database logging requires a
little more work than the one for syslog alerting. In addition to specifying the
output plug-in configuration and where to load the message maps from, we may
also need to configure the interface, BPF filter, and hostname values. For this
particular system, we are running Snort of eth1 and we are not using a BPF filter.
We want to use the default hostname, so we will not need to specify an alternate
value in the configuration file. Since we want packet logs, we know we need to
use the log_acid_db output plug-in. Combining all this information, we have
created the following configuration file and saved it to /etc/snort/bymysql.con.:
www.syngress.com
Simpo PDF Merge and Split Unregistered Version -
295_Snort2e_11.qxd 5/5/04 6:58 PM Page 581
Mucking Around with Barnyard • Chapter 11 581
config sid-msg-map: /var/snort/rules/sid-msg.map
config gen-msg-map: /var/snort/rules/gen-msg.map
config interface: eth1
output log_acid_db: mysql, database snort, server pizza, \
user snortdb, password abc123, detail full
The command line for logging events to a database is similar to the com-

mand line for syslog alerts. We still want to run in continual-processing mode, we
still need to specify an alternate PID file, we still want to enable bookmark sup-
port to avoid reprocessing the same data, and we still want to run as a daemon.
There are a few changes that we must make. First, we will need to change the
filenames for the configuration file, PID file, and bookmark file. Second, since we
need to process unified log files instead of unified alert files, we need to change
the base filename specified with the –f option. Finally, unlike our syslog case,
when we first start processing data, we want to insert all of the old records into
the database.Therefore, we will omit the –n option. Making all these changes
gives us the following command line:
barnyard –c /etc/snort/bymysql.conf –X /var/snort/run/bymysql.pid –D \
-f unified.log –w /var/snort/run/bymysql.bookmark
This command line runs Barnyard in the configuration we want. If there is a
bookmark file present, then Barnyard starts processing the next record that has
been processed. If the bookmark file is not found, then Barnyard will process all
of the existing unified log files before processing new records. Of course, if there
are many existing unified files, it will take some time before current records are
added to the database.
Extracting Data
So far, we have configured syslog alerting for real-time notification and database
logging for our analysis console. While this provides us with considerable flexi-
bility, we may also have the need to extract some of the alert data for other pur-
poses. Suppose, for example, that we have a report generation tool that we want
to use to create periodic reports to show to management.This tool requires that
we provide it with data in a CSV file. We would like to be able to periodically
process the unified alert data to create CSV files to use with this reporting tool.
www.syngress.com
Simpo PDF Merge and Split Unregistered Version -
295_Snort2e_11.qxd 5/5/04 6:58 PM Page 582
582 Chapter 11 • Mucking Around with Barnyard

To do so, we can use the alert_csv output plug-in.This reporting program uses
the timestamp, event type, and source and destination IP addresses, and generates
statistics about the amount, the type, and the targets of the alerts that were
detected. While we could modify the reporting program to read this data from
the database, it is far easier to provide CSV file that it already supports.This fic-
tional program expects each line of the CSV file to use the following format:
timestamp, event message, source IP address, destination IP address
Using our knowledge of the alert_csv output plug-in and the Barnyard con-
figuration file format, we can quickly write a configuration file that can be used
to generate the correct output. We have written such a file and saved it as
/etc/snort/bycsv.conf.This file contains the following configuration:
config sid-msg-map: /var/snort/rules/sid-msg.map
config gen-msg-map: /var/snort/rules/gen-msg.map
output alert_csv: report.csv timestamp,msg,srcip,dstip
Since we only want to generate these CSV files occasionally, we do not need
to run Barnyard in continual-processing mode. Instead, we will use batch-pro-
cessing mode and only run it when we need to generate a CSV file to create a
report.The command line for this is much simpler than the ones we used for our
syslog alerting and database logging. In this case, we only need to specify the
config file to use, the directory we want the output to be written to, and the file
to process. Supposing that we want the output file to be written to the directory
/var/snort/report_input/, we would use the following command:
barnyard –o –c /etc/snort/bycsv.conf –L /var/snort/reports/ <filename>
This command will process the file <filename> and create the file
/var/snort/reports/report.csv. We can then call our reporting program and tell it to
use the CSV file as its input. If we wanted to process multiple unified alert files,
we could specify multiple filenames on the previous command line.
OINK!
When using this example, we have to remember that the alert_csv
output plug-in will append data to the output file if it already exists.

Therefore, we will want to run rm –f /var/snort/reports/report.csv
before we run Barnyard.
www.syngress.com
Simpo PDF Merge and Split Unregistered Version -
295_Snort2e_11.qxd 5/5/04 6:58 PM Page 583
Mucking Around with Barnyard • Chapter 11 583
Real-Time Console Alerting
The final thing we want from our sample deployment is the capability to log in
to our IDS system and display the events to the screen as they are received.The
output from the alert_fast output plug-in meets our needs since we only need a
limited amount of information about each alert and we want it in a human-read-
able format. However, there is a severe limitation to this output plug-in for what
we want to do. We want the information displayed to the screen, while the
alert_fast output plug-in writes information to a file. While we could modify the
alert_fast plug-in to write to the screen, instead we will work around this limita-
tion by writing the output to a file and using another program, tail, to display the
events as they are written to the file.
The first thing we need to do is create the appropriate configuration file. By
now, you can probably guess what this file will look like, but will we include it
here anyway.The following is the configuration that we are going to use. We
have saved this to the file /etc/snort/byalertfast.conf.
config sid-msg-map: /var/snort/rules/sid-msg.map
config gen-msg-map: /var/snort/rules/gen-msg.map
output alert_fast: alerts.out
Now that we have our configuration file, we need to construct the command
line that we will use to run Barnyard. In this case, we want to run Barnyard in
continual-processing mode, but since we will only use this configuration occa-
sionally, we do not need to enable bookmark support. However, since we only
care about new events, we will want to include the new records only option. In
addition, since we are going to run another command to view the contents of

alerts.out, we will need to background the Barnyard process.To do this we will
use the daemon mode option and specify a PID file as we did for the syslog
alerting and database logging configurations. Finally, we will need to specify the
log directory to which we want the output to be written.The command line we
are going to use for this configuration is:
barnyard –c /etc/snort/byalertfast.conf -X /var/snort/run/byalertfast.pid \
-D -f unified.alert –n -L /var/snort/log/
www.syngress.com
Simpo PDF Merge and Split Unregistered Version -
295_Snort2e_11.qxd 5/5/04 6:58 PM Page 584
584 Chapter 11 • Mucking Around with Barnyard
Once we have started Barnyard, we will then want to start the process that
will display the events as they are written to the output file.To do this, we run
the following command:
tail –f /var/snort/log/alerts.out
Now all of the alerts will be displayed to the screen as they happen. When
we tire of watching the events scroll past at a mind-numbing rate, we simply exit
tail and then kill the Barnyard process by running:
kill `cat /var/snort/run/byalertfast.pid`
While this process works, it has several negative aspects. First, if there are any
problems with running Barnyard, all of the errors will go to syslog.Therefore,
before we start looking at the output, we need to make sure that Barnyard actually
started. Second, this process has the possibility to consume a large amount of disk
space if it is left running for a long time or we neglect to remove the output file
when we are finished. Additionally, the command line is overly complex for a
command we want to run only occasionally. In the next section, we will extend
Barnyard by adding a new output plug-in that is designed to solve these problems.
Writing a New Output Plug-In
In the previous section, we realized that displaying events from a unified alert file
to the screen was a complicated process with several deficiencies.This made the

final phase of our deployment much more complex and prone to error. It would
be much more convenient if Barnyard had a way to display the contents of a uni-
fied alert file directly to the screen instead of requiring us to write the output to a
file and then process that file with another program. If Barnyard included an
output plug-in that rendered output to the screen instead of a file, we could just
run Barnyard with the proper configuration and not have to worry about using
any other programs. Additionally, the command line would become much simpler.
Since Barnyard is an open-source program, we have the ability to add new
functionality to it. Additionally, since Barnyard uses a modular design for the
implementation of output plug-ins, it is relatively easy to add one.Therefore, to
make things work the way we want, we can add a new output plug-in designed
to satisfy our particular needs. In this section, we will cover the basics of writing
a new output plug-in and adding it to Barnyard. Since this output plug-in is
going to display alert events to console output, we are going to name it
“alert_console.”
www.syngress.com
Simpo PDF Merge and Split Unregistered Version -
295_Snort2e_11.qxd 5/5/04 6:58 PM Page 585
Mucking Around with Barnyard • Chapter 11 585
Implementing the Plug-In
As we shall see here, the basic implementation of a new output plug-in is not a
difficult task. All that is required is to set up the source files, implement a handful
of functions, and update op_plugbase to initialize the new plug-in when
Barnyard starts up.The plug-in we are implementing here is extremely simple. It
does not need to handle several of the tasks that a more complex output plug-in
may require.This level of simplicity was chosen to focus on the essentials of
writing an output plug-in instead of getting bogged down in the intricacies of
other tasks (such as connecting to a database). When implementing a new output
plug-in, it is always useful to refer to the existing output plug-ins to learn how to
handle some of the more complex tasks that may be needed.

Setting Up the Source Files
The first step when writing a new output plug-in is to create the source files.
Most of the output plug-ins contain two source files, a header file and a C file.
The alert_console output plug-in is no different and is composed of the files
op_alert_console.h (the header file) and op_alert_console.c (the C file). For manage-
ability, all of the output plug-ins are grouped together in a single directory,
src/output-plugins. We have placed the source files for the alert_console output
plug-in in this directory as well.
The Header File
The header file is used to define functions and variables that are exported from
the .c file and made available to other parts of the program. Each Barnyard
output plug-in exports exactly one function, the initialization function.The
alert_console header file is displayed in the following code.The header files for
the other output plug-ins all look very much like this one.
/*
** Copyright (C) 2004 Andrew R. Baker <>
**
** This program is distributed under the terms of version 1.0 of the
** Q Public License. See LICENSE.QPL for further details.
**
** 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.
www.syngress.com
Simpo PDF Merge and Split Unregistered Version -
295_Snort2e_11.qxd 5/5/04 6:58 PM Page 586
586 Chapter 11 • Mucking Around with Barnyard
**
*/
#ifndef __OP_ALERT_CONSOLE_H__

#define __OP_ALERT_CONSOLE_H__
void OpAlertConsole_Init();
#endif /* __OP_ALERT_CONSOLE_H__ */
The C File
The C file contains the actual implementation of the output plug-in. It is in this
file that all of the required functions are implemented.This file contains include
directives, function prototypes, and function definitions.The next section, Writing
the Functions, explains all of the required functions and shows the implementation
of each for the alert_console output plug-in. However, before we can start
implementing these, we need to create a basic C file that contains the standard
set of include directives and the output plug-in API function prototypes.This
section of op_alert_csv.c is shown in the following code:
/*
** Copyright (C) 2004 Andrew R. Baker <>
**
** This program is distributed under the terms of version 1.0 of the
** Q Public License. See LICENSE.QPL for further details.
**
** 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.
**
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "barnyard.h"
www.syngress.com
Simpo PDF Merge and Split Unregistered Version -
295_Snort2e_11.qxd 5/5/04 6:58 PM Page 587

Mucking Around with Barnyard • Chapter 11 587
#include "util.h"
#include "input-plugins/dp_alert.h"
#include "output-plugins/op_plugbase.h"
#include "classification.h"
#include "sid.h"
#include <netinet/in.h>
/* Output plug-in API functions */
static int OpAlertConsole_Setup(OutputPlugin *, char *args);
static int OpAlertConsole_Exit(OutputPlugin *);
static int OpAlertConsole_Start(OutputPlugin *, void *);
static int OpAlertConsole_Stop(OutputPlugin *);
static int OpAlertConsole_LogConfig(OutputPlugin *);
static int OpAlertConsole(void *, void *);
Writing the Functions
The most difficult part of implementing a new output plug-in is writing the
seven required functions.These functions comprise the rest of the C file for the
alert_console output plug-in.
The Init Function
The initialization, or Init, function registers the output plug-in to Barnyard.The
registration procedure is fairly straightforward. First, we call RegisterOutputPlugin
specifying the name and type of the output plug-in.The name can be just about
anything, but most of the output plug-ins include the type of the output plug-in
in the name (for example, alert_fast, log_dump).The name of the output plug-in
is the keyword that is used when configuring the output plug-in in the Barnyard
configuration file.The type of the output plug-in identifies which type of uni-
fied records the output plug-in will process.The supported types are alert, log, and
stream-stat.
This function returns a pointer to a newly created OutputPlugin object. Once
we have this object, we just need to add all of our plug-in specific functions to

it.The OutputPlugin object has member elements that are used to store references
to these functions, and we just use a simple assignment to associate them. Here is
the initialization function we wrote for the alert_console plug-in:
/* Initialize and register this output plug-in */
www.syngress.com
Simpo PDF Merge and Split Unregistered Version -
295_Snort2e_11.qxd 5/5/04 6:58 PM Page 588
588 Chapter 11 • Mucking Around with Barnyard
void OpAlertConsole_Init()
{
OutputPlugin *outputPlugin;
/* Register the output plugin */
outputPlugin = RegisterOutputPlugin("alert_console", "alert");
/* Set the functions */
outputPlugin->setupFunc = OpAlertConsole_Setup;
outputPlugin->exitFunc = OpAlertConsole_Exit;
outputPlugin->startFunc = OpAlertConsole_Start;
outputPlugin->stopFunc = OpAlertConsole_Stop;
outputPlugin->logConfigFunc = OpAlertConsole_LogConfig;
outputPlugin->outputFunc = OpAlertConsole;
}
The Setup Function
The Setup function is called whenever the output plug-in is specified in the con-
figuration file.This function must parse any arguments specified in the configura-
tion file and allocate memory for any plug-in specific data. Since our new output
plug-in does not support any configuration arguments nor does it have any plug-
in specific data, this function does not need to do anything. However, it is likely
that any other output plug-in we write will at least have some instance specific
data.The OutputPlugin object has a pointer that can be used to associate instance
specific data with it. By allocating memory for the instance specific data and

storing the memory address into outputPlugin->data, this information can be used
by the other plug-in functions.The Setup function for the alert_console output
plug-in is included here. As mentioned, this function does not perform any
actions.
static int OpAlertConsole_Setup(OutputPlugin *outputPlugin, char *args)
{
/* No instance specific data to setup */
return 0;
}
www.syngress.com
Simpo PDF Merge and Split Unregistered Version -
295_Snort2e_11.qxd 5/5/04 6:58 PM Page 589
Mucking Around with Barnyard • Chapter 11 589
For an example on processing configuration arguments and managing
instance specific data, it is recommended that you look at the implementation of
the alert_syslog2 output plug-in in the file src/output-plugins/op_alert_syslog2.c.
The Exit Function
The Exit function is related to the Setup function. While the Setup function is
used to process arguments and allocate memory for instance specific data, the
Exit function is responsible for freeing this memory. Since our output plug-in
does not have any instance specific data, this function does not have to perform
any actions. Here is the Exit function as it appears in the alert_console output
plug-in:
static int OpAlertConsole_Exit(OutputPlugin *outputPlugin)
{
/* No instance specific data to destroy */
return 0;
}
The Start Function
The Start function is used to start the output plug-in. It is in this function that

we handle all the tasks of opening output files, connecting to remote systems,
and so forth. Which of these tasks are performed and how they are accomplished
depends on what the output plug-in does. For the alert_console output plug-in,
none of these tasks is required.This function is also responsible for calling the
LogConfig function if the system verbosity is set high enough (>= 2).The Start
function for the alert_console output plug-in is listed here:
static int OpAlertConsole_Start(OutputPlugin *outputPlugin,
void *spool_header)
{
/* No instance specific handles to open */
if(pv.verbose >= 2)
OpAlertConsole_LogConfig(outputPlugin);
return 0;
}
www.syngress.com
Simpo PDF Merge and Split Unregistered Version -
295_Snort2e_11.qxd 5/5/04 6:58 PM Page 590
590 Chapter 11 • Mucking Around with Barnyard
The Stop Function
The Stop function is the partner to the Start function.This function is responsible
for closing output files, disconnecting from remote systems, and so forth. Since
the alert_console output plug-in did nothing in the Start function, this function
does not need to perform any actions. Here is the Stop function for the
alert_console output plug-in:
static int OpAlertConsole_Stop(OutputPlugin *outputPlugin)
{
/* No instance specific handles to close */
return 0;
}
The LogConfig Function

The LogConfig function was added to the output plug-in API in Barnyard 0.2.
This function is responsible for all of the output plug-in configuration messages
we saw when we were running Barnyard with the –R option.The purpose of
this function is to display all of the instance specific configuration data in a
human-readable format. How the data is displayed is dependent on the specifics
of the particular output plug-in.The LogConfig function for the alert_console
output plug-in is listed in the following:
static int OpAlertConsole_LogConfig(OutputPlugin *outputPlugin)
{
if(!outputPlugin)
return -1;
LogMessage("OpAlertConsole configured\n");
/* No instance specific configuration to display */
return 0;
}
This function is fairly straightforward, but it does use a utility function that
we have not mentioned before, LogMessage.The LogMessage function is used to
display output to the appropriate logging facility. If Barnyard is running in
daemon mode, this function will use syslog; otherwise, it will display the content
of the message to the console using stderr.This function is used in a number of
www.syngress.com
Simpo PDF Merge and Split Unregistered Version -
295_Snort2e_11.qxd 5/5/04 6:58 PM Page 591
Mucking Around with Barnyard • Chapter 11 591
places in Barnyard to report warnings and errors.The arguments to this function
are the same as the arguments to printf, a format string followed by a variable
number of arguments. It is important to remember to add “\n” to the end of the
format string. Otherwise, messages that are displayed to stderr will all run
together on a single line.
The Output Function

So far, we have implemented six functions that do either very little or nothing at
all. Now that we are on our final function, we have a considerable amount of
work to do.The output function is the function responsible for generating the
actual output.This function is called once for each unified record that Barnyard
processes. How the output is generated is dependent on the needs of the partic-
ular output plug-in. For alert_console, we modified the output function from the
alert_fast output plug-in to suit our needs.The alert_console output function is
listed here:
static int OpAlertConsole(void *context, void *data)
{
char timestamp[256];
UnifiedAlertRecord *alert = (UnifiedAlertRecord *)data;
ClassType *class;
Sid *sid = NULL;
char sip[16];
char dip[16];
if(!data)
return -1;
sid = GetSid(alert->event.sig_generator, alert->event.sig_id);
class = GetClassType(alert->event.classification);
if(RenderTimeval(&alert->ts, timestamp, 256) == -1)
{
/* could not render the timeval */
LogMessage("ERROR: OpAlertConsole failed to render timeval\n");
return -1;
}
www.syngress.com
Simpo PDF Merge and Split Unregistered Version -
295_Snort2e_11.qxd 5/5/04 6:58 PM Page 592
592 Chapter 11 • Mucking Around with Barnyard

snprintf(sip, 16, "%u.%u.%u.%u",
(alert->sip >> 24) & 0xff,
(alert->sip >> 16) & 0xff,
(alert->sip >> 8) & 0xff,
alert->sip & 0xff);
snprintf(dip, 16, "%u.%u.%u.%u",
(alert->dip >> 24) & 0xff,
(alert->dip >> 16) & 0xff,
(alert->dip >> 8) & 0xff,
alert->dip & 0xff);
if(alert->protocol == IPPROTO_TCP ||
alert->protocol == IPPROTO_UDP)
{
fprintf(stdout, "%s {%s} %s:%d -> %s:%d\n"
"[**] [%d:%d:%d] %s [**]\n"
"[Classification: %s] [Priority: %d]\n", timestamp,
protocol_names[alert->protocol], sip, alert->sp,
dip, alert->dp, alert->event.sig_generator,
alert->event.sig_id, alert->event.sig_rev,
sid ? sid->msg : "ALERT",
class ? class->name : "Unknown",
alert->event.priority);
}
else
{
fprintf(stdout, "%s {%s} %s -> %s\n"
"[**] [%d:%d:%d] %s [**]\n"
"[Classification: %s] [Priority: %d]\n", timestamp,
protocol_names[alert->protocol], sip, dip,
alert->event.sig_generator, alert->event.sig_id,

alert->event.sig_rev, sid ? sid->msg : "ALERT",
class ? class->name : "Unknown",
alert->event.priority);
}
www.syngress.com
Simpo PDF Merge and Split Unregistered Version -
295_Snort2e_11.qxd 5/5/04 6:58 PM Page 593
Mucking Around with Barnyard • Chapter 11 593
PrintXref(alert->event.sig_generator, alert->event.sig_id, stdout);
fprintf(stdout, " "
" \n");
fflush(stdout);
return 0;
}
This function illustrates a number of aspects of processing an alert record. At
various points within the function, we access member elements of the alert
record.These elements correspond to the alert record fields that we discussed
earlier in the chapter in the section Understanding the Snort Unified Files. The alert
record data structure is defined in the file src/input-plugins/dp_alert.h. Some of the
elements we access are components of the event substructure.This data structure
is used in both alert and log records and is defined in the file src/event.h.
In addition to accessing elements of the alert record, this function also uses
four utility functions: RenderTimeval, GetSid, GetClassType, and PrintXref.The
RenderTimeval function is used to render the record timestamp in a human-read-
able format.The GetSid and GetClassType functions query the meta-data that was
loaded from sid-msg.map, gen-msg.map, and classification.config and return a
SID and ClassType object, respectively.These objects contain information, such as
the message and classification description, that we use when generating output.
More information on the information available in the SID and ClassType objects
can be found by looking at the source files src/sid.h and src/classification.h.The

final function, PrintXref, prints the external references for this event.
Adding the Plug-In to op_plugbase.c
The final step in implementing the plug-in is updating op_plugbase.c to call the
initialization function. Once the function has been initialized, the output plug-in
system will handle calling all of the other functions whenever they are needed.
Adding the new output plug-in to op_plugbase.c only requires two simple modifi-
cations. First, we need to add a reference to the new output plug-in header file.
If you remember, the header file contains the definition of the new plug-in’s
www.syngress.com
Simpo PDF Merge and Split Unregistered Version -
295_Snort2e_11.qxd 5/5/04 6:58 PM Page 594
594 Chapter 11 • Mucking Around with Barnyard
initialization function.To make this modification, we add the following line
where the rest of the output plug-in include directives are found:
#include "op_alert_console.h"
The second modification that must be made is to update the
LoadOutputPlugins() to call our new initialization function.The
LoadOutputPlugins() function is called when Barnyard first starts up in order to
register all of the built-in output plug-ins. We update this function by adding the
following line before the return statement at the end of the function:
OpAlertConsole_Init();
With these two minor changes, our new output plug-in will now be available
once we have rebuilt Barnyard.
Finishing Up
Now that we have finished writing our new output plug-in, we need to rebuild
Barnyard to have it included.To do this, we are going to need a few additional
tools to those we needed when we built and installed Barnyard at the beginning
of this chapter.To ease portability across different platforms, Barnyard has been
developed using automake and autoconf. We will need both of these tools to finish
integrating our output plug-in into Barnyard.

Updating Makefile.am
Before the Barnyard build system will detect and compile our new output plug-
in, we have to tell it about the new source files (op_alert_console.c and op_alert_con-
sole.h).This is done by updating the Makefile.am file in the directory where the
new source files are located. Since we added the files in src/output-plugins, we will
need to edit src/output-plugins/Makefile.am. Let’s see what this file looks like
before we make our changes:
AUTOMAKE_OPTIONS=foreign no-dependencies
noinst_LIBRARIES = libop.a
libop_a_SOURCES = op_decode.c op_fast.c op_plugbase.c op_logdump.c \
op_decode.h op_fast.h op_plugbase.h op_logdump.h \
op_alert_syslog.c op_alert_syslog.h op_log_pcap.c op_log_pcap.h \
op_acid_db.c op_acid_db.h \
op_alert_csv.c op_alert_csv.h \
op_sguil.c op_sguil.h \
www.syngress.com
Simpo PDF Merge and Split Unregistered Version -
295_Snort2e_11.qxd 5/5/04 6:58 PM Page 595
Mucking Around with Barnyard • Chapter 11 595
op_alert_syslog2.c op_alert_syslog2.h
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/src @extra_incl@
This file tells the Barnyard build system how the files in this directory are
supposed to be built. In order to add new files, we need to add the names of our
two new source files to the libop_a_SOURCES configuration line (which is
actually on multiple lines with continuation characters). After adding these files,
the new Makefile.am contains:
AUTOMAKE_OPTIONS=foreign no-dependencies
noinst_LIBRARIES = libop.a
libop_a_SOURCES = op_decode.c op_fast.c op_plugbase.c op_logdump.c \
op_decode.h op_fast.h op_plugbase.h op_logdump.h \

op_alert_syslog.c op_alert_syslog.h op_log_pcap.c op_log_pcap.h \
op_acid_db.c op_acid_db.h \
op_alert_csv.c op_alert_csv.h \
op_sguil.c op_sguil.h \
op_alert_syslog2.c op_alert_syslog2.h \
op_alert_console.c op_alert_console.h
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/src @extra_incl@
Building Barnyard
Once we have added our source files to Makefile.am, we need to get the build
system to incorporate those changes.To save us some time and effort, the
Barnyard source distribution includes a script that runs all the required com-
mands in the correct order.Therefore, updating the build system only requires
that we run the script autojunk.sh. Once run, the build system will be updated
and we can proceed to building Barnyard.
Building Barnyard after these changes is the same process that was presented
earlier in this chapter. Basically, we now need to run the configure, make, and make
install commands. For more details on how to build Barnyard, see the section
Installing Barnyard.
Real-Time Console Alerting Redux
Now that we have our new output plug-in, we can revisit our real-time console
alerting scenario from our sample deployment. Our requirements have not
changed; we still want to be able to display new events to the console in a
www.syngress.com
Simpo PDF Merge and Split Unregistered Version -
295_Snort2e_11.qxd 5/5/04 6:58 PM Page 596
596 Chapter 11 • Mucking Around with Barnyard
human-readable format as they are detected.The alert_console output plug-in
was written to render the events in the desired format. Since this output plug-in
does not require any additional configuration, our Barnyard configuration file is
very simple. We have saved this file to /etc/snort/byconsole.conf.

config sid-msg-map: /var/snort/rules/sid-msg.map
config gen-msg-map: /var/snort/rules/gen-msg.map
output alert_console
Now all we need to do is work out what command line we need to run
Barnyard in the desired manner. We still want to run in continual-processing
mode in order to see new alerts as they are detected by Snort. We also want to
ignore any alerts that had already been detected before we started. However,
since we no longer need to run a second program to read an output file, we no
longer need to run in the background and we do not need to specify a PID file.
Finally, we want Barnyard to display a little more information about what it is
doing so we are going to increase the verbosity by 1.The command line for real-
time console alerting using the new alert_console output plug-in is:
barnyard –c /etc/snort/byconsole.conf –f unified.alert –n –v
That is much simpler than the command line we had to use before.
Additionally, when before we had to issue another command to stop Barnyard,
now we can just press Ctrl-C and Barnyard will exit. We also no longer have to
worry about any extra files using up disk space.Thus, by adding a new output
plug-in, we have extended Barnyard to better fit our needs.
Secret Capabilities of Barnyard
While not necessarily a “secret capability,” one thing can be done with Barnyard
that many users do not realize is possible: localization of alert messages. One
thing many users want to be able to do is to localize the messages for Snort
alerts. While this can be done with Snort, it requires editing each rule individu-
ally. Whenever the rules are updated, they all need to be edited again.To localize
the preprocessor alerts, you would have to edit the Snort source code. Obviously,
this is not the best use of an analyst’s time.
Barnyard provides a much easier way to localize these messages than is pos-
sible with Snort. With Barnyard, all of the message information is loaded from
the sid-msg.map and gen-msg.map files. In Snort, the messages for rules are read
www.syngress.com

Simpo PDF Merge and Split Unregistered Version -
295_Snort2e_11.qxd 5/5/04 6:58 PM Page 597
Mucking Around with Barnyard • Chapter 11 597
from the 48 rule files, and the messages for preprocessors are directly in the
source code. Moreover, the map files that Barnyard uses are primarily only the
message data. With Snort, there are also all of the other rule options as well.
Therefore, if we want to localize the alert messages when using Barnyard, we
only have to create new versions of sid-msg.map and gen-msg.map that contain
our localized messages. As new rules and preprocessor alerts are added, new
entries can simply be added to these files. However, we still need to be careful
when doing this, since Barnyard does not support the wide character encoding
that some localization may require.
www.syngress.com
Simpo PDF Merge and Split Unregistered Version -
295_Snort2e_11.qxd 5/5/04 6:58 PM Page 598
598 Chapter 11 • Mucking Around with Barnyard
Summary
Barnyard is an event-processing tool that was developed to assist Snort with the
task of generating event output. It allows the time-consuming tasks of output,
such as communicating with a database server, to be separated from the Snort
process, thus allowing Snort to spend its time processing network traffic. Snort
uses the unified file format to communicate event information to Barnyard.This
format can be used to spool Snort alert, log, and stream-stat records.
There is a multitude of configuration options available for Barnyard, both on
the command line and in the configuration file.The command-line options are
focused on how Barnyard will run.The configuration file is used to configure
the types of output that Barnyard will generate. Both the command line and the
configuration file include additional options to specify where to load event meta-
data from.The event meta-data is used to provide additional, human-readable
information about the event details.

Barnyard can run in either batch-processing mode or continual-processing
mode. In batch-processing mode, Barnyard processes all of the events contained
in the specified unified files. In continual-processing mode, new events are pro-
cessed as they are generated by Snort. Continual-processing mode is the most
appropriate mode for real-time processing of data into a database or for real-time
notifications of events. Batch-mode processing is useful for extracting event
information into formats that can be processed by other programs.
A number of output plug-ins included in Barnyard can be used to format
data in a variety of ways.The output plug-ins are capable of processing both
Snort alert and log records.The capabilities of these plug-ins range from inserting
events into a database to printing human-readable packet dumps to a file. If there
is no existing plug-in suitable for a particular situation, then the modular archi-
tecture of Barnyard allows for one to be added with a minimum of effort.
Solutions Fast Track
What Is Barnyard?
 Barnyard is a tool that was developed to assist Snort with generating
alert output.
www.syngress.com
Simpo PDF Merge and Split Unregistered Version -
295_Snort2e_11.qxd 5/5/04 6:58 PM Page 599
Mucking Around with Barnyard • Chapter 11 599
 Barnyard reads the Snort unified output files and generates output using
one of the many included output plug-ins.
 Barnyard allows Snort to spend its time processing network traffic
instead of formatting output.This allows Snort to process network traffic
at higher speeds than would otherwise be possible.
Understanding the Snort Unified Files
 The Snort unified files are used to spool event data from Snort to
Barnyard.
 Snort can generate three types of unified records: alerts, logs, and

stream-stats.
 Unified alert records contain the minimal information about an alert.
 Unified log records contain all of the event information contained in
the unified alert record, and include the packet that generated the alert.
 Unified stream-stat records are generated by the stream4 preprocessor
and include information about the TCP sessions that Snort detects.
Installing Barnyard
 Installing Barnyard requires that the source package be downloaded and
built.
 When built, Barnyard can be configured to include support for the
MySQL and PostgreSQL database servers.
 The latest released version of Barnyard can be downloaded from the
SourceForge project site.
Configuring Barnyard
 Barnyard is configured through a combination of command-line options
and configuration file directives.
 The command-line options are used to specify how Barnyard is going
to run.This includes specifying the mode of operation that will be used.
www.syngress.com
Simpo PDF Merge and Split Unregistered Version -
295_Snort2e_11.qxd 5/5/04 6:58 PM Page 600
600 Chapter 11 • Mucking Around with Barnyard
 The configuration file directives are used to specify configuration for
specific output plug-in configurations and information about where to
load event meta-data from.
Understanding the Output Plug-Ins
 The output plug-ins determine how Barnyard processes the unified
records. Barnyard includes output plug-ins for both alert and log
records.
 The alert output plug-ins available in Barnyard include alert_fast,

alert_csv, alert_syslog, alert_syslog2, and alert_acid_db.
 The log output plug-ins available in Barnyard include log_dump,
log_pcap, log_acid_db, and sguil.
Running Barnyard in Batch-Processing Mode
 Batch-processing mode is used to process all of the records in a set of
unified files.
 This mode is often used to extract information from specific unified
files for processing by another program.
 The alert_csv and log_pcap output plug-ins are most often used with
batch-processing mode.
Using the Continual-Processing Mode
 Continual-processing mode is used to process new events as they are
generated by Snort.
 Bookmark support can be used with continual-processing mode to allow
Barnyard to remember where it was while processing the unified files.
 When enabled, the new records only option causes Barnyard to process
only new events, skipping any events that already existed.
 The daemon mode option allows Barnyard to detach from the control-
ling terminal and run in the background. Multiple Barnyard processes
can be run as daemons by using the PID file option.
www.syngress.com
Simpo PDF Merge and Split Unregistered Version -
295_Snort2e_11.qxd 5/5/04 6:58 PM Page 601
Mucking Around with Barnyard • Chapter 11 601
Deploying Barnyard
 Deployments of Barnyard may consist of multiple Barnyard configura-
tions, each designed to process events in a different way.
 Barnyard can be deployed with continual-processing mode to support
real-time event notification and database logging.
 Some deployments will also use the batch-processing mode for occa-

sional processing of the alert data in other ways.
Writing a New Output Plug-In
 While Barnyard includes many output plug-ins, they may not suit the
needs of a particular situation.
 The modular structure of Barnyard allows for new output plug-ins to be
added with relative simplicity.
 Adding a new output plug-in Barnyard consists of three steps: writing
the output plug-in functions, adding the new output plug-in to
op_plugbase.c, and updating the build system to compile the new
output plug-in.
Secret Capabilities of Barnyard
 Barnyard makes it easy to change the alert messages to localize them to
the particular environment.
 The sid-msg.map and gen-msg.map files can be modified to change the
messages that Barnyard will display without the need to update the
Snort rule files.
www.syngress.com
Simpo PDF Merge and Split Unregistered Version -
295_Snort2e_11.qxd 5/5/04 6:58 PM Page 602
602 Chapter 11 • Mucking Around with Barnyard
Frequently Asked Questions
The following Frequently Asked Questions, answered by the authors of this book,
are designed to both measure your understanding of the concepts presented in
this chapter and to assist you with real-life implementation of these concepts. To
have your questions about this chapter answered by the author, browse to
www.syngress.com/solutions and click on the “Ask the Author” form. You will
also gain access to thousands of other FAQs at ITFAQnet.com.
Q: I am having problems with the alert messages when I am running Barnyard.
Instead of seeing the message that is defined in the Snort rule, I see messages
like “Snort Signature ID: 1,2600.”The alerts look fine when generated

directly from Snort. What am I doing wrong?
A: Unlike Snort, which gets the alert messages directly from the rule files,
Barnyard reads the message information from the sid-msg.map file. If the
map file is not updated when rules are added to Snort, then Barnyard will
not know what message to display.Therefore, if the message is missing,
Barnyard displays the “Snort Signature ID: <generator ID>,<signature ID>”
for the event message.
Q: When I run Barnyard, I get the error message “Unknown magic 1a2b3c4d.”
Why won’t Barnyard process this file?
A: Barnyard identifies the Snort unified files by using a four-octet magic value
at the beginning of the file. If the value in the file does not match any of the
known types, Barnyard will generate an “Unknown magic” error message. In
the error message, the magic value of 1a2b3c4d indicates that this file is a
pcap file. In order to use Barnyard, you will need to generate unified output
files using either the log_unified or alert_unified Snort output plug-in.
Q: I am trying to process unified files on my Linux x86 server that were created
on my Solaris SPARC Snort sensor. Unfortunately, I see the error message
“Unknown magic 3741ADDE.” What is wrong?
A: When the Snort unified output format was first written, it was decided to
write all of the data using host byte order. At that time, it was envisioned that
users would be processing the unified files on the same system as the one on
which they were created.Therefore, Barnyard does not have the capability to
read unified files that were generated on a system using a different byte order
www.syngress.com
Simpo PDF Merge and Split Unregistered Version -

×