Individuare gli script PHP che inviano SPAM

Introduzione

Quando un sito in PHP viene viene utilizzato per inviare tonnellate di email di SPAM tramite una qualche vulnerabilità nel codice, la prima cosa che si deve affrontare, oltre alla pulizia della coda di postfix, è l’individuazione dello script PHP responsabile.
Le cose si fanno più difficili quando sul nostro server sono presenti decine di Virtual Host, poichè il file colpevole dell’invio di spam diventa difficilmente identificabile.
Possiamo però modificare il comportamento di default di PHP per l'invio di email, istruendolo a tenere traccia di tutti gli invii effettuati in un file di log, che potremo poi consultare alla ricerca dello script colpevole.

Configurazione di PHP

Creiamo un nuovo file contenente le istruzioni personalizzate:

# nano /usr/local/bin/sendmail-php

con contenuto:

#!/bin/sh
# Logging sendmail wrapper

SENDMAIL="/usr/sbin/sendmail"
LOGFILE="/var/log/mail_php.log"

DT=`date "+%Y-%m-%d %H:%M:%S"`
DTFN=`date "+%Y%m%d-%H%M%S"`
TMPFP=`tempfile --prefix=lsm_`

cat | tee "$TMPFP" | $SENDMAIL $*
RETVAL=$?

TO=`grep "To:" <"$TMPFP"`
rm -f "$TMPFP"

echo "$DT: $PWD sends e-mail $TO" >>$LOGFILE

exit $RETVAL

Rendiamo eseguibile lo script appena creato:

# chmod +x /usr/local/bin/sendmail-php

Creiamo il file di log e rendiamolo scrivibile:

# touch /var/log/mail_php.log
# chown root:adm /var/log/mail_php.log
# chmod 662 /var/log/mail_php.log

Ora istruiamo PHP a fare uso del nuovo script:

# nano /etc/php5/apache2/php.ini

modificando le istruzioni:

[mail function]
; For Win32 only.
SMTP = localhost
smtp_port = 25

; For Win32 only.
;sendmail_from = me@example.com

; For Unix only.  You may supply arguments as well (default: "sendmail -t -i").
;sendmail_path =

in

[mail function]
; For Win32 only.
;SMTP = localhost
;smtp_port = 25

; For Win32 only.
;sendmail_from = me@example.com

; For Unix only.  You may supply arguments as well (default: "sendmail -t -i").
sendmail_path = /usr/local/bin/sendmail-php

Se usate PHP come CGI, con SUPHP o FCGI, modificate alla stessa maniera anche il file /etc/php5/cgi/php.ini.

Aggiungiamo una configurazione per Logrotate, in modo da non trovarci il server intasato di log:

# nano /etc/logrotate.d/sendmail-php

di contenuto:

/var/log/sendmail.log {
    weekly
    rotate 4
    compress
    delaycompress
    missingok
    create 662 root adm
}


Riavviamo Apache per fargli digerire le modifiche:

# /etc/init.d/apache2 restart

Test della configurazione

Per verificare che tutto funzioni correttamente, creiamo un file di test nella root di Apache:

# nano /var/www/testphpmail.php

di contenuto:

<?php
mail('yourname@yourdomain.com','This is a test message subject','This is a test message body');
echo 'Mail sent.'; 
?>

Richiamiamolo in un browser:

http://ip.del.nostro.server/testphpmail.php

e verifichiamo nei log che l'invio sia stato tracciato correttamente:

# cat /var/log/mail_php.log
2014-03-12 09:24:29: /var/www sends e-mail To: yourname@yourdomain.com
2014-03-12 09:24:31: /var/www sends e-mail To: yourname@yourdomain.com
2014-03-12 09:25:50: /var/www sends e-mail To: yourname@yourdomain.com