Finden Sie das PHP-Skript, das E-Mails sendet

9

Gibt es eine Möglichkeit für mich, das PHP-Skript zu finden, das E-Mails sendet.

Ich habe Apache + PHP (weder mod_suphp noch suexec) in einer "Standard" -Installation, und ich möchte herausfinden, welches PHP-Skript E-Mails sendet. Wenn ich die Protokolle überprüfe, sehe ich nur die UID des Benutzers, der die E-Mails sendet (in Mein Fall Apache), aber ich möchte herausfinden, aus welchem ​​Skript die E-Mail stammt.

Ist es möglich oder muss ich suexec oder mod_suphp installieren, um den Überblick zu behalten?

Danke für die Hilfe.

Adam
quelle

Antworten:

9

PHP 5.3 wurde gesteckt, um eine bessere Mail-Verfolgung zu erreichen, aber ich bin mir nicht sicher, ob das passiert ist. (edit: yes php 5.3 hat jetzt eine integrierte Protokollierung - php.ini hat die Konfigurationsvariable mail.log, die die Verwendung von Mail aus PHP-Code protokolliert.)

Wir haben das Problem gelöst, indem wir sendmail zu einem Wrapper-Shell-Skript gemacht haben.

In php.ini einen neuen Mailer einstellen. Z.B:

sendmail_path = /usr/local/bin/sendmail-php -t -i

Das sendmail-php-Skript verwendet einfach den Logger, um Informationen abzurufen, und ruft dann sendmail des Systems auf:

#!/bin/bash

logger -p mail.info -t sendmail-php "site=${HTTP_HOST}, client=${REMOTE_ADDR}, script=${SCRIPT_NAME}, filename=${SCRIPT_FILENAME}, docroot=${DOCUMENT_ROOT}, pwd=${PWD}, uid=${UID}, user=$(whoami)"

/usr/sbin/sendmail -t -i $*

Dadurch wird protokolliert, auf was Ihre mail.info in der Datei syslog.conf eingestellt ist.

Ein weiterer Vorschlag ist die Installation der Suhosin-PHP-Erweiterung, um Lücken in PHP zu schließen, es sei denn, Sie führen Debian oder Ubuntu aus, wo dies bereits die Standardeinstellung ist.

Labradort
quelle
PHP 4.x hier (habe einige alte Apps, die nicht auf PHP 5.x portiert werden können)
Adam
Kein Problem, dieser Wrapper wird den Trick machen. Es ist außerhalb von PHP. Ich erwähnte PHP 5.3 nur, weil dieses Fehlen einer Protokollierungsfunktion bis dahin behoben sein sollte. Der Wrapper funktioniert sehr gut und wir konnten ein fehlerhaftes Skript eines Benutzers identifizieren, der Spam zuließ.
Labradort
thks, ich denke, ich werde Ihren Ansatz nehmen. Vielen Dank
Adam
1
Hallo, jetzt nicht warum, aber das "script = $ {SCRIPT_NAME}, Dateiname = $ {SCRIPT_FILENAME}" gibt nichts zurück, siehe: 7 20:24:08 Gateway-Logger: sendmail-php: client =, Dateiname =, pwd = / var / www / html / mail, uid = 48, user = apache
adam
Sind Sie sicher, dass es richtig eingerichtet wurde? Wenn es in Ihrer PHP-Umgebung als vordefinierte Variable unbekannt war, sollte in der protokollierten Ausgabe auch Folgendes angezeigt werden: "script =". Überprüfen Sie sorgfältig, was Sie erneut eingerichtet haben. Sie könnten versuchen: $ _SERVER ['SCRIPT_FILENAME'] Möglicherweise können Sie weitere Variablen für die Protokollierung in der PHP-Dokumentation zu vordefinierten Variablen nachschlagen
labradort
4

Die Lösung hierfür erfordert tatsächlich einige Schritte. Die obige Lösung von labradort funktioniert nicht wirklich, da das Logger-Skript ein Bash-Skript und kein PHP ist und das Bash-Skript keinen Zugriff auf die PHP-Variablen hat, sodass die Protokolle leer sind. Grundsätzlich muss alles, was Sie protokollieren möchten, vor dem Senden der E-Mail in Umgebungsvariablen in PHP gespeichert werden, damit der Logger Zugriff auf die Daten hat. Da Sie versuchen, die Skripte anderer Benutzer zu erkennen, nicht unbedingt Ihre eigenen, haben Sie keine Kontrolle über den PHP-Code. Daher müssen Sie die Funktion auto_prepend_file von PHP verwenden, um sicherzustellen, dass alle ausgeführten PHPs Ihren Initialisierungscode vor allem anderen ausführen. Ich habe den folgenden Code über php.ini vorangestellt, um sicherzustellen, dass ich die benötigten Daten im Logger habe:

