Hi Ken, > php_admin_value sendmail_path "/usr/sbin/sendmail -t -i -f > the-admin-username-here"
After a bit of experimenting I found this as well: php_admin_flag mail.add_x_header On It will add an "X-PHP-Originating-Script:" into the header of emails sent by PHP. Something like this: X-PHP-Originating-Script: 502:mail.php That then tells us that the email was sent by the script "mail.php" owned by the user with the ID 502. All in all that helps a little. But not much - that is for sure. Because if suPHP is off, that user might as well be "apache" and then we have to search all over the place again, as this script could be on any site. There is an unofficial PHP patch which extends the mail() function with much more detailed forced headers that you can't turn off. These headers then give us the full path to the script in question and also tell us which remote IP address called the script that generated the mail. Which is very useful. But it requires a custom built PHP. And it discloses too much information about the environment of the server to any recipient of such emails. After trying a couple of different approaches I found something that is as simple as it is elegant. And no, it wasn't my own idea. It's a slightly modified approach that Philip Iezzi initially blogged about in 2009. I comitted it to SVN, but it's not on YUM yet, as I want to give it some thorough testing before release: See: http://devel.blueonyx.it/trac/changeset/874/ What it does: Two new files are added: /usr/sausalito/configs/php/set_php_headers.php /usr/sausalito/sbin/phpsendmail The first one is a small PHP script with this in it: <?php putenv("_HTTP_HOST=".@$_SERVER["HTTP_HOST"]); putenv("_SCRIPT_NAME=".@$_SERVER["SCRIPT_NAME"]); putenv("_SCRIPT_FILENAME=".@$_SERVER["SCRIPT_FILENAME"]); putenv("_DOCUMENT_ROOT=".@$_SERVER["DOCUMENT_ROOT"]); putenv("_REMOTE_ADDR=".@$_SERVER["REMOTE_ADDR"]); putenv("_SOWNER=".@get_current_user()); ?> The second one is a simple shell script. It logs PHP mail related activity to /var/log/maillog in a format like this: Apr 19 01:35:01 5108r root: sendmail-wrapper-php: site=5108r1.smd.net, client=10.1.128.1, script=/home/.sites/28/site1/web/mailtest/mailtest/mail.php, uid=502, user=site1_admin Next the php.ini files (either /etc/php.ini or your third party PHP's php.ini file) are modified and the following three lines are added or changed: mail.add_x_header = On sendmail_path = /usr/sausalito/sbin/phpsendmail auto_prepend_file = /usr/sausalito/configs/php/set_php_headers.php This also goes into the separate php.ini's of suPHP enabled sites. Finally the following three lines are added to the Apache Vhost containers of any sites that have PHP or suPHP enabled: php_admin_flag mail.add_x_header On php_admin_value sendmail_path /usr/sausalito/sbin/phpsendmail php_admin_value auto_prepend_file /usr/sausalito/configs/php/set_php_headers.php So what does it all do? The 'auto_prepend_file' parameter will trick PHP into prepending any executed PHP script with the code from /usr/sausalito/configs/php/set_php_headers.php. We use this 'auto_prepend_file' to get some extended information about the IP accessing the script, the path to the script, the scripts name and owner. This information is stored in the protected envelope variables. When a PHP script now tries to send an email using the PHP mail() function, that function works as it normally does. The email is generated the same way as before. But instead of passing the command to send the email directly to /usr/sbin/sendmail, we take a little round about through the shell script /usr/sausalito/bin/phpsendmail, which has this code in it: -------------------------------------------------------------------------------------------------- #!/bin/sh # This is a wrapper that wraps around the PHP mail() function. # It logs some useful extra variables to /var/log/maillog. # These give us a good indication about which PHP script is # sending emails: /usr/bin/logger -p mail.info sendmail-wrapper-php: site=${_HTTP_HOST}, client=${_REMOTE_ADDR}, script=${PWD}${_SCRIPT_NAME}, uid=${UID}, user=${_SOWNER} /usr/sbin/sendmail -t -i $* -------------------------------------------------------------------------------------------------- The first thing this script does, is to log the gathered information about the PHP script into /var/log/maillog. The last thing it does is to simply pass the email on to /usr/sbin/sendmail. Last and least there is the PHP parameter 'mail.add_x_header' which we set to 'On', too. That includes a line like this in every email header that PHP's mail() function sends: X-PHP-Originating-Script: 502:mail.php The '502' in the above examle tells us that the numeric user ID of the owner of the script was '502'. After the colon we see the name (just the name - not the path!) of the offending script. In this case here 'mail.php'. Now if we have such an email in front of us and would need to find out which site and user the email really came from on our server, we would need to take a look at /var/log/maillog like this: cat /var/log/maillog|grep uid=502|grep mail.php So we grep for the numeric user ID (502 in this case) and the name of the script (mail.php) that was listed in the "X-PHP-Originating-Script:" header of said email. [root@5108r php]# cat /var/log/maillog|grep uid=502|grep mail.php client=10.1.128.1, script=/home/.sites/28/site1/web/mailtest/mailtest/mail.php, uid=502, user=site1_admin Apr 19 01:10:18 5108r root: sendmail-wrapper-php: site=5108r1.smd.net, client=10.1.128.1, script=/home/.sites/28/site1/web/mailtest/mailtest/mail.php, uid=502, user=site1_admin Apr 19 01:35:01 5108r root: sendmail-wrapper-php: site=5108r1.smd.net, client=10.1.128.1, script=/home/.sites/28/site1/web/mailtest/mailtest/mail.php, uid=502, user=site1_admin Voila! Or if we wanted to see just the log entries of all PHP related email activity, we could use this command: cat /var/log/maillog|grep sendmail-wrapper-php The nice thing here is that the email header doesn't really disclose much useful information to anyone who should rather be left in the dark. But it helps us tremendously to find any offender we're looking for in the now slightly extended logging in /var/log/maillog. The wrapper around Sendmail (/usr/sausalito/bin/phpsendmail) requires neither setuid nor any extended privileges and there is nothing in it that could be exploited. The only "nasty" part is that we now use 'auto_prepend_file' to stick our small /usr/sausalito/configs/php/set_php_headers.php in front of every executed PHP script. However, just extending the envelope variables a bit (like it does) will hardly do any harm to scripts. Unless someone has a better idea or finds a good reason why this might be a bad idea, I'll push the update out after some further testing. -- With best regards Michael Stauber _______________________________________________ Blueonyx mailing list [email protected] http://mail.blueonyx.it/mailman/listinfo/blueonyx
