These scripts are *really* rough they were created with great haste and not much care for want of any good way to check the integrity of an OS X system (why can't apple include anything better than a simple checksum in the package receipts?). These script make use of the mtree(8) utility on an OS X machine.
How to use them:
Make a directory somewhere copy these scripts into that directory run the collect_data.sh script as root squirrel the resulting data directory away, when you have some reason to doubt the integrity of your system run the check_data.sh obviously you will need to run collect_data.sh again when you run software update or install a new version of xcode.
Its possible to take the data output directory from one machine and run it on another unfortunately you may see a lot of differences that
are irrelevant for a variety of reasons including differing kernel extensions, differing software load (From apple e.g. different versions of Xcode) etc
Other things I would add, check for suid binaries not on a list say the one from the CERT OS X security guide, other similar things from
/etc/security on openbsd that make sense, more directories that contain apple stuff, checks of the launchd daemons/agents directories
(and a comparison with whats in the plists as disabled but launchd has loaded) many other things
and of course something better than mtree that would look at the versions.plist files etc and go the version you have is different from the
spec file but wont spew 400 file changes at you because of that.
collect_data.sh
#!/bin/bash
secure_paths='/bin /sbin /usr/bin /usr/sbin /System/Library/Extensions /System/Library/CoreServices /System/Library/Frameworks /System/Library/PrivateFrameworks /System/Library/LoginPlugins /usr/libexec /usr/lib'
if [ ! -d data ] ; then
mkdir data
fi
echo "Localizable.strings" >> /tmp/$$
echo "version.plist" >> /tmp/$$
echo "Info.plist" >> /tmp/$$
echo "*.nib" >> /tmp/$$
for DIR in $secure_paths ; do
fname=`echo $DIR | sed 's/^\///' | sed 's/\//./g'`;
/usr/sbin/mtree -X /tmp/$$ -cx -p $DIR -k 'uname,gname,sha1digest,type,size,md5digest,ripemd160digest,mode' | tail +5 > data/$fname.mtree
done
rm /tmp/$$
# record the kernel sums
/sbin/md5 /mach_kernel > data/kernel.sums
/usr/bin/shasum /mach_kernel >> data/kernel.sums
check_data.sh
#!/bin/bash
if [ ! -d data ] ; then
echo "No data directory exists";
exit 255
fi
# some stuff to ignore
echo "Localizable.strings" >> /tmp/$$
echo "version.plist" >> /tmp/$$
echo "Info.plist" >> /tmp/$$
echo "*.nib" >> /tmp/$$
U=$IFS
IFS=$'\n'
for MTREE in `ls data/*.mtree` ; do
path=`echo $MTREE | sed 's/^data\//\//' | sed 's/\.mtree//' | sed 's/\./\//g'`;
echo "checking $path";
/usr/sbin/mtree -X /tmp/$$ -f $MTREE -p $path;
done
IFS=$U
rm /tmp/$$
# record the kernel sums
/sbin/md5 /mach_kernel > /tmp/$$-kernel.sums
/usr/bin/shasum /mach_kernel >> /tmp/$$-kernel.sums
ksumdiff=`/usr/bin/diff /tmp/$$-kernel.sums data/kernel.sums 2>&1`
if [ $? -ne 0 ] ; then
echo "Kernel sums differ"
fi
rm /tmp/$$-kernel.sums