...making Linux just a little more fun!

<-- prev | next -->

# Intrusion Detection with Tripwire

By Barry O'Donovan

## Intrusion Detection with Tripwire

### 1. Introduction

A little over two years ago I was hacked. Someone broke into a web server I was administrating that had only Apache and OpenSSH running publically, and all packages were up-to-date. The hacker replaced my `ps` binary with his own to hide his processes, added a new service that was executed from the binary "`/bin/crond` " (the space is intentional - it makes it look like a normal and an expected process in a running-processes listing and a normal binary in a directory listing). The "`crond` " process gathered usernames and passwords and stored them in a text file in the directory "`/dev/pf0 / /`", (5 and 2 spaces respectively), which also contained a root shell. The chances of me finding and identifying this intrusion would have been extremely remote if I had not been running Tripwire.

Tripwire is a file integrity checker for UNIX/Linux based operating systems and works as an excellent intrusion detection system. It will not prevent an intrusion; for this see my previous articles on setting up firewalls and securing a Linux distribution for help.

The idea behind Tripwire is quite simple: it first creates a "baseline" database of the state of the files and directories on your system and then on subsequent runs it compares the current state of the files and directories against this baseline identifying any deletions, additions or changes. The files and directories to be checked are decided by a "policy" file. This file also defines what attributes to compare; this can include access, inode and modification timestamps, owner and group IDs, permissions, file size and type, MD5 and SHA hash values, etc.

In this article I will guide you through the process of getting and installing Tripwire, configuring it and setting it up to run on a daily basis. In the final section I will mention a few additional steps you can take to ensure the integrity of your Tripwire database and thus your file system.

### 2. Acquiring and Installing Tripwire

The easiest method of installing Tripwire is to use a vendor supplied package (I have checked and these are available for RedHat/Fedora Core, SuSE, Mandrakesoft and Debian). The advantages of using these is that the policy file will be already created and configured for the system you are using. Make sure to use official packages for your distribution to ensure they have not been trojaned.

If you cannot locate a precompiled package for your distribution, then you can download the latest source code from http://sourceforge.net/projects/tripwire/. The version available at time of going to press was 2.3.1-2. This version is dated March 2001 and when I tried to compile it on my system I got a myriad of errors. The sources do not use the autoconf/automake build system and this may be the main cause of the errors. I have decided to place the resolution of these problems outside the scope of this article given the availability of precompiled packages for many distributions.

### 3. An Overview of Tripwire's Files

The operation of Tripwire is controlled by a configuration file and a policy file; both of these files are encoded and signed before use for security reasons. These files usually reside in `/etc/tripwire`. The plain text versions are called `twcfg.txt` and `twpol.txt`, and the encoded and signed versions are called `tw.cfg` and `tw.pol`. The plain-text version of the configuration file contains key-value pairs including the following required variables (default values for my distribution shown):

    POLFILE         = /etc/tripwire/tw.pol
    DBFILE          = /var/lib/tripwire/$HOSTNAME.twd
    REPORTFILE      = /var/lib/tripwire/report/$HOSTNAME-$DATE.twr
    SITEKEYFILE     = /etc/tripwire/site.key
    LOCALKEYFILE    = /etc/tripwire/$HOSTNAME-local.key

The `POLFILE`, `DBFILE` and `REPORTFILE` dictate the locations of the policy file, the database file and the report file respectively. A report file is generated each time Tripwire is used to check the integrity of the file system and its name is determined by both the hostname and current date. The `SITEKEYFILE` and `LOCALKEYFILE` variables hold the locations of the two key files; site keys are used for signing files that can be used on multiple systems within an organisation such as the policy and configuration files, while the local key is used for files specific to this system such as the database file.

Ensure that the `$HOSTNAME` environment variable is correctly set to your system's hostname before using any of Tripwire's commands. Also, the `HOSTNAME` variable in `twpol.txt` must be set correctly so that it matches the system's hostname. If you are unsure of what the system's hostname is set to, then execute `echo $HOSTNAME` on the command line.

