Intrusion Detection (IDS) using mtree


When you are dealing with any system, especially one publicly accessible service or one with multiple users, you need to make sure it has not been tampered with. Implementing an intrusion detection system (IDS) is a good way to do a routine sanity check on the system.

There a few products like Tripwire and AIDS offering intrusion detection packages, but you may want a simpler solution. Perhaps you do not have a need for all the bells and whistles of the larger packages like pretty graphics and pie graphs for the manager types. You want it simple and you need something that just works. You may want to look at making your own IDS using mtree.

By making your own system, not only can you audit the files on the disk but also audit the IDS itself. You would have control of how the IDS ran, how and where it looks at files and what it does when or if a problem is found. Take a look at the binary "mtree" which is installed by default on most open source systems.

Building a custom Intrusion Detection System

To get started, make a directory owned by root with (chmod 700) which in our example will be called /ids_dir . This directory will contain the single IDS shell script and the hash check files generated by mtree. Lets look at the simple shell script making up our custom IDS solution.

In order to find out if any of our files have changed we first need to make an initial hash check of all of the files/directories we want to keep an eye on. The script "" will make a comparative cksum, md5digest, sha1digest and rmd160digest of all of the files in the directories /bin, /sbin and /usr. We are only checking these three(3) directories in our example, but you should take some time later and make a longer list of directories or files that are important to your machine.

The script has two variables you need to set before executing it. The first is the $KEY variable. This sets a seed value necessary to generate the has on the files and it is a 23 digit number you can make up for this purpose. The same $KEY value is also need to verify the hash values against. If an unauthorized person had the has files, but not the $KEY value, then they would not be able to check the validity of your files. The second variable id $DIR. This is the directory that the script and hash checked files generated by mtree will reside.

The Script:


if [ $# -eq 0 ]
    echo ""
    echo "    ./ \$arg"
    echo "--------------------------------------"
    echo "generate = generate IDS signatures"
    echo "verify   = verify files against known signatures"
    echo ""

## IDS signature key (any random 23 digits)

## IDS signature directory (to store this script and mtree hash files)

if [ $1 = "generate" ]
     cd $DIR
     mtree -c -K cksum,md5digest,sha1digest,rmd160digest -s $KEY -p /bin > mtree_bin
     mtree -c -K cksum,md5digest,sha1digest,rmd160digest -s $KEY -p /sbin > mtree_sbin
     mtree -c -K cksum,md5digest,sha1digest,rmd160digest -s $KEY -p /usr > mtree_usr
     logger IDS generate IDS signatures

if [ $1 = "verify" ]
     cd $DIR
     mtree -s $KEY -p /bin < mtree_bin >> temp 2>&1
     mtree -s $KEY -p /sbin < mtree_sbin >> temp 2>&1
     mtree -s $KEY -p /usr < mtree_usr >> temp 2>&1
     cat temp | mail -s "`hostname` file integrity check" root
     rm temp
     logger IDS verify files against known signatures

Verify the environment ( ./ generate )

Now that you have made the /ids_dir, copied the script "" into /ids_dir and made up a new 23 digit value for KEY we are ready to run for the first time. Execute the command "./ generate". Once finishes you will see three files in the /ids_dir directory containing the hash values for all of the directories and files mtree checked under /bin, /sbin and /usr.

 -rwx------  1 root      321 Jan 10 10:20
 -rw-r--r--  1 root   234567 Jan 10 10:20 mtree_bin
 -rw-r--r--  1 root    34567 Jan 10 10:20 mtree_sbin
 -rw-r--r--  1 root  1234567 Jan 10 10:20 mtree_usr

These mtree_* files are the files we will make all subsequent IDS checks against. Be sure only authorized admins can access these files and make an off system copy to be safe. A copy on CD in a safe is preferable, but a personal encrypted usb key will work too. Also make sure to backup the 23 digit $KEY variable as an authorized admin can _not_ do a hash check without it.

Running the scripts

The script is split into two parts, generate and verify. To start a hash check of all the directories listed and files in those directories you execute the script "" with the argument "generate". To verify the hash values against the files currently on the system execute the script "" with the argument "verify". During the verify process an email with the results are sent to the root user.

Email report of an unmodified system ( ./ verify )

Now it is time to run "./ verify" which we will verify the files on the system are the same files we hash checked. After you run the check script an email similar to the one below will be sent to root. If all the files are the same then the mail will look like this one.

From: (Root User) 
Date: Fri, 13 Jun 2008 10:20:30 -1000 (FDT) 
Subject: machine.domain.lan file integrity check

mtree: /bin checksum: 893663885 
mtree: /sbin checksum: 1746129196 
mtree: /usr checksum: 1666010597

Email report of a modified system ( ./ verify )

If mtree finds a file that has been modified, deleted or added since the last run of "./ generate" the file(s) will be listed in the email. You should track down why the change was made and if it is legitimate. Then, if the change was legitimate, you should re-run the command "./ generate" to update the hash files.

From: (Root User) 
Date: Fri, 13 Jun 2008 20:20:30 -1000 (FDT) 
Subject: machine.domain.lan file integrity check

mtree: /bin checksum: 893663885
mtree: /sbin checksum: 3292978967
        modification time (Fri Jun 13 10:20:30 2008, Fri Jun 13 20:20:30 2008)
        size (5099786, 5105218)
        modification time (Fri Jun 13 10:20:30 2008, Fri Jun 13 20:20:30 2008)
        cksum (1813282464, 116976809)
        MD5 (bce978da0f3964de5cf9578c4d41bce8, 2d71a0a8591484b78cdd9c75139882e4)
        RMD160 (7b2242bdcefd2604ecd96fb4aabf4415fc2a6b24, 8bd2258f58074e378e92a34d204a6a9ba79a6fd1)
        SHA1 (df4c50eacc108619560cc99c6c667c18b90f6389, e3c4e13f307ea22a1c3ee7e39d57d8620619221d)
        size (5041903, 5099786)
        modification time (Fri Jun 13 10:20:30 2008, Fri Jun 13 20:20:30 2008)
        cksum (2712827374, 1813282464)
        MD5 (a647512bf76f5adaababfd9d6a6ac015, bce978da0f3964de5cf9578c4d41bce8)
        RMD160 (df4930f11ec815031a1b0895cace2fa9380b4824, 7b2242bdcefd2604ecd96fb4aabf4415fc2a6b24)                             
        SHA1 (030497bf2f6dd2994ea594583aaf56b5aea25417, df4c50eacc108619560cc99c6c667c18b90f6389)
mtree: /usr checksum: 1666010597

Automation with cron

Finally, setup a cron job to run the " verify" commanded script and review the emails when they arrive. This cron job will run the script every 6 hours for example.

 #minute (0-59)
 #|   hour (0-23)
 #|   |    day of the month (1-31)
 #|   |    |   month of the year (1-12 or Jan-Dec)
 #|   |    |   |   day of the week (0-6 with 0=Sun or Sun-Sat)
 #|   |    |   |   |   commands
 #|   |    |   |   |   |
 #### file integrity check
 00   */6  *   *   *   /ids_dir/ verify

Questions, comments, or suggestions? Contact