PHP Script to track changes in your files

[info]Download Source code here comparefiles[/info]

Last week I wrote a simple php script for removal of eval(base64_decode()) virus. However it helps only once you know that your site is infected. The other part of the problem is to detect the infection as early as possible, and identify the infected files.

One of the many ways to early detection is to keep monitoring the files on your websever. Keep a database of all the files in your server, with a time stamp and a hash. Do this periodically and you have several snapshots to compare and see when the files changed. Once you know the files that are infected, you can restore ( if you have a backup) or try to fix them by removing the malicious code.

comparison.gif

I wrote a very simple script to achieve this task on my webserver. This is a very simple script. It lets you save MD5 values of all your files in a database with timestamp and later lets you compare the 2 timestamps to see which files have been added, deleted or changed.

I am not a programmer so I am sure this script can be further improved by someone experienced in programming. One area could be to somehow limit the number of files it process in a batch, just to account for a huge number of files on a server with limited memory. On my server, it took 27 seconds to run for 18,200 files, which is not too long, but on some server it may even take longer.

webfront.php


Who I am
I may be a small script, but I will help you generate a list of added, deleted or changed files by saving MD5 of files in a database and comparing 2 such snapshots. You can take as many snapshots as you want ( comparising of Date, filename and MD5 of file) and later compare any 2 snapshots you want. Before you use me , define your database credentials in connection.php

Create a System state Snapshot
If you are using me first time, you will have to take a snapshot first. I take time to run, depending on the number of files you have, but not as long as the comparison guy below me.


Compare Snapshots
Here are the snapshots I see you have taken. Select 2 timestamps to compare. I take very long to run. I was never told how to handle timeout :-(. If you are programer, please fix me with Ajax displaying stuff while PHP is still running a query.

" ;
echo "

" ;
echo " " ;
echo "
";
$SQL = "SHOW TABLES IN $db;";
$result = mysql_query($SQL);
echo "Second Snapshot
" ;
echo "
" ;
echo "";
echo "

";
}
?>

compare.php

 


strtotime($db2)) {$tmphold=$db1; $db1=$db2;$db2=$tmphold ; echo "Your first selection was $db1 and Second selection was $db2. I swiped selections to have latest one as second selection. If I didn't do that your file added and deleted list won't be correct
";}
if ($db1!=$db2)
{
ExceptDB ($db1,$db2);
CompareDB ($db1,$db2);
}
else {echo "You didn't give me anything to compare. Either both selections were same or there was no selection made. ";}
function ExceptDB ($db1,$db2)
{
$SQL = "SELECT *FROM $db1 WHERE FileName NOT IN ( SELECT FileName FROM $db2) ";
$result = mysql_query($SQL);
while ( $db_field = mysql_fetch_array($result, MYSQL_BOTH) )
{print $db_field['FileName']. "..Deleted
" ; }
$SQL = "SELECT *FROM $db2 WHERE FileName NOT IN ( SELECT FileName FROM $db1) ";
$result = mysql_query($SQL);
while ( $db_field = mysql_fetch_array($result, MYSQL_BOTH) )
{print $db_field['FileName']. "..Added
" ; }
}
function CompareDB ($db1,$db2)
{
$SQL = "SELECT * from $db1, $db2 WHERE $db1.FileName = $db2.FileName";
$result = mysql_query($SQL);
while ( $db_field = mysql_fetch_array($result, MYSQL_BOTH) )
{
if ($db_field[2]!=$db_field['MD5']) {print "$db_field[FileName].....changed
";}
}
}
?>

Snapshot.php


$file)
{UpdateDB ($file,md5_file($file));}
echo "Done ";
}
function ListFiles($dir) // Function to read directories recursively
{
if($dh = opendir($dir)) {
$files = Array();
$inner_files = Array();
while($file = readdir($dh)) {
if($file != "." && $file != ".." && $file[0] != '.') {
if(is_dir($dir . "/" . $file)) {
$inner_files = ListFiles($dir . "/" . $file);
if(is_array($inner_files)) $files = array_merge($files, $inner_files);
} else {
array_push($files, $dir . "/" . $file);
}
}
}
closedir($dh);
return $files;
}
}
?>
25) {echo "That was a lot of time ! Told you so.";} else {echo " Well, that wasn't too bad. I am great, ain't I"; }
?>