Neben dem Script, welches dann schlussendlich den Viagraspamcode ausgibt (siehe neulich), werden noch weitere Scripte in die PHP-Dateien injiziert, diese fungieren dann als Backdoor, um beliebigen (php) Code auszuführen.
Damit das klappt, muss der Code quasi "auf Zuruf" ausgeführt werden. Eine Version, die ich gefunden habe, arbeitet mit eval();
in Verbindung mit base64_decode();
, eine andere in Verbindung mit gzinflate();
und noch eine mittels str_rot13();
.
Die, die mir am meisten Kopfzerbrechen machte, arbeitet mit preg_replace();
, in Verwendung mit dem (bösen!) "e
"-Modifier - d.h. das Ergebnis der Ersetzung wird direkt ausgeführt. Ersetze also irgendeinen String mit einem Funktionsaufruf und *bam* - Code wird ausgeführt.
Wird der Befall erstmal bekannt, wäre es recht einfach, mittels grep
in den Dateien nach diesen Funktionsnamen zu suchen, deshalb versuchen die Angreifer, diese zu verschleiern, genauso wie die Befehlskette, die am Ende ausgeführt wird.
PHP spielt ihnen dabei in die Hände, denn für PHP ist z.b. print_r($arr);
genau das Gleiche wie $f = "print_r"; $f($arr);
.
Der Name einer Funktion kann also als String in eine Variable gespeichert werden, und schreibt man diese dann mit "()" dazu, funktionierts.
Einen String kann man auch konkatinieren, also geht auch das: $f = "pri" . "nt_" . "r"; $f($arr);
.
Genau das machen die Schlaumeierangreifer und produzieren nun munter Variationen von zusammengesetzten Funktionsnamen-Strings in den befallenen Dateien.
Um diese zu finden, muss man schon ziemlich tief in die Regular Expression Kiste greifen. Ich bleibe jetzt mal bei meinem Beispiel mit der harmlosen "print_r()" Funktion, "in echt" muss man nach den anderen Funktionsnamen suchen.
Disclaimer: Ich bin mit Regular Expressions zwar nicht gerade auf Kriegsfuss, aber alles andere als sattelfest. Sollte im Folgenden also was total krude sein, dann möge man mir das verzeihen, ich bin halt nur ein Designer/Developer Hybrid und kann von allem etwas, aber nix richtig :-))
Wie erwischt man also alle möglichen Variationen von "print_r", die nach dem Muster $xvxvxvxvx="pr"."in"."t_"."r"
oder "p"."rin"."t"."_r" oder oder gebildet werden? Meine Idee war, es auf die möglichen Buchstaben und Konkatinierungszeichen und Anführungszeichen zu beschränken. Aber der Reihe nach:
Ich suche also nach einer Zeichenkette, die mit einem "$" beginnt, von einem beliebig langen Zufallsstring gefolgt wird, der auf ein "=" triff und danach geht das Spiel mit dem zusammengesetzten String los, dessen Bestandteile von Anführungszeichen eingeschlossen sind und die mit einem Punkt "." getrennt sind. Was hinten rauskommt, ist bekannt: Der Name der Funktion. Da ich nicht weiss, welche Buchstaben der Funktion hintereinanderstehen und wann getrennt wird, ist es am einfachsten, per Gruppe auf die Buchstaben zu checken: "[print_]+"
würde "print_r" genauso finden, wie "pr" oder "in" oder "t_r". Das Pluszeichen besagt, das ein oder mehrere der Zeichen zwischen den eckigen Klammern vorkommen dürfen. Das ist nötig, damit zb "rint_r" auch gefunden wird. Nachteil ist, dass "rrrrrrrrriiiii" auch gefunden würde. Regex ist kein Ponyhof.
Nimmt man den "Konkatinierungspunkt" und die Anführungszeichen (sowohl ' als auch ") dazu, kommt man dem Ziel aber schon recht nahe: "[print_\.'\"]\+"
.
Um die Treffer noch mehr einzuengen, kombiniere ich das mit dem $ des Variablennamens, alles Mögliche dahinter (hier gibt es noch Optimierungsbedarf, anscheinend funktioniert (.*?) - non-greedy - nicht), den möglichen Leerzeichen und dem Gleichheitszeichen: "\$.*=[[:space:]]\?[print_\. '\"]\+"
.
Kombiniert man das nun mit rekursiver Suche in grep, hat man schon ein ganz gutes Tool an der Hand, um die befallenen Dateien zu finden:
grep -rn --include="*.php" "\$.*=[[:space:]]\?[preglac_\. '\"]\+" . |
Dummerweise wirft dieser Befehl aber jede Menge "false positives" aus, wahrscheinlich, weil mir ein Dan Grad in RegEx noch lange verwehrt sein wird, aber wenn man sich die Ergenisse in eine Datei leiten lässt, dann kann man diese recht schnell auf die Schadcodeabschnitte scannen. Falls also ein Regex-Grosswesir das hier liest und den Begriff noch etwa präzisieren möchte, immer her damit in die Kommentare, ich aktualisiere dann gerne hier. :-)
Noch ein Wort zum Schluss: Es ist ja ganz schön, wenn man Stellen aufspüren kann, an denen der Code lauert - richtige Sicherheit und ein 100% cleanes System gibt es aber nur, wenn man es neu aufbaut - sonst hat man immer das Risiko, dass man den Code irgendwo übersehen hat, weil er vielleicht doch noch mal ganz anders verschleiert wurde, und da es sich dabei um eine Backdoor handelt, genügt eine einzige erreichbare Datei und der Spuk kann von vorne beginnen.
Als Übung und zum Lernen ist diese Beschäftigung mit der gehackten Kiste aber echt interessant.
Unbedingt lesen: http://blog.namics.com/2012/01/a-study-in-viagra.html
Nachtrag
Weitere Suchmuster, die infizierte Dateien aufspüren konnten (teilweise sehr lose, man muss dann die Ergebnisse nach den Hackmustern scannen, deshalb habe ich sie noch durch less
geleitet):
find . -name "*.php" -print | xargs grep "eval(base64_decode(" | less find . -name "*.php" -print | xargs grep "gzinflate" | less find . -name "*.php" -print | xargs grep "eval(" | less find . -name "*.php" -print | xargs grep "\['php_code'\]" | less find . -name "*.php" -print | xargs grep "\"\^\"" | less |
Ebenfalls hilfreich, aber ziemlich aufwendig: Im Erweiterungsmanager sieht man, ob Dateien verändert wurden:
Es lohnt, sich so angemahnte Dateien genauer anzuschauen, auch wenn es meistens falscher Alarm in Hinblick auf den Schadcode ist.
Die Info findet man, wenn man die Extension im Manager anklickt und dann auf "Informationen" geht.
4 Reaktionen zu “Google Conditional Hack, Teil 2”
Waren das alles typo3-files die da kompromittiert wurden?
Falls ja, kannst Du einen frischen Tarball in ein neues Verzeichnis auspacken und mal die Unterschiede ermitteln (welche files gibts nur hier, aber nicht da / welche sind unterschiedlich).
find compromized/typo3 -type f -print0 | xargs -0 md5sum | sort -k2 > suspect.list
find fresh/typo3 -type f -print0 | xargs -0 md5sum | sort -k2 > ok.list
diff -u ok.list suspect.list
Evtl. noch auf php-files Einschränken oder so (find ver/zeich/nis -type f -name '*.php' -print0)
Wenn man Einfluss auf den Webserver nehmen kann, sollte man in jedem Fall suhosin von Stefan Esser einsetzen. Damit kann man z.B. die Nutzung von eval() komplett untersagen oder einschränken und auch loggen: http://www.hardened-php.net/suhosin/a_feature_list:eval_black_and_whitelist.html
Hi Tom,
nein, es waren php Dateien betroffen, egal wo auf dem Server. TYPO3 wäre ein geringeres Problem (mal abgesehen von lokal installierten Extensions), weil man einfach die Source austauschen und somit "frische" erhalten Dateien kann.
Suhosin ist auf jeden Fall eine gute Idee, wobei der "Trick" mit preg-replace(/.../e,...,...), auch daran vorbei käme, bzw die meisten Anwendungen ohne preg_replace() lahm gelegt wären.
ok, dann zieht das mit dem diff natürlich nicht. Außer man gräbt ein Backup aus :o)
Aber mit Suhosin würde man ja nicht preg_replace sperren, sondern eval()
Achso, die Files wurden ja über einen "nicht-php"-weg verändert. Hat' ich schon vergessen. Na gut, dann hilft das auch eher weniger.
[...] The saga continues… (siehe voriges Post) [...]
Kommentare sind geschlossen.