<?php
/**
 * This passes all SERVER variables to environment variables, 
 * so they can be used by called bash scripts later
 */
foreach ( $_SERVER as $k=>$v ) putenv("$k=$v");
?>

Ich habe hier ein vollständiges Tutorial zusammengestellt, wie dies funktioniert: http://mcquarrie.com.au/wordpress/2012/10/tracking-down-malicious-php-spam-scripts/

Tom McQuarrie
quelle
Das Wrapper-Skript funktionierte bei Redhat und Debian Linux bei der Implementierung von PHP-Standardeinstellungen, als es PHP 5.2 und früher war. Ich benutze heutzutage einfach mail.log = /var/log/apache-mail.log und es macht das, was ich brauche.
Labradort
1
Genau so wird der Shellshock-Bug ausgenutzt. Ich empfehle ernsthaft nicht, die Dinge so zu machen.
Ben Hitchcock
Du hast einen Punkt. Sie könnten die Variablen sicherlich über eine Bereinigungsfunktion ausführen, um schädliche Elemente wie "() {:;};" zu entfernen. Eigentlich ist es wahrscheinlich eine gute Idee, den Variablennamen auch "PHP_" voranzustellen, nur für den Fall, dass es zu einem Konflikt zwischen Umgebungsvariablennamen kommt.
Tom McQuarrie
2

Es gibt einen Patch für PHP, der anzeigt, welches Skript die E-Mails generiert, indem der gesendeten E-Mail ein Header hinzugefügt wird. Ich habe es nicht getestet, da ich nicht daran interessiert bin, Core-PHP zu patchen, aber ich habe gute Dinge gehört.

WheresAlice
quelle
1
Das klingt nach einem hervorragenden Weg. +1. Wenn Sie jedoch einen gemeinsam genutzten Host mit mehreren Clients verwalten, möchten Sie diese Clients möglicherweise über den Header informieren oder die Ausgabe stattdessen in eine Protokolldatei umleiten.
Pekka
Ja, vielleicht ist es der richtige Weg, aber ab einem bestimmten Punkt ist es ein Sicherheitsproblem. Alle Leute werden jetzt wissen, welches Skript E-Mails sendet. Schlecht erstellte Skripte laden nur dazu ein, gehackt zu werden. Weiterleitung zu einem Protokoll Vielleicht ist es besser
Adam
Schlecht erstellte Skripte sollten sich nicht in erster Linie auf dem Server befinden. Die Benutzer finden sie, wenn sie vorhanden sind (insbesondere, wenn sie Teil eines beliebten CMS-Systems sind). Aber ich verstehe, dass es vielleicht einen Fall gegen diese Lösung gibt.
WheresAlice
0

Sie müssen die Zugriffsprotokolle nach etwas durchsuchen, das dem Zeitrahmen entspricht, in dem die Nachrichten zum Spool hinzugefügt wurden.

Richard Salts
quelle
Bei der Wiedergabe besteht das Problem darin, dass es sich um ein gemeinsames Hosting handelt und für jede Domain ein dediziertes Zugriffsprotokoll.
Adam
Ja, leider müssen Sie alle durchgehen.
Richard Salts
0

Vielleicht suchen Sie einfach in Quelldateien nach "mail (" - Teilzeichenfolge?

Dmitry Trukhanov
quelle
Das ist manchmal einen Blick wert und insbesondere den Quellcode, der ihn umgibt, auf mögliche Schwachstellen für Spammer. Aber mit vielen komplizierten PHP-Skripten, die vielen Leuten auf einem gemeinsam genutzten Host gehören, ist dies nicht die Lösung für dieses Problem.
WheresAlice
In einer gemeinsam genutzten Hosting-Umgebung kann dies nicht das genaue Skript genau
bestimmen
0

Aktivieren Sie diese einfach auf Ihrer php.ini

mail.add_x_header = On
mail.log = /var/log/phpmail.log

Erstellen Sie dann diese Datei und erteilen Sie die Schreibberechtigung. Behalte es danach im Auge.

Kevin Nguyen
quelle