home January 01, 2017

Intrusion Detection (IDS) using mtree


simple and effective file level intrusion detection

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. We are going to name the script "ids.sh", but can can name it anything you like.

First, you need to have the binary called mtree (OpenBSD or FreeBSD) or freebsd-mtree (Ubuntu linux). Mtree is installed on OpenBSD and FreeBSD by default. If you are running Ubuntu Linux just install the package, "sudo apt-get install freebsd-buildutils". Once you have the binary set the script variable MTREE to the binary name. NOTE: the shell script is running in bash so make sure the shebang, "#!/usr/local/bin/bash" actually points to bash. This means #!/usr/local/bin/bash on OpenBSD and #!/bin/bash on Ubuntu for example.

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 hash on the files. It is a randomly generated 23 digit number you can make up for this purpose. The same $KEY value is also needed to verify the hash values against. If an unauthorized person had the hash files, but not the $KEY value from the script, then the attackers would not be able to check or spoof the validity of your files. The second variable is $DIR. This is the directory that the script and hash checked files generated by mtree will reside.

The Script: ids.sh

#!/usr/local/bin/bash
#
## moneyslow.com  ids.sh
#

if [ $# -eq 0 ]
   then
    echo ""
    echo "  moneyslow.com    ./ids.sh \$arg"
    echo "--------------------------------------"
    echo "generate = generate IDS signatures"
    echo "verify   = verify files against known signatures"
    echo ""
   exit
 fi

## mtree binary (OpenBSD: mtree and Linux: freebsd-mtree)
MTREE=mtree

## IDS seed signature key
KEY=12345946598234534539234

## IDS signature directory
DIR=/ids_dir

if [ $1 = "generate" ]
   then
     rm -rf $DIR/mtree_*
     cd $DIR
     $MTREE -c -K cksum,md5,sha1,sha512 -s $KEY -p /bin > mtree_bin
     $MTREE -c -K cksum,md5,sha1,sha512 -s $KEY -p /sbin > mtree_sbin
     $MTREE -c -K cksum,md5,sha1,sha512 -s $KEY -p /usr > mtree_usr
     logger IDS generate IDS signatures
     chmod 600 $DIR/mtree_*
   exit
 fi

if [ $1 = "verify" ]
   then
     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
   exit
 fi
  

Running the script

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 "ids.sh" with the argument "generate". To verify the hash values against the files currently on the system execute the script "ids.sh" with the argument "verify". During the verify process an email with the results are sent to the root user.

Generate the file hashes ( ./ids.sh generate )

Now that you have made the /ids_dir, copied the script "ids.sh" into /ids_dir and made up a new 23 digit value for KEY we are ready to run ids.sh for the first time. Execute the command "./ids.sh generate".

The "generate" method will run and create a cksum AND md5 AND sha1 AND sha512 digest of every file and directory under /bin, /sbin and /usr. The reason we use more then one sum method is it is more difficult to crack multiple, independent digests. If there is a known weakness in chksum for example, then the file can also be verified against the cksum, md5, sha1 and sha512 sums. It is much harder for an attacker to falsify all methods. If you look inside of the mtree_bin file you will see each digest listed. For example, this is the listing for the file system binary, "ls".

ls  size=30208 time=1389912006.000000000 cksum=993622937 \
    md5digest=bf0d29a02c4a797418010404ff498ce3 \
    sha1digest=22e46e8e1fbd3a31e3192cc4d497d4ef6cdfb3a7 \
    sha512=26ace806c50decda4d468de0585e5a1ad0e94d24ae802788614de16b1c47a80b77733a2f003a2a0563e84a5d24869342762501924593153e7aa91174671b5b7a

Once ids.sh 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. You are welcome to open up the mtree_* files and take a look at the hashes and file info.

 -rwx------  1 root      321 Jan 10 10:20 ids.sh
 -rw-------  1 root   234567 Jan 10 10:20 mtree_bin
 -rw-------  1 root    34567 Jan 10 10:20 mtree_sbin
 -rw-------  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.

Verify - Email report of an unmodified system ( ./ids.sh verify )

Now it is time to run "./ids.sh 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@your_machine.org (Root User) 
To: root@your_machine.org
Date: Fri, 13 Jun 2910 10:20:30 -1000 (FDT) 
Subject: machine.domain.lan file integrity check

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

Verify - Email report of a modified system ( ./ids.sh verify )

If mtree finds a file that has been modified, deleted or added since the last run of "./ids.sh 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 "./ids.sh generate" to update the hash files.

From: root@your_machine.org (Root User) 
To: root@your_machine.org
Date: Fri, 13 Jun 2910 20:20:30 -1000 (FDT) 
Subject: machine.domain.lan file integrity check

mtree: /bin checksum: 893663885
mtree: /sbin checksum: 3292978967
local/sbin:
        modification time (Fri Jun 13 10:20:30 2910, Fri Jun 13 20:20:30 2910)
local/sbin/route:
        size (5099786, 5105218)
        modification time (Fri Jun 13 10:20:30 2910, Fri Jun 13 20:20:30 2910)
        cksum (1813282464, 116976809)
local/sbin/reboot:
        size (5041903, 5099786)
        modification time (Fri Jun 13 10:20:30 2910, Fri Jun 13 20:20:30 2910)
        cksum (2712827374, 1813282464)
mtree: /usr checksum: 1666010597

Automation with cron

Finally, setup a cron job to run the "ids.sh 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/ids.sh verify