weil die Hackerangriffe, vor allem erfolgreiche, nerven, und man solche auch bei aktuellester Contenido-Version nicht ausschließen kann, habe ich mir ein Überwachungsskript für die Verzeichnisse geschrieben.
Das Skript liegt in contenido/cronjobs und wird (mindestens) einmal am Tag aufgerufen und schickt einen Statusbericht per Mail.
Es verhindert nicht den erfolgreichen Angriff, sorgt aber für die zeitnahe Kenntnisnahme und gibt detailliert die Änderungen am Webspace aus. Bei mir hat es sich bereits sehr zuverlässig bewährt.
Das Script geht _alle_ Verzeichnisse auf dem Webspace, auch außerhalb der Contenido-Verzeichnisse durch und überprüft Veränderungen:
1 - enthält das Verzeichniss nur zulässige Dateien
2 - Änderungsdatum (wenn Heute oder Gestern) der enthaltenen Dateien.
Wer das Skript einsetzen möchte .... muss
a) alle Verzeichnisse im Webspace im Array $sollarrays ergänzen (rekursiv per PHP machen oder manuell

b) Serverpfad $pfad_praefix angeben
c) $mail - Variablen setzen.
d) cronjob tabelle aktualisieren oder per URL das Skript ausführen.
Zwei Sachen wären aus meiner Sicht noch zu verbessern:
1 - Veränderte Dateien werden für den aktuellen _und_ letzten Tag abgefragt. Veränderte Dateien und Verzeichnisse werden dann also an zwei aufeinanderfolgenden Tagen, also doppelt, gemeldet. Der Grund für die Abfrage von heute und gestern ist natürlich, dass wenn der cronjob um 22:00 läuft, ich sonst nicht weiß, was zwischen 22:00-23:59 passiert.
2 - Bei Verzeichnissen, die sich per Definition verändern dürfen, z.B. Upload und die Unterordner habe ich noch keinen befriedigenden Lösungsansatz. Möglicherweise wäre es sinnvoll, auf Dateiendung ".php" zu prüfen, weil solche Dateien dort nicht vorkommen dürfen.
Wenn jemand für diese beiden Aufgaben eine elegante Lösung weiß ....?
Leider ist mein Coding- und Comment-Style nicht so superdufte, ich denke aber, man kann durchsteigen. Für Kommentare und Verbesserungen bin ich gerne zu haben.
Code: Alles auswählen
<?php
/*****************************************
* File : hackkontrolle.php
* Project : Contenido -
* Descr : Verzeichnis√Ueberwachung um Hackerangriffe zu identifizeren. In Systemverzeichissen werden Dateien abgelegt, die da nicht hingehoeren. Diese werden durch dieses Skript erkannt, eine Nachricht wird abgesetzt. Das Skript wird durch cronjob gestartet.
√úberwachung der a) Contenido-Verzeichnisse:
contenido,contenido/includes, contenido/applets,contenido/cronjobs,contenido/external,contenido/external/backendedit,contenido/external/frontend,contenido/external/mozile,contenido/external/wysiwyg,contenido/images,contenido/images/actions,contenido/locale,contenido/logs,contenido/plugins,contenido/scripts,contenido/styles,contenido/temp,contenido/templates,contenido/tools,contenido/tools
cms, cms/includes, cms/js, cms/logs,cms/templates
conlib
docs, docs/api, docs/techref,docs/backend,docs/frontend,docs/modules,docs/plugins
downloads
pear, pear/CACHE, pear/HTML,pear/Log, pear/Net, pear/OLE,pear/OS,pear/PEAR,pear/scripts,pear/Spreadsheet, pear/XML
Erweitert um b) _alle_ Verzeichnisse auf dem Webspace, auch ausserhalb von Contenido. Es wird eine Lösung gesucht, fuer Verzeichnisse, die dynamischen Content enthalten und sich regelmäßig ändern dürfen.
* Author : Kloevekorn
* Created : 29.02.2008
******************************************/
require('../../contenido/classes/class.phpmailer.php');
$heute = date("Y-m-d");
$gestern = date("Y-m-d",(strtotime("now")-86400));
$pfad_praefix= '/dasIst/der/hosting/serverpfad.de/';
$handle = fopen('hackkontrolle.log', 'a');
//verzeichnisinhalte definieren:
$sollarrays = array(
'/'=>array('.htaccess','cms','conlib','contenido','docs','downloads','error404.html','index.html','logo.jpg','pear','php.ini','phpinfo.php','phpMyAdmin'),
'cms'=>array('cache','config.php','css','dbfs.php','error.php','front_content.php','front_crcloginform.inc.php','images','includes','index.php','js','logs','php.ini','templates','upload'),
'cms/logs'=>array('index.php'),
//-----und alle weiteren Verzeichnisse auf dem Webspace
)
;
//einzelnes öffnen der definierten Verzeichnisse aus $sollarrays, und Vergleich des Sollinhalts mit aktuell enthaltenen Dateien
foreach ($sollarrays as $key=>$sollarray) {
$verz = opendir($pfad_praefix.$key);
if ($verz){
$sollarray = array();
foreach ($sollarrays[$key] as $index) {
array_push($sollarray,$index);}
$linkl=array();
while ($file = readdir ($verz)) {
// akt. Verzeichnis auslesen
if($file != "." && $file != ".." && $file != $filename) {
// Ordner/Dateien ins Ist-Array
array_push ($linkl, "$file");
}
}
$count_ist = count($linkl);
$count_soll = count($sollarray);
// wenn sich das verzeichnis geändert hat, Array mit Dateinamen fuellen:
if ( $count_soll == $count_ist) {
//$fehlerstring .= 'OK: '.$key."\n";
$okays++;
}
elseif ($count_ist > $count_soll) {
for($x = 0; $x < $count_ist; $x++)
{ if(!in_array("$linkl[$x]", $sollarray))
{
$fehlerstring .= "\n".$key.":".$linkl[$x]." !!! \n\n";
fwrite ($handle,"Falsche Datei: $pfad_praefix.$key: $linkl[$x]\n");
$errors++;
}
}
}
else {$fehlerstring .= "\n\nACHTUNG: ".$key." ist unterschiedlich (ist:$count_ist / soll:$count_soll) - bitte prüfen.\n\n";
fwrite ($handle, "ACHTUNG: ".$key." ist unterschiedlich (ist:$count_ist / soll:$count_soll) - bitte prüfen.\n");
$errors++;
}
}
else {$fehlerstring .= "\n\nMeldung: ".$key. " konnte nicht geöffnet werden oder wurde nicht gefunden.\n\n";
fwrite ($handle, "\n\nMeldung: ".$key. " konnte nicht geöffnet werden oder wurde nicht gefunden.\n");
$errors++;
}
}
closedir($verz);
foreach($sollarrays as $key=>$sollarray) //geht natürlich auch mit dem ersten verzeichnis-array.
{if ($key != 'contenido/cronjobs'){ //cronjobs nicht, weil sich die dateien immer ändern dürfen
// $files=glob("$pfad_praefix$dir/*.*",GLOB_BRACE);
$files=glob("$pfad_praefix$key/*.*",GLOB_BRACE);
if (is_array($files))
{
{foreach ($files as $filename)
{ $filedate = date ("Y-m-d", filemtime($filename));
if ($filedate == ($heute) || $filedate==$gestern) {
$errors++;
fwrite ($handle, "Geaendert am ".$filedate.": ".$filename."\n");
$fehlerstring .= "\nGeaenderte Datei: ".$filedate.": ".$filename;
}
}}
}
}
}
//Ueberpruefung von CMS-Verzeichnissen, die sich aendern duerfen:
$dynamicDirs = array('cms/css','cms/cache','cms/images','cms/templates','cms/upload');
foreach ($dynamicDirs as $value) {
$files=glob("$pfad_praefix$value/*.*",GLOB_BRACE);
foreach ($files as $filename) {
if (preg_match('/(php|pl)\>/i', $filename)) {
if ($filename != 'index.php') {
$errors++;
fwrite ($handle, "Unzulaessige Datei \"$filename\" in $value \n");
$fehlerstring .= "\nGeaenderte Datei: ".$filedate.": ".$filename;
}
elseif ($filename == 'index.php') {
if ($filedate == $heute || $filedate==$gestern) {
$errors++;
fwrite ($handle, "Geaendert am ".$filedate.": ".$filename."\n");
$fehlerstring .= "\nGeaenderte Datei: ".$filedate.": ".$filename;
}
}
}
}
}
$ausgabestring = "OK: $okays Dateien/Verzeichnisse\n";
if ($errors>0) {$ausgabestring .= "Überprüfen ($errors Fehler: $fehlerstring";}
$mail = new PHPMailer();
$timestamp = time();
$datum = date("d.m.Y",$timestamp);
$uhrzeit = date("H:i",$timestamp);
$mail->From = "hackkontrolle@site.de";
$mail->FromName = "Hack-Kontrolle";
$mail->AddAddress("admin@site.de");
$mail->CharSet = "Mime-Version: 1.0 Content-Type: \"text/plain\"; charset=\"utf-8\" Content-Transfer-Encoding: \"quoted-printable\"";
$mail->Subject = "Hackkontroll site.de am $datum um $uhrzeit";
$mail->Body = $ausgabestring;
//EMail senden und überprüfen ob sie versandt wurde
if(!$mail->Send())
{
//$mail->Send() liefert FALSE zurück: Es ist ein Fehler aufgetreten
//echo "Fehler: Die Email konnte nicht gesendet werden ($datum $uhrzeit)". $mail->ErrorInfo >>hackgericht.log;
fwrite ($handle, "Fehler: Die Email konnte nicht gesendet werden ($datum $uhrzeit)\n");
}
else
{
//$mail->Send() liefert TRUE zurueck: Die Email ist unterwegs
//echo "Die Email wurde versandt. ($datum $uhrzeit)\n" >>hackgericht.log;
fwrite ($handle, "Email gesendet ($datum $uhrzeit).\n");
}
?>