Attackers can't rewrite your log files
if they can't connect to the log server. Learn the ways
of stealth.
In a column about syslog [see
"syslog Configuration" in the December 2001 issue of
LJ] I mentioned ``stealth logging''--by running
your central log server without an IP address, you can
hide your central log server from intruders. But log
servers aren't the only type of system that can benefit
from a little stealth. Network sniffers and network
intrusion detection systems (NIDSes) probes can also
function perfectly well without IP addresses, making
them less vulnerable to network attacks than the systems
they protect.
This month I demonstrate three ways to use the
versatile and powerful Snort--as a stealth sniffer, a
stealth NIDS probe and a stealth logger--on a network
interface with no IP address. If you're already familiar
with Snort, I hope you'll see how easily it can be used
stealthfully. If you're new to Snort, this article may
be a useful crash course for you. All Snort commands and
configurations in this article work equally well on
interfaces with and without IP addresses.
Why Be Stealthful?
Running internet-connected computers is risky.
Anytime you provide services, there's a chance that a
hostile user might hijack the system through an
application vulnerability or simply overwhelm the system
with a denial-of-service attack that sends more traffic
to your system than it can handle. For web servers, FTP
servers and other systems that end users interact with,
this risk never can be eliminated--it only can be
minimized or contained.
Network probes and log servers are unique, however,
because their roles are fundamentally passive; they
receive data but don't need to send any. Taking
advantage of their passivity by making them inaccessible
from the networks they protect makes a lot of sense.
The trade-off is systems without IP addresses must be
administered only from the console, or must have another
network interface with an IP address. If a system has
multiple interfaces, two precautions are vital. First,
IP forwarding must be disabled, and second, the
interface with an IP address must be connected to a
different network from the sniffing/logging
interface. It could, for example, be connected to a
dedicated ``admin'' network consisting only of NIDS
probes, loggers and administrative workstations.
Physical and System-Level Setup
Physically installing a network interface card (NIC)
is easy. Provided that your NIC is supported by your
kernel, Linux should automatically detect the NIC and
load the appropriate kernel module(s).
However, different distributions handle NIC
initialization in different ways. For example, after
adding a second NIC to my Red Hat stealth sniffer, I had
to create a new file,
/etc/sysconfig/network-scripts/ifcfg-eth1, with the
following contents:
DEVICE=eth1
USERCTL=no
ONBOOT=yes
BOOTPROTO=
BROADCAST=
NETWORK=
NETMASK=
IPADDR=
Although Red Hat's Kudzu tool automatically
detected the new interface, its network-configuration
script returned an error when I declined to give an IP
address. By creating my own
/etc/sysconfig/network-scripts/ifcfg-eth1 file, I got
Red Hat to activate the new interface without actually
giving it an IP address. On different distributions
other steps may be required.
Stealth Sniffing
Once you've installed and activated your stealth NIC
and connected it to the network you wish to monitor,
it's time to try some stealth sniffing. For the
remainder of the article I'll assume you've already
installed Snort. Most Linux distributions contain their
own Snort packages, and the latest version is available
at http://www.snort.org/. If you're going
to use Snort as a NIDS, it's especially important to be
running a recent version of Snort.
The Snort command for ``sniffer mode'' is simply:
snort -dvi eth1
The -d option tells Snort to decode application
data. The -v option tells it to print packets to the
console, and the -i option lets you specify the
interface to sniff. To tell Snort to skip the
hexadecimal data and show only ASCII, use the -C option
(Listing 1).
Listing 1. A Packet Dump withoutHexadecimal
Data
Snort's sniffing functionality works perfectly well
on an interface without an IP address.
Stealthful Intrusion Detection
Intrusion detection is a big topic, and Snort's
intrusion detection abilities are diverse and powerful.
Before we go any further, then, I want to stress that
I'm only scratching the surface: running Snort with a
near-default configuration file, using only the included
rules, is not the most effective way to use Snort
as a NIDS. I'm describing this method here because it's
a simple and fast way to get started with NIDS.
To start using Snort in NIDS mode, all you need to do
is edit the file /etc/snort/snort.conf and start Snort
in dæmon mode. Then, periodically update the Snort rules
referenced in snort.conf as new attack signatures become
available. Let's briefly discuss each of these steps.
Although you can specify any configuration file you
like with Snort's -c startup option, most people use
/etc/snort/snort.conf. For the remainder of this article
I'll assume that's your choice too. Listing 2 shows a
truncated but syntactically complete Snort configuration
file.
Listing 2. A Sample snort.conf File
As you can see, a Snort configuration consists of
global options, variable declarations, ``preprocessor''
statements, ``output'' statements and Snort rules.
Global options (``config'' statements) provide a handy
means of setting most of the options that also can be
passed to Snort via startup flags, which saves typing.
Variables are used by Snort rules to make attack
detection more accurate. For example, by specifying the
IP address of your local name servers via the
DNS_SERVERS variable, Snort will disregard certain types
of packets sent by your DNS servers that, in other
circumstances, might look like attacks.
Preprocessor statements are used to configure
preprocessor modules, which are Snort components that
act on or alter packets prior to matching them against
rules. For example, the preprocessor frag2 re-assembles
fragmented packets, and it also watches out for
IP-fragment-based attacks and other fragment-related
anomalies.
Output statements configure postprocessor modules,
which provide different means of logging or otherwise
archiving Snort alerts and observed packets. For
example, the database postprocessor can be used to log
packets to a MySQL database for later correlation and
analysis by tools such as ACID (www.andrew.cmu.edu/~rdanyliw/snort/snortacid.html).
Finally, rules can be listed either directly, as with
Listing 2's ``Cisco Catalyst Remote Access'' alert, or
in included text files, as with the remainder of Listing
2. The latter method makes it easy to use the rule files
maintained by the Snort team at www.snort.org/dl/signatures/snortrules.tar.gz
(updated every 30 minutes!) or the ArachNID rules at www.whitehats.com/ids.
To start Snort in NIDS mode using this configuration
file, execute this command:
snort -c /etc/snort/snort.conf -D -i eth1
Remember that in earlier examples we set up eth1
as our stealth interface.
By default, Snort will log alerts to
/var/log/snort/alert and port-scanning activity to
/var/log/snort/portscan.log. Packets referenced in
alerts will be logged to subdirectories of
/var/log/snort, as described in Listing 3.
A dedicated NIDS probe will need to start Snort in
its boot routine. The official Snort RPM automatically
installs the startup script /etc/init.d/snortd. Once
you've configured Snort to your satisfaction, activate
this script for the desired runlevels with the
chkconfig command. You may need to write your
own startup script if you installed Snort from source.
Running Snort in NIDS mode deserves its own article,
even a whole series of articles, but this is
enough to illustrate that Snort can be used with a
non-IP-addressed interface and to show how to get
started with NIDS mode.
Stealthful Logging
Now it's time to combine the previous two techniques
in a third one: stealth logging. Normally, a central log
server runs syslog or syslog-ng. And indeed, it's
possible to capture log packets via a non-IP-addressed
interface with Snort and pass them to syslog or
syslog-ng. However, it's a lot simpler to let Snort
write the packets to a log file itself. The method I'm
about to describe uses Snort, tail and awk instead of a
traditional logger (on the central logserver,
that is; on hosts that send logs you'll still
need to configure syslog or syslog-ng as described
below).
Suppose you have a LAN segment with several servers
whose log messages you'd like sent to a single log
server. Suppose further that you're far less concerned
with the confidentiality of these log messages than with
their integrity. You don't care if anybody eavesdrops
the messages, but you don't want the messages tampered
with once they've been received by the central log
server. Your log server, therefore, is connected to the
LAN via a non-IP-addressed interface and will sniff log
packets sent to a bogus IP address on the LAN.
Configuring Your Hosts to Send Logs to the Stealth
Logger
On each server from which you wish to send logs,
you'll need to do two things. The first step is to
configure each sender's system logger to send its
messages to the bogus IP. By ``bogus'', I only mean that
no host actually has that IP address; it must be
valid for the LAN in question. Suppose our example LAN's
network address is 192.168.1.0/24 and our bogus
logger-host address is 192.168.1.111. Servers on the LAN
that use standard syslog will each need a line like this
in /etc/syslog.conf:
*.info @192.168.1.111
On servers that use syslog-ng, you'll need several
lines in /etc/syslog-ng/syslog-ng.conf, like these:
destination d_loghost { udp(ip(192.168.1.111)
port(514)); };
filter f_info { level(info); };
log { filter(f_info); destination(d_loghost); };
In either case you may wish to specify different
criteria from simply saying ``all messages whose
severity is ‘info' or higher'', as shown in the above
two examples.
Besides the appropriate lines in its logger's
configuration file, each log sender will also need a
static ARP entry for the bogus IP address. If your LAN
consists of a hub or a series of ``cascaded'' hubs, this
ARP address also can be bogus. If your LAN is switched,
you'll instead need to specify the real MAC address
(hardware address) of the log server. The command to add
a static ARP entry on our example log-sending servers
is:
arp -s 192.168.1.111 00:04:C2:56:54:58
where 192.168.1.111 is our bogus log-host IP, and
00:04:C2:56:54:58 is either a bogus MAC address or the
real MAC address of our stealth logger's
non-IP-addressed interface.
Now each server on our protected LAN is configured to
send its logs to 192.168.1.111, and in the case of a
switched LAN, they'll be sent to the stealth logger's
switch port. Now all we need to do is configure the
stealth logger itself.
Configuring Snort on the Stealth Logger
As with intrusion-detection mode, we can configure
Snort as a stealth logger by editing only one file,
/etc/snort/snort.conf. Listing 3 shows my Red Hat
stealth logger's snort.conf file. Let's dissect it.
Listing 3. /etc/snort/snort.conf/ for a Stealth
Logger
First, we have a single variable declaration:
EXTERNAL_NET any. None of the other variables we set for
NIDS mode are necessary here. Next, we've got a few
config statements: dump_payload is equivalent to the
command-line option -d; dump_chars_only is equivalent to
-C; and logdir specifies the root directory for Snort
logs (and is equivalent to -l).
Continuing down Listing 3, we next see one
preprocessor statement: we're invoking the frag2
preprocessor with default settings. Large log packets
may be fragmented, and if so, frag2 will re-assemble
them for us.
Finally, the payoff: a single custom Snort rule.
Writing Snort rules is no more complicated than writing
iptables or ipchains rules, requiring only a basic
understanding of how TCP/IP protocols and applications
behave. The ``Snort Users' Manual'' at www.snort.org/docs/writing_rules
documents this clearly and comprehensively. Let's walk
through the Snort rule in Listing 3:
log udp 192.168.1.20/32 any ->
192.168.1.111/32 514 (logto:
"logged-packets";)
The rule begins with the rule action log. In this
case, we're using Snort as a packet logger. So rather
than writing a message to /var/log/snort/alert, we want
Snort to log any packets that match the rule without
writing an alert.
Next comes the rule's matching protocol, udp.
syslog messages usually are sent via UDP.
After the rule's protocol comes its source IP,
expressed in CIDR notation. 192.168.1.20 is the IP
address of the host sending log packets, so we want to
match packets sent by that host. /32 is CIDR shorthand
for ``parse all 32 address bits'', which indicates this
is a single host address rather than a range of
addresses. To match packets from all hosts on the
example LAN, we instead could specify a source IP of
192.168.1.0/24.
The source port follows the source IP, in this case
``any'' source port. ``Any'' is a common source-port
designator in Snort rules, because with only a few
exceptions, TCP/IP client applications send packets from
arbitrary, high-numbered ports. In the middle of the
rule is its direction operator (->), which signifies
that the IP and port to the left of it pertain to the
packet's source, and those to the right pertain to its
destination. The other allowed direction operator is
<>, which indicates that the source and
destination IP/port pairs are interchangeable. In other
words, Snort should match packets going in either
direction between the specified IP addresses on the
specified ports.
To the right of the direction operator come the
rule's destination IP and destination port designators,
192.168.1.111/32 and 514, respectively. 192.168.1.111 is
the bogus IP address to which our servers log, on UDP
port 514.
Finally, the rule's options are listed between
parentheses, delimited by semicolons if there are
multiple options. In this case there's only one, logto:
"logged-packets". The logto option lets us specify a log
file to which to write matched packets, in this case
/var/log/snort/logged-packets (earlier we set the
configuration option logdir to /var/log/snort).
Without the logto: option, Snort will log packets in
a new subdirectory of the root log directory, one
subdirectory per matched source-IP address. For a
stealth logger's purposes, though, it's much better to
use the logto: option to specify a single log
file to which matched packets for each rule are logged.
This allows you to group packets by rule rather than by
transaction.
Whew, it took me longer to explain that single rule
than it took me to explain the rest of our stealth
logger's snort.conf file. But the rule is the important
part. If you have additional servers sending log
messages, you'll probably want a separate rule for each
so their messages are logged to separate files.
Conclusion
Snort is a versatile and powerful tool for sniffing,
intrusion detection and packet logging. Configuring it
to run stealthily in sniffing mode or NIDS mode is easy;
incorporating it into a stealth-logging solution is only
slightly less so. Good luck with your logging and NIDS
endeavors, stealthful or not!
LAN Segments, Hubs and Switches
Mick Bauer (mick@visi.com) is a
network security consultant for Upstream Solutions,
Inc., based in Minneapolis, Minnesota. He is the
author of the upcoming O'Reilly book Building
Secure Servers With Linux, composer of the
``Network Engineering Polka'' and a proud parent (of
children).