I've cleaned up the testutils.pl script and the instructions, and am re-posting this to get a cleaner copy in the archives.
-
I've been thinking about this rootkit detection and exposure issue, and here are my thoughts:
To me, in determining the integrity of any system, the core question is, have the system utilites been compromised? In the equestrian sporting world there is a saying, "Pretty is as Pretty does." From this philosophy, what do the utilites say, and is there a difference between the output of the utilities on the machine and "known clean" utilities? I can't get completely past the feeling that any other test is just window dressing, and while they are all useful tools, it seems to me that any of them could possibly be compromised with a sophisticated enough rootkit. When you are root, _in theory_ you can rewrite md5sums, dates, and even remote hosts used to retrieve live trusted sums. I know of no rootkits that currently do this, but I can imagine how it might be possible.
Anyways, with help from a "Building a live CD" article in this month's Linux Journal, here is the procedure that I have come up with to test system utilities on any machine without a reboot:
You need a knoppix cd and about 2 gig of space to use the utilities on the knoppix cd. Here's the recipe:
Drop the KNOPPIX cd into the tray. Download the cloop-utils package, on debian this is
# apt-get install cloop-utils
Mount the Knoppix cd:
# mount /dev/cdrom /mnt
Extract the compressed knoppix filesystem (this will take a while)
# extract_compressed_fs /mnt/KNOPPIX/KNOPPIX > /tmp/knoppix-compressed
Then mount the extracted filesystem.
# mkdir /tmp/knoppix; mount -o loop /tmp/knoppix-compressed /tmp/knoppix
Okay, now you're set. Is there a difference in the output of the current system utilities and that of the knoppix cd utilities? Here's a perl script to check:
-------8<------------------------------------------ #!/usr/bin/perl # testutils.pl Don Erickson 2005 ######################################################################## # # This script will test the output of commonly trojaned programs. # # The live Knoppix disc must be cloop mounted at /tmp/knoppix/ # ####################################################################### @testthese = ("ps ax", "df", "netstat", "ifconfig", "ls -R", "iptables -L", #"du / -x --exclude=tmp" );
$i=0; $outfile="/tmp/testresults.txt"; $sysout="/tmp/sysout";$knoppixout="/tmp/knoppixout";
open(OUTFILE,">$outfile") || die "Can't open $outfile"; close(OUTFILE,"$outfile"); open(OUTFILE,">>$outfile");
foreach (@testthese) {
$testpath = `which $testthese[$i]`;$testpath =~ s/\n//; $testargs = $testthese[$i];$testargs =~ s/^[^ ]+//; $testthis = $testpath.$testargs;
print "Testing output of '$testthis'\n"; print OUTFILE "\n########\nDiff of $testthis :: '<' = system '>' = knoppix\n\n"; print "System..."; system("$testthis > $sysout"); print "done. Knoppix..."; system("env LD_LIBRARY_PATH=/tmp/knoppix/lib /tmp/knoppix$testthis > $knoppixout"); print "done.\n"; system("env LD_LIBRARY_PATH=/tmp/knoppix/lib /tmp/knoppix/usr/bin/diff $sysout $knoppixout >> $outfile") == 0; $i++;
}
print OUTFILE "Tests concluded.\n"; print "Tests concluded.\n"; print "Read the results in $outfile\n"; exit;
--------->8-----------------------------
Obviously this script can be edited to test the output of any utility that you wish to check, just add the command to the @testthese array. I'm sure that there are lots of lists of "normally rewritten utilities" for most rootkits on the web. The 'du' test is commented out as this one will take a chunk of time to run. The results will show expected differences, but any seriously funny stuff should reach out and grab you by the throat.
If anybody sees any flaws in my thinking here, feel free to point them out. At this point I don't see why this wouldn't work, and while trojaned kernel modules are getting more common in rootkits, I can't think of how a trojaned utility could hide from this type of scrutiny.
Regards,
-Don
I have a dream . . . :)
I use phpwebalbum for my church website and I frequently post photos I take on Sunday mornings to the website. However, with all the photos already posted, it's hard for end users to find the new photos (via the phpwebalbum interface).
So, I decided to create a new folder called WhatsNew. Then, I did a search for any files added to the album in the last 48 hours:
find /path/to/photos -mtime 48 -name '*.jpg'
and piped it to a text file.
Then, I wanted to create symbolic links to the JPG files but I wanted to use the text file to pipe the information to the ln command.
So far, I have been unsuccesful. I guess my next option is to write a script file, but I'm not very good at those yet (beyond really basic ones).
Any suggestions.
Thanks!
Jon Moss [email protected]
On Sunday 06 March 2005 02:30 pm, Jon Moss wrote:
find /path/to/photos -mtime 48 -name '*.jpg' [> textfile]
Then, I wanted to create symbolic links to the JPG files but I wanted to use the text file to pipe the information to the ln command.
Rather than pipe the output to a text file, use the "exec" option of find to execute the symlink command - something like
find /path/ -mtime 48 -name '*.jpg' -exec -s /path/{} WhatsNew/{} ;
(I had to trim the paths to keep the command from wrapping, but you get the general idea.)
The man page for find has some details on using the -exec option; they caution that the double braces that substitute the current filename might need to be quoted or escaped as does the semicolon that ends the command string, depending on context and the shell.
On Sun, 6 Mar 2005, Jonathan Hutchins wrote:
Rather than pipe the output to a text file, use the "exec" option of find to execute the symlink command - something like
find /path/ -mtime 48 -name '*.jpg' -exec -s /path/{} WhatsNew/{} ;
While not as elegant as Jonathan's solution, the following has the advantage or totally regenerating the new picture links when it is run - first cd to the directory with your photos:
----8<------------------------------- #! /usr/bin/perl system("rm -r newpix; mkdir newpix"); (@newpix)=qx (find . -mtime -3 -name '*.jpg'); print "@newpix\n"; foreach $_ (@newpix) { chomp ($link =($_)); $newlink = "newpix/$link"; system ("ln -s '$link' '$newlink'"); };
print "\n\nDone.\n"; exit;
---->8---------------------------
This will link to files created in the last 36 hours, the -3 (days) argument to mtime.
Regards,
-Don
Thanks for both suggestions. I will try both of them.
Have a great week!
Jon Moss
On Sun, 6 Mar 2005, Jonathan Hutchins wrote:
Rather than pipe the output to a text file, use the "exec" option of find to execute the symlink command - something like
find /path/ -mtime 48 -name '*.jpg' -exec -s /path/{} WhatsNew/{} ;
While not as elegant as Jonathan's solution, the following has the advantage or totally regenerating the new picture links when it is run - first cd to the directory with your photos:
----8<------------------------------- #! /usr/bin/perl system("rm -r newpix; mkdir newpix"); (@newpix)=qx (find . -mtime -3 -name '*.jpg'); print "@newpix\n"; foreach $_ (@newpix) { chomp ($link =($_)); $newlink = "newpix/$link"; system ("ln -s '$link' '$newlink'"); };
print "\n\nDone.\n"; exit;
---->8---------------------------
This will link to files created in the last 36 hours, the -3 (days) argument to mtime.
Regards,
-Don
Jon Moss wrote:
Thanks for both suggestions. I will try both of them.
Have a great week!
Another option for you. I don't grok perl well, and find the syntax for the find command difficult to remember (and complex to properly escape at the command line). For a simple task like yours, I'd fall back to one of my shell script standbys: using "while read ..." to loop over every line of input. You can either do this inline, with pipe symbols, or as a seperate command using a text file to store the intermediate results (and allow for visual verification/editing).
Just type the following at the command line
while read VALUE ; do # Put your commands here echo $VALUE done < my.text.file
NOTES:
You don't have to type everything on one line...once you type the 'while', the shell interpreter knows the command isn't finished until you type 'done' and keeps giving you new prompts.
You can also easily do the same thing with piped command output, ie:
find /path/to/photos -mtime 48 -name '*.jpg' | while read FILE ; do ln -s $FILE my/directory/$FILE done