small script to check your site for file changes

Coding Critique is the place to post source code for peer review by other members of DevNetwork. Any kind of code can be posted. Code posted does not have to be limited to PHP. All members are invited to contribute constructive criticism with the goal of improving the code. Posted code should include some background information about it and what areas you specifically would like help with.

Popular code excerpts may be moved to "Code Snippets" by the moderators.

Moderator: General Moderators

Post Reply
User avatar
egg82
Forum Contributor
Posts: 156
Joined: Sat Oct 01, 2011 9:29 pm
Location: Colorado, USA

small script to check your site for file changes

Post by egg82 »

Also could be described as a small "anti-hack" log. Basically it checks your site's files from wherever it's sitting.
It is infinitely recursive, so if you put it in your site's root and cron it every hour or two, you should be able to find any changes in any file extensions you wish via the generated log file.

a few points:
this by no means should be the only security measure on a website. It does help, but it does not do it all.
this was written using a windows machine, so all new lines are "\r\n" instead of "\n" - just a forewarning.
this does check for additions and removals as well as changes. It gets as specific as naming the file(s) created/removed/changed
this does not check databases. Why? Because databases are usually dynamic. You would get a flood of messages
This is not the cleanest code in the world, but it works and it works well (to the extent of my testing)

Code: Select all

<?php
$include = "php, htm, html";
$file = "check_errors.txt";
$md5_file = "check_md5.txt";

//------------------------

$include_array = explode(",", preg_replace("/\s+/", "", $include));
$md5_array = array();
$dir_array = array();
$files_array = array();
$file_handle = fopen($file, "a");
$md5_handle = fopen($md5_file, "r");

$handle = opendir(getcwd());
if(!$handle){
	fwrite($file_handle, "Could not get main directory\r\n");
	fclose($file_handle);
	exit();
}
$dir_string = getcwd();
while(($entry = readdir($handle)) !== false){
	if($entry != "." and $entry != ".."){
		if(is_dir($dir_string."\\".$entry)){
			if(!in_array($dir_string."\\".$entry, $dir_array)){
				array_push($dir_array, $dir_string."\\".$entry);
			}
		}else{
			if(in_array(substr(strrchr($entry, "."), 1), $include_array, true) == true){
				if(!in_array($dir_string."\\".$entry, $files_array)){
					array_push($files_array, $dir_string."\\".$entry);
				}
			}
		}
	}
}
closedir($handle);
if(count($dir_array) == 1 and (!isset($dir_array[0]) or $dir_array[0] == "")){
	$dir_array = array();
}
if(count($files_array) == 1 and (!isset($files_array[0]) or $files_array[0] == "")){
	$files_array = array();
}

for($i=0;$i<count($dir_array);$i++){
	$handle = opendir($dir_array[$i]);
	if(!$handle){
		fwrite($file_handle, "Could not get directory ".$dir_array[$i]."\r\n");
		fclose($file_handle);
		exit();
	}
	$dir_string = $dir_array[$i];
	while(($entry = readdir($handle)) !== false){
		if($entry != "." and $entry != ".."){
			if(is_dir($dir_string."\\".$entry)){
				if(!in_array($dir_string."\\".$entry, $dir_array)){
					array_push($dir_array, $dir_string."\\".$entry);
				}
			}else{
				if(in_array(substr(strrchr($entry, "."), 1), $include_array, true) == true){
					if(!in_array($dir_string."\\".$entry, $files_array)){
						array_push($files_array, $dir_string."\\".$entry);
					}
				}
			}
		}
	}
	closedir($handle);
}
if(count($dir_array) == 1 and (!isset($dir_array[0]) or $dir_array[0] == "")){
	$dir_array = array();
}
if(count($files_array) == 1 and (!isset($files_array[0]) or $files_array[0] == "")){
	$files_array = array();
}
for($i=0;$i<count($files_array);$i++){
	array_push($md5_array, md5_file($files_array[$i]));
}

$added_array = array();
$removed_array = array();
$changed_array = array();
$files_array2 = array();
$md5_array2 = array();