Other configuration file values we will use are shown here followed by a description of each:

    EDITOR                 =/bin/vi
    MAILNOVIOLATIONS       =true
    EMAILREPORTLEVEL       =3
    REPORTLEVEL            =3
    MAILMETHOD             =SENDMAIL
    MAILPROGRAM            =/usr/sbin/sendmail -oi -t

`EDITOR`
  When updating the database after files have been added, removed or altered, a "ballot-box" styled form must be completed by placing an 'x' opposite the files which we have changed and do not indicate an intrusion; this variable sets the editor to use for this process.
`MAILNOVIOLATIONS`
  Tripwire e-mails a report whenever a violation was found. This option tells Tripwire to always e-mail a report whether a violation was found or not. This is useful as it shows the system administrator that Tripwire is running as expected.
`EMAILREPORTLEVEL` and `REPORTLEVEL`
  The amount of information Tripwire includes in its report file and e-mail. Valid values range from 0 to 4 with the default being 3.
`MAILMETHOD` and `MAILPROGRAM`
  The mail method can either be `SMTP` (in which case additional variables have to be set to indicate the SMTP host and port) or `SENDMAIL` (in which case we include the `MAILPROGRAM` variable).

There are a number of other options and these are explained in the man page: `TWCONFIG(4)`.

Creating your own policy file is a long and tedious task that is also outside the scope of this article. If you get a packaged version of Tripwire for your distribution then the policy file should already be created. The policy file is essentially a list of rules and associated files which should be checked by Tripwire; the rules indicate the severity of a violation. The text version of the file itself is quite readable and is worth a look to fully understand how Tripwire works. Also, irrespective of your distribution, you will find that Tripwire generates a lot of the following errors when checking the filesystem:

    File system error.
    Filename: XXXXXXXXXXXXX
    No such file or directory

For each of these errors there is an entry for the named file in the policy file but this file does not exist on your system. You will have to edit the policy file and comment out these lines.

Tripwire comes with four binary files:

`tripwire`
  The main file; used for initialising the database, checking the integrity of the file system, updating the database and updating the policy.
`twadmin`
  Tripwire's administrative and utility tool; used for creating and printing configuration files, replacing and printing a policy file, generating site and local keys and other encryption related functions.
`twprint`
  Used to print the reports and database in human-readable format.
`siggen`
  Generates the various hashes that Tripwire supports for checking the integrity of files.

### 4. Initialising the Keys and Database

In this section we will set Tripwire up so that you can use it on a daily basis to check your systems integrity. I am assuming that the current working directory is `/etc/tripwire` and that the following files exist in the specified paths:

`/etc/tripwire/twcfg.txt`: | plain-text version of the configuration file
`/etc/tripwire/twpol.txt`: | plain-text version of the policy file

The first step is to generate the keys to be used when signing the database, policy file and configuration file. You will be asked for a passphrase for each of the local and site keys; it should be greater than 8 characters and include punctuation symbols as well as alphanumeric characters.

    [root@home /etc/tripwire]# twadmin --generate-keys --site-keyfile ./site.key

    (When selecting a passphrase, keep in mind that good passphrases typically
    have upper and lower case letters, digits and punctuation marks, and are
    at least 8 characters in length.)

    Enter the site keyfile passphrase: XXXXXXXXXXXXXXXXXX
    Verify the site keyfile passphrase: XXXXXXXXXXXXXXXXXX
    Generating key (this may take several minutes)...Key generation complete.

    [root@home /etc/tripwire]# twadmin --generate-keys --local-keyfile ./$HOSTNAME-local.key

    Enter the local keyfile passphrase: XXXXXXXXXXXXXXXXXX
    Verify the local keyfile passphrase: XXXXXXXXXXXXXXXXXX
    Generating key (this may take several minutes)...Key generation complete.
    [root@home /etc/tripwire]#

