Toby is another reimplementation of the ever-useful tripwire program. The original tripwire-1.3 is available for free, but ran a bit slow in my test comparisons. For a period of several years, newer versions of tripwire were not free and thus served as the impetus for the creation of this program.
The first major difference from tripwire is that toby is written in perl. Cryptographic modules from CPAN are used, hopefully ensuring that as better algorithms are found for some routines (eg, MD5) then toby will inherit those improvements.
Currently, there are a few deficiencies in the program. There is no -loosedir option, so directories are strictly checked in the same way as files. Also, the configuration file is really just a perl subroutine -- making it both quite powerful and perhaps inaccessible to the casual user.
The basic operation of toby is simple enough:
Currently, the configuration code is a perl script which is executed from within toby. I haven't thought of a format for a config file which would be any better, so I have left it that way for now. A big advantage is that code to parse the config file isn't required, and the config script could get fancy (as the solaris sample does) and programmatically decide what should be monitored.
While traversing the file system based on directory trees defined in the config script, hashes are taken of each file. Currently, only MD5 and SHA-1 hashes are taken -- these being the only hashes available on CPAN. For symbolic links, the hashes are taken of the link itself, not the file pointed to.
One shortcoming in the handling of the databases is that both the old and the new database are kept entirely in memory, which could result in large data structures. I spent a few agonizing days trying to keep only a minimum amount of information in memory, but it complicated the program and ultimately never worked right in the face of certain changes to the file system. In practice, a typical database is only a few megabytes in size, so this is not as onerous as I might have thought.
Another (coding) shortcoming is that I support the tripwire notation for defining comparisons for changes in files. Is this notation useful in any way? Or would it make more sense to remove the support and let users build their own comparison routines?
When using a host based intrusion detection system such as Toby, it's important to keep in mind that a fundamental assumption in the software is that the Operating System does not lie. For instance, when you run your file integrity checker, a big assumption being made is that it hasn't been tampered with to give you false information. As Toby is only a perl script, it's easy to see how it might be tampered with; compiled programs such as tripwire have the same problem, though.
Arhuman points out that this could be solved by installing your software and database on an encrypted loopback partition, and only mounting the partition when you are about to do a check. This is still not foolproof, though, because a dedicated hacker could wait for the moment that you mount the encrypted partition and then modify the program before you execute it. (Granted, that is fairly unlikely since they won't even know which integrity checker you are using, or even that you are using one at all.)
More devious, and easier than predicting what file integrity checker is being used, is to modify the kernel to return different results when a file is read versus when it is executed. Then /bin/login could be modified with impugnity and no checksumming would ever reveal the difference. There is no defense against this, except to place your disks in a secure machine and run the integrity check on that machine. Every integrity check available will succumb to this sort of attack.
So far, I have only come up with one plan that guarantees the correctness of a file integrity check. To do so requires two machines. Machine A is your regular Internet accessible machine; the system disk must be a SCSI disk. The disk is on a chain shared with Machine B, so that the disk is accessible from both machines simultaneously. Machine B must have a system disk that is not on the shared chain, and must not be accessible from any network. Assuming that Machine B is absolutely secure, you can now run your file integrity check from this machine on the shared disk, and be sure that the results are true. (Note that you require SCSI host controllers that are capable of sharing a chain in this manner.)
The bottom line is that file integrity checkers are not infallible.