Why configure a third-party file integrity checker when you already have mtree?
If you care about the security of your server, you need file integrity checking. Without it, you may never know if the system has been compromised by a rootkit or an active intruder. You may never know if your logs have been modified and your ls and ps utilities replaced by Trojaned equivalents.
Sure, you can download or purchase a utility such as tripwire, but you already have the mtree utility [Hack #54] ; why not use it to hack your own customized file integrity utility?
mtree lists all of the files and their properties within a specified directory structure. That resulting list is known as a specification. Once you have a specification, you can ask mtree to compare it to an existing directory structure, and mtree will report any differences. Doesn't that sound like a file integrity checking utility to you?
6.6.1 Creating the Integrity Database
Let's see what happens if we run mtree against /usr/bin:
# cd /usr/bin # mtree -c -K cksum,md5digest,sha1digest,ripemd160digest -s 123456789 \ > /tmp/mtree_bin mtree: /usr/bin checksum: 2126659563
Let's pick apart that syntax in Figure 6-2.
If you run that command, it will perk along for a second or two, then write the value of the checksum to your screen just before giving your prompt back. That's it; you've just created a file integrity database.
Before we take a look at that database, take a moment to record the seed you used and the checksum you received. Note that the more complex the seed, the harder it is to crack the checksum. Those two numbers are important, so you may consider writing them on a small piece of paper and storing them in your wallet. (Don't forget to include a hint to remind you why you have that piece of paper in your wallet!)
Now let's see what type of file we've just created:
# file /tmp/mtree_bin /tmp/mtree_bin: ASCII text # ls -l /tmp/mtree_bin -rw-r--r-- 1 root wheel 111503 Nov 23 11:46 /tmp/mtree_bin
It's an ASCII text file, meaning you can edit it with an editor or print it directly. It's also fairly large, so let's use head to examine the first bit of this file. Here I'll ask for the first 15 lines:
# head -n 15 /tmp/mtree_bin # user: dru # machine: genisis # tree: /usr/bin # date: Sun Nov 23 11:46:21 2003 # . /set type=file uid=0 gid=0 mode=0555 nlink=1 flags=none . type=dir mode=0755 nlink=2 size=6656 time=1065005676.0 CC nlink=3 size=78972 time=1059422866.0 cksum=1068582540 \ md5digest=b9a5c9a92baf9ce975eee954994fca6c \ sha1digest=a2e4fa958491a4c2d22b7f597f05885bbe8f6a6a \ ripemd160digest=33c74b4200c9507b4826e5fc8621cddb9e9aefe2 Mail nlink=3 size=72964 time=1059422992.0 cksum=2235502998 \ md5digest=44739ae79f3cc89826f6e34a15f13ed7 \ sha1digest=a7b89996ffae4980ad87c6e7c56cb207af41c1bd \
The specification starts with a nice summary section. In my example, the user that created the specification was dru. Note that I used the su utility to become the superuser before creating the specification, but my login shell knew that I was still logged in as the user dru. The summary also shows the system name, genisis, the directory structure in question, /usr/bin, and the time the specification was created.
The /set type=file line shows the information mtree records by default. Notice that it keeps track of each file's uid, gid, mode, number of hard links, and flags.
Then, each file and subdirectory in /usr/bin is listed one at a time. Since I used -K to specify three different cryptographic hashes, each file has three separate hashes or digests.
6.6.2 Preparing the Database for Storage
Once you've created a specification, the last place you want to leave it is on the hard drive. Instead, sign that file, encrypt it, transfer it to a different medium (such as a floppy), and place it in a secure storage area.
To sign the file:
# md5 /tmp/mtree_bin MD5 (/tmp/mtree_bin) = e05bab7545f7bdbce13e1bb04a043e47
You may wish to redirect that resulting fingerprint to a file or a printer. Keep it in a safe place, as you'll need it to check the integrity of the database.
Next, encrypt the file. Remember, right now it is in ASCII text and susceptible to tampering. Here I'll encrypt the file and send the newly encrypted file to the floppy mounted at /floppy:
# openssl enc -e -bf -in /tmp/mtree_bin -out /floppy/mtree_bin_enc enter bf-cbc encryption password: Verifying - enter bf-cbc encryption password:
The syntax of the openssl command is fairly straightforward. I decided to encrypt enc -e with the Blowfish -bf algorithm. I then specified the input file, or the file to be encrypted. I also specified the output file, or the resulting encrypted file. I was then prompted for a password; this same password will be required whenever I need to decrypt the database.
Once I verify that the encrypted file is indeed on the floppy, I must remember to remove the ASCII text version from the hard drive:
# rm /tmp/mtree_bin
I'll then store the floppy in a secure place, such as the safe that contains my backup tapes.
6.6.3 Using the Integrity Database
Once you have an integrity database, you'll want to compare it periodically to the files on your hard drive. Mount the media containing your encrypted database, and then decrypt it:
# openssl enc -d -bf -in /floppy/mtree_bin_enc -out /tmp/mtree_bin enter bf-cbc encryption password:
Notice that I used basically the same command I used to encrypt it. I simply replaced the encrypt switch (-e) with the decrypt switch (-d). The encrypted file is now the input, and the plain text file is now the output. Note that I was prompted for the same password; if I forget it, the decryption will fail.
Before using that database, I first want to verify that its fingerprint hasn't been tampered with. Again, I simply repeat the md5 command. If the resulting fingerprint is the same, the database is unmodified:
# md5 /tmp/mtree_bin MD5 (/tmp/mtree_bin) = e05bab7545f7bdbce13e1bb04a043e47
Next, I'll see if any of my files have been tampered with on my hard drive:
# cd /usr/bin # mtree -s 123456789 < /tmp/mtree_bin mtree: /usr/bin checksum: 2126659563
If none of the files have changed in /usr/bin, the checksum will be the same. In this case it was. See why it was important to record that seed and checksum?
What happens if a file does change? I haven't built world on this system in a while, so I suspect I have source files that haven't made their way into /usr/bin yet. After some poking about, I notice that /usr/src/usr.bin has a bluetooth directory containing the source for a file called btsockstat. I'll install that binary:
# cd /usr/src/usr.bin/bluetooth/btsockstat # make # make install # ls -F /usr/bin | grep btsockstat btsockstat*
Now let's see if mtree notices that extra file:
# cd /usr/bin # mtree -s 123456789 < /tmp/mtree_bin . changed modification time expected Wed Oct 1 06:54:36 2003 found Sun Nov 23 16:10:32 2003 btsockstat extra mtree: /usr/bin checksum: 417306521
Well, it didn't fool mtree. That output is actually quite useful. I know that btsockstat was added as an extra file, and I know the date and time it was added. Since I added that file myself, it is an easy matter to resolve. If I hadn't and needed to investigate, I have a time to assist me in my research. I could talk to the administrator who was responsible at that date and time, or I could see if there were any network connections logged during that time period.
Also note that this addition resulted in a new checksum. Once the changes have been resolved, I should create a new database that represents the current state of /usr/bin. To recap the necessary steps:
6.6.4 Deciding on Which Files to Include
When you create your own integrity database, ask yourself, "Which files do I want to be aware of if they change?" The answer is usually your binaries or applications. Here is a list of common binary locations on a FreeBSD system:
The sbin directories are especially important because they contain system binaries. Most ports will install to /usr/local/bin or /usr/X11R6/bin.
The second question to ask yourself is "How often should I check the database?" The answer will depend upon your circumstances. If the machine is a publicly accessible server, you might consider this as part of your daily maintenance plan. If the system's software tends to change often, you'll also want to check often, while you can still remember when you installed what software.
6.6.5 See Also