Now that we have generated our keys, we need to sign the configuration and policy files (after editing them as required):

    [root@home /etc/tripwire]# twadmin --create-cfgfile --cfgfile ./tw.cfg --site-keyfile ./site.key \
        twcfg.txt
    Please enter your site passphrase: XXXXXXXXXXXXXXXXXX
    Wrote configuration file: /etc/tripwire/tw.cfg

    [root@home /etc/tripwire]# twadmin --create-polfile --cfgfile tw.cfg --site-keyfile site.key twpol.txt
    Please enter your site passphrase: XXXXXXXXXXXXXXXXXX
    Wrote policy file: /etc/tripwire/tw.pol
    [root@home /etc/tripwire]#

Do not leave the plain-text versions of the configuration and policy files on your hard drive. Move them onto a floppy disk or encrypt them using a utility such as GPG. Also ensure that the permissions of the signed files are set such that they are only readable/writable by root:

    [root@home /etc/tripwire]# chmod 0600 tw.cfg tw.pol

The last job we must do to complete the set-up is create the baseline database:

    [root@home /etc/tripwire]# tripwire --init --cfgfile ./tw.cfg --polfile ./tw.pol \
        --site-keyfile ./site.key --local-keyfile ./home.barryodonovan.com-local.key
    Please enter your local passphrase:
    Parsing policy file: /etc/tripwire/tw.pol
    Generating the database...
    *** Processing Unix File System ***
    Wrote database file: /var/lib/tripwire/$HOSTNAME.twd
    The database was successfully generated.
    [root@home /etc/tripwire]#

### 5. Integrity Checking

Now that Tripwire is installed, configured and the baseline database has been created, we can get on with the business of checking the integrity of the file system:

    [root@home /etc/tripwire]# tripwire --check
    Parsing policy file: /etc/tripwire/tw.pol
    *** Processing Unix File System ***
    Performing integrity check...
    Wrote report file: /var/lib/tripwire/report/$HOSTNAME-20040823-210750.twr
    ... ... ...
    Total objects scanned:  52387
    Total violations found:  0

Each violation (an addition, removal or change) is reported to `stdout` and written to the report file as indicated. On this occasion I have assumed the default locations of the configuration and policy files. I could have specified these explicitly on the command line as I have been doing with switches such as `--cfgfile`, etc.

Your goal should be to set this up to run on a daily basis. This can be done as a cron or an Anacron job; Anacron is the better choice when the computer is not on 24/7. Using either cron or Anacron, the output should be e-mailed to the root user on each run of Tripwire.

In the case of Anacron, create a file in `/etc/cron.daily/` called (for example) `tripwire-check` containing:

    #!/bin/bash

    /usr/sbin/tripwire --check

and ensure that it is executable (`chmod u+x /etc/cron.daily/tripwire-check`). If you want to use a cron job, then add the following line to root's crontab to perform the check every day at 3am (`crontab -e`):

    00 03 * * * /usr/sbin/tripwire --check

### 6. Updating the Database

When any file that Tripwire checks changes, you must update the Tripwire database so that it reflects the new information for the file. This can be done as part of the integrity checking process by using the interactive switch ('`-I`') or by using the database update mode of the `tripwire` command:

    [root@home /etc/tripwire]# tripwire --update --twrfile /var/lib/tripwire/report/$HOSTNAME-20040823-210750.twr
        < At this point you will be asked to choose which file records to update in the >
        < database via the ballot-box mechanism. Unless you specified otherwise, vi     >
        < will be the editor chosen. If you have not used vi before then I suggest you  >
        < change it to a pico, nedit or whatever you prefer. Add/remove the x's from    >
        < the ballot boxes, save and exit                                               >
    Please enter your local passphrase: XXXXXXXXXXXXXXX
    Wrote database file: /var/lib/tripwire/home.barryodonovan.com.twd
    [root@home /etc/tripwire]#

As you can see from the command line above, you must specify a report file to be used when updating the database. Choose the most recently generated report file. If you find yourself having to constantly update the same non-critical files, then feel free to update the policy so as to exclude those files.

