Find the php script thats sending mails

Solution 1:

php 5.3 was slotted to get better mail tracing, but I'm not sure if that happened. (edit: yes php 5.3 has logging built in now - php.ini has the config variable mail.log which will log use of mail from php code.)

We solved the problem by making sendmail a wrapper shell script.

In php.ini set a new mailer. E.g.:

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

The sendmail-php script simply uses logger to get info, and then calls the system's sendmail:

#!/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 $*

This will log to whatever your mail.info is set to in the syslog.conf file.

Another suggestion is to install suhosin php extension to tighten up loopholes in PHP, unless you are running Debian or Ubuntu where this is already the default.

Solution 2:

The solution to this actually requires a few steps. labradort's solution above doesn't actually work since the logger script is a bash script, not php, and the bash script has no access to php's variables, so the logs come out blank. Basically whatever you want to log needs to be saved to environment variables in php prior to sending the email so the logger has access to the data. Since you're trying to detect other user's scripts, not necessarily your own, you have no control over the php code, so you need to use PHP's auto_prepend_file feature to ensure that all executed php runs your initialisation code before everything else. I prepended the following code via php.ini to ensure I have the data I need in the logger:

<?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");
?>

I put together a full tutorial on how to get this working here: http://mcquarrie.com.au/wordpress/2012/10/tracking-down-malicious-php-spam-scripts/

Solution 3:

There is a patch for PHP that will show which script is generating the emails by adding a header to the email being sent. I haven't tested it since I'm not keen on patching core PHP, but I've heard good things.