$i = 0;
while(!feof($md5_handle)){
	$files_array2[$i] = trim(fgets($md5_handle));
	$md5_array2[$i] = trim(fgets($md5_handle));
	$i++;
}
fclose($md5_handle);
if(count($files_array2) == 1 and (!isset($files_array2[0]) or $files_array2[0] == "")){
	$files_array2 = array();
}
if(count($md5_array2) == 1 and (!isset($md5_array2[0]) or $md5_array2[0] == "")){
	$md5_array2 = array();
}

if(count($files_array)>count($files_array2)){
	do{
		array_push($files_array2, "");
		array_push($md5_array2, "");
	}while(count($files_array)>count($files_array2));
}elseif(count($files_array2)>count($files_array)){
	do{
		array_push($files_array, "");
		array_push($md5_array, "");
	}while(count($files_array2)>count($files_array));
}

for($i=0;$i<count($files_array);$i++){
	if($files_array[$i] != ""){
		if(!in_array($files_array[$i], $files_array2)){
			array_push($added_array, $files_array[$i]);
		}
	}
	if($files_array2[$i] != ""){
		if(!in_array($files_array2[$i], $files_array)){
			array_push($removed_array, $files_array2[$i]);
		}
	}
	if($md5_array[$i] != ""){
		if(!in_array($md5_array[$i], $md5_array2) and !in_array($files_array[$i], $added_array) and !in_array($files_array[$i], $removed_array)){
			array_push($changed_array, $files_array[$i]);
		}
	}
}
if(count($added_array) == 1 and (!isset($added_array[0]) or $added_array[0] == "")){
	$added_array = array();
}
if(count($removed_array) == 1 and (!isset($removed_array[0]) or $removed_array[0] == "")){
	$removed_array = array();
}
if(count($changed_array) == 1 and (!isset($changed_array[0]) or $changed_array[0] == "")){
	$changed_array = array();
}

$total_string = "Check at ".date("m/d/Y")." ".date("H:i:s")." -";
$wrong = 0;
if(count($added_array)>0){
	$wrong++;
	$total_string .= " Added files: (".implode(", ", $added_array).")\r\n";
}
if(count($removed_array)>0){
	$wrong++;
	$total_string .= " Removed files: (".implode(", ", $removed_array)."\r\n)";
}
if(count($changed_array)>0){
	$wrong++;
	$total_string .= " Changed files: (".implode(", ", $changed_array).")\r\n";
}
if($wrong == 0){
	$total_string .= " OK\r\n";
}

fwrite($file_handle, $total_string);
fclose($file_handle);

$new_string = "";
for($i=0;$i<count($files_array);$i++){
	$new_string .= $files_array[$i]."\r\n".$md5_array[$i]."\r\n";
}
$md5_handle = fopen($md5_file, "w");
fwrite($md5_handle, trim($new_string));
fclose($md5_handle);
?>
enjoy, and as always critique is welcomed :D
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Re: small script to check your site for file changes

Post by Chris Corbyn »

I haven't read your code, which is quite dense and procedural, but you may be able to greatly simplify it with http://www.php.net/manual/en/book.fam.php... this would be a long-running script, rather than a run-every-so-often script.

From a quick overview of the structure of your code, I'd say that you should begin by breaking it down into smaller functions, which will almost certainly make that deep nesting easier to follow and the code easier to maintain ;)
User avatar
egg82
Forum Contributor
Posts: 156
Joined: Sat Oct 01, 2011 9:29 pm
Location: Colorado, USA

Re: small script to check your site for file changes

Post by egg82 »

Chris Corbyn wrote:I haven't read your code, which is quite dense and procedural, but you may be able to greatly simplify it with http://www.php.net/manual/en/book.fam.php... this would be a long-running script, rather than a run-every-so-often script.

From a quick overview of the structure of your code, I'd say that you should begin by breaking it down into smaller functions, which will almost certainly make that deep nesting easier to follow and the code easier to maintain ;)
My, they really do have a function or class for everything!
What's PHP's overhead?

Anyway, I just did this for fun and thought i'd share because it might be useful to someone down the road. Though if you want to use PHP's FAM, be my guest! :P
Francois99
Forum Newbie
Posts: 1
Joined: Fri Nov 08, 2013 8:40 pm

Re: small script to check your site for file changes

Post by Francois99 »

Thank you very much for this usefull script!
Post Reply