If any changes are found you will be presented with a "ballot-box" styled form that must be completed by placing an 'x' opposite the violations that are safe to be updated in the database (for example you updated the Apache web server yesterday and Tripwire is reporting a change in the binary `/usr/sbin/httpd` as would be expected). If anything has changed that you cannot directly account for then you should check it out as it may indicate that someone has broken into your system.

### 7. Updating the Policy

The `tripwire` command has a policy update mode which means that a change in policy does not require us to reinitialise the database. The policy update mode simply synchronises the existing database with the new policy file. The new policy file expected is the plain-text version - Tripwire will then ask for the local and site passphrases, synchronise the database and sign both the new policy file and the database.

    tripwire --update-policy --cfgfile ./tw.cfg --polfile ./tw.pol --site-keyfile ./site.key \
        --local-keyfile ./$HOSTNAME-local.key new_policy_file.txt

Again, you should not leave the plain-text version of the policy file on the system.

### 8. Securing Tripwire

Using Tripwire as an intrusion detection system is only as effective as the security of Tripwire itself. There are a number of procedures you can follow to ensure maximum security:

- ensure that no plain text copies of the configuration file or the policy file exist on the system
- ensure the access modes of the Tripwire binaries are 0500 (i.e. `-r-x------`); as root execute: `chmod 0500 /usr/sbin/tripwire /usr/sbin/twadmin /usr/sbin/twprint /usr/sbin/siggen`
- ensure the access modes of the configuration directory and the database and report directory are 0700 (i.e. `-rwx------`) and similarly for its contents; as root execute: `chmod -R u=rwX,go-rwx /var/lib/tripwire` - the capital 'X' in the permissions sets the execute (or access if a directory) bit if the file already has it set or if it is a directory.

The last procedure is something that I would consider a 'must' rather than a 'should'. Tripwire's database must be secure for an integrity check to be sufficiently trustworthy. If you are not updating the database on a regular occasion (such as on a server, etc) then you can keep the database on removable media without too much inconvenience. This can be as simple as leaving a write-protected floppy cantaining the database in the floppy drive, or a re-writable CD in a CD-ROM drive (read-only drive). If the database changes then you can update the database on these mediums by write-enabling the floppy or erasing and burning the new database to the CD-RW; but an attacker will be unable to remove or alter the database in anyway.

A second solution would be to keep the database on another machine and download it as required. This could be as simple as using `wget` to fetch the database from a web server just prior to running the integrity check and removing it afterwards. For example, change the Anacron script to:

    #!/bin/bash

    # switch to the database directory as specified by the Tripwire configuration file
    cd /var/lib/tripwire

    # download the database from a password protected directory (.htaccess)
    wget http://www.someserver.com/private/$HOSTNAME.twd --http-user=username --http-passwd=password

    # perform the integrity check
    /usr/sbin/tripwire --check

    # remove the database
    rm -f $HOSTNAME.twd

You can use `scp`, `rsync`, etc in a similar fashion.

### 9. Further Resources

A standard installation of Tripwire comes with many man pages which provide all the information you should need:

- `TRIPWIRE(8)` - (i.e. execute `man 8 tripwire` to view this man page)
- `TWINTRO(8)` - an introduction to Tripwire
- `TWADMIN(8)`
- `TWPRINT(8)`
- `SIGGEN(8)`
- `TWCONFIG(8)` - information on the Tripwire configuration file
- `TWPOLICY(8)` - information on the Tripwire policy file
- `TWFILES(8)` - information on the various Tripwire files

Barry O'Donovan graduated from the National University of Ireland, Galway with a B.Sc. (Hons) in computer science and mathematics. He is currently completing a Ph.D. in computer science with the Information Hiding Laboratory, University College Dublin, Ireland in the area of audio watermarking.

Barry has been using Linux since 1997 and his current flavor of choice is Fedora Core. He is a member of the Irish Linux Users Group. Whenever he's not doing his Ph.D. he can usually be found supporting his finances by doing some work for Open Hosting, in the pub with friends or running in the local park.

Copyright © 2004, Barry O'Donovan. Released under the Open Publication license

Published in Issue 106 of Linux Gazette, September 2004

<-- prev | next -->