Use Snort and ClamAV to detect viruses as they cross your network.
Much focus in recent years has been given to email attachments as an avenue for viruses and worms to infiltrate a network. The Melissa and I Love You viruses are infamous examples. You can easily set up a system to scan your users’ email for such things [Hack #74], but there are many more vectors for virus propagation, such as web pages, IRC, IM file transfers... there’s really no limit. So, how do you scan for viruses and prevent them from propagating over those services?
One way is to modify Snort using the useful ClamAV [Hack #74] patch, which integrates the two packages. The patch adds a clamav preprocessor to Snort that monitors network traffic and uses the ClamAV engine to scan it for viruses. When ClamAV matches a virus definition, it generates a Snort alert. Even better, you can use this functionality with Snort_inline [Hack #111] to actually drop the traffic containing the viral payload before it can propagate.
To get started, download the ClamAV patch (http://www.bleedingsnort.com/cgi-bin/viewcvs.cgi/snort-clamav/?root=Snort-Clamav
) that’s appropriate for the version of Snort you’re using. Then, change to the directory into which you’ve unpacked the Snort source code and apply the patch:
$cd snort-2.4.3
$patch -p1 < ../snort-2.4.3-clamonly.diff
$find . -name \*.rej
You’ll then need to regenerate all of the files used by the build system. Do so by running the following command:
$ libtoolize -f && aclocal -I ./m4 && autoheader && automake && autoconf
Notice that there are a few more options for the configure script now:
$ ./configure --help | grep -i clam
--enable-clamav Enable the clamav preprocessor
--with-clamav-includes=DIR clamav include directory
--with-clamav-defdir=DIR clamav virusdefinitions directory
Run configure with all three of these options, in addition to any others that you want to use. If you’ve installed ClamAV in its default location, you’ll want to use /usr/local/include and /usr/local/share/clamav for the --with-clamav-includes
and --with-clamav-defdir
options, respectively. After the configure script has finished, type make
to start compiling.
Once the build has finished, install Snort as normal. Enable the clamav preprocessor by editing your Snort configuration file and adding a
preprocessor
clamav
directive.
Make sure you enable the clamav preprocessor after enabling the stream4_reassemble preprocessor in your configuration file; otherwise, the clamav preprocessor might miss some viral payloads that span multiple IP datagrams or arrive out of order. Also be sure to put it before the directive enabling the http_inspect preprocessor.
The clamav preprocessor has several options that you can use to specify which ports to scan for viral traffic, which direction of a TCP stream to scan, what to do in inline mode if a virus is found, and a few other miscellaneous things. To specify options, put a colon after the preprocessor name (e.g., clamav:
) and list the options separated by commas. The examples shown here are complete preprocessor
directives. When you edit your configuration file, you should combine all of the options you want to use into one preprocessor clamav
line.
By default, ClamAV scans only ports 21, 25, 80, 81, 110, 119, 139, 143, and 445 for viral payloads. To add ports, use the ports
option followed by a space-delimited list of the ports to include. You can also exclude a port from being scanned by using the !
operator. This is especially useful when you’re using the all
keyword, which specifies all ports for scanning.
For instance, you might want to scan all ports, except for some that usually carry encrypted traffic:
preprocessor clamav: ports all !22 !443 !993 !995
For TCP streams, you can opt to scan traffic going to the client, to the server, or in either direction. By default ClamAV scans both directions, but if you want to scan only traffic going to clients, to lessen the load on your IDS, you can use the toclientonly
option:
preprocessor clamav: toclientonly
Alternatively, if you feel that viruses being sent to your servers is a bigger issue, you can use the toserveronly
option.
Determining when viruses are loose on your network is very different from being able to proactively block them. When using Snort in inline mode with the clamav preprocessor, it’s possible to automatically stop a viral payload from reaching its destination. The only thing in question is which method to use. If you want Snort to silently drop any packets in which it detects a viral payload, use the action-drop
option. If you want to perform a TCP reset instead, use the action-reset
option:
preprocessor clamav: action-reset
If the location of the virus definitions (specified when running configure with --with-clamav-defdir
) has changed since you compiled Snort, you can use the dbdir
option to specify the new location. The preprocessor also allows you to specify how often to reload the virus definitions with the dbreload-time
option. This defaults to 600 seconds, but you’ll probably want to change it to a longer time period (for example, 86400 seconds if you update your virus definitions once a day).
The following directive specifies /opt/clamav/share as the directory to read virus definitions from and indicates that they should be reloaded once per day:
preprocessor clamav: dbdir /opt/clamav/share, dbreload-time 86400
To increase the preprocessor’s reliability, you can use the file-descriptor-mode
option, which causes it to write packet payloads to a file before scanning them. Otherwise, it holds them in memory when doing the scanning. When this option is enabled, the payloads are written to /tmp by default. If you want to change this, use the descriptor-temp-dir
option. The following directive tells Clam AV to write payloads to /var/tmp/clamav before scanning them for viral content:
preprocessor clamav: file-descriptor-mode, descriptor-temp-dir /var/tmp/clamav
Bear in mind, however, that the file-descriptor-mode
option can reduce performance significantly, since the preprocessor is constantly writing to disk. To alleviate this problem, use a
memory-based filesystem. For instance, in Linux you can create a 256MB filesystem that is backed by memory at /var/tmp/clamav by running the following command:
# mount -t tmpfs tmpfs /var/tmp/clamav -o size=256M
Of course, you should make sure you have plenty of RAM to do this.
Similarly, under FreeBSD, you can add the following lines to /etc/rc.conf to cause /tmp to use the Virtual Memory Manager (VMM) for storage rather than a disk:
tmpmfs="YES" tmpsize="256m"
After you’ve done that, reboot to let the change take effect.
Once you’ve configured the preprocessor, start Snort as you normally would. If you didn’t use the -q
command-line option, which suppresses output, you should see some lines similar to these, signifying that the clamav preprocessor was loaded properly:
ClamAV config: Ports: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ... Virus definitions dir: '/usr/local/share/clamav' Virus DB reload time: '86400' Scan only traffic to the client File descriptor scanning mode: Enabled, using cl_scandesc Directory for tempfiles (file descriptor mode): '/tmp'
As a quick test, you can use Netcat (http://www.vulnwatch.org/netcat/
) on another system to have it send one of the ClamAV test files to a system that is visible to your IDS sensor. Do so by running something like this on the server:
$ nc -l 65535 < clam.cab
Of course, make sure to use a port that you’re actually monitoring for viruses. Then, use Netcat on the client system to connect to it. Once the client system connects and is sent the test file, you should see Snort generate an alert similar to this:
06/24-00:30:45.562228 [**] [125:1:1] (spp_clamav) Virus Found: ClamAV-Test-File [**] {TCP} 192.168.0.62:65535 -> 192.168.0.40:65129
Now that you have it working, you can deploy the clamav preprocessor across all of your Snort sensors. Doing so will give you a heads-up on any viruses that might be propagating across your network and give you time to take action before any outbreaks get too serious.