• Our team is looking to connect with folks who use email services provided by Plesk, or a premium service. If you'd like to be part of the discovery process and share your experiences, we invite you to complete this short screening survey. If your responses match the persona we are looking for, you'll receive a link to schedule a call at your convenience. We look forward to hearing from you!
  • The BIND DNS server has already been deprecated and removed from Plesk for Windows.
    If a Plesk for Windows server is still using BIND, the upgrade to Plesk Obsidian 18.0.70 will be unavailable until the administrator switches the DNS server to Microsoft DNS. We strongly recommend transitioning to Microsoft DNS within the next 6 weeks, before the Plesk 18.0.70 release.
  • The Horde component is removed from Plesk Installer. We recommend switching to another webmail software supported in Plesk.

PHP Email Injection

T

TDuncklee

Guest
PHP Email Injection. If your users have php email forms you are an open relay!

Ive managed to stop the hackers/spammers from using php email injection on my customers forms. http://securephp.damonkohler.com/index.php/Email_Injection
The correct way to stop this hack is for all form data to be properly validated. However, even just explaining what the issues are to some customers is impossible so I had to come up with a server wide solution. I also log all form submissions for now. Ill look through them occasionally to see if a spammer got through somehow. At the end of the code are the things I check for to flag it as spam. This is a tough one but for now it seems every message Ive looked at has multiple Subject: s so if I find that I drop the message. I also am checking for the known test email addresses the spammers are using. PLEASE, if anyone has ideas on what to look for to definitively determine if it is an email injection spam message, post them. Also, they do not change their test addressees very often in the thousands of messages Ive looked at anyway. If anyone sees a new address, post it.

Here is what I did:

Create a php script called fake_sendmail.php
Code:
#!/usr/local/psa/apache/bin/php 
<?php
// script to filter email generated from php mail() function.
// Used to block spammers from abusing the function as described here:
// [url]http://securephp.damonkohler.com/index.php/Email_Injection[/url]
// modify php.ini
//         sendmail_path = /path/to/fake_sendmail.php -t -i
// If message does not pass the message_chk function we just
// drop the message on the floor.

$size_of_mbox = 10; // Approx max size (in Meg) of logged messages
$sendmail="/usr/local/psa/qmail/bin/sendmail";  // the real sendmail program
$args = "";

for( $i=1; $i <= $argc; $i++ ){
     $args .= $argv[$i]." ";
}
$fd = fopen("php://stdin", "r");
$email = "";
while (!feof($fd)) {
    $email .= fread($fd, 1024);
}
fclose($fd);


$lines = explode("\n", $email);

$from = "";
$subject = "";
$headers = "";
$message = "";
$splittingheaders = true;

for ($i=0; $i<count($lines); $i++) {
    if ($splittingheaders) {    // this is a header until we find empty line
        if (trim($lines[$i])!="") {
            $headers .= $lines[$i]."\n";
        }  // look out for special headers
        if (preg_match("/^Subject: (.*)/", $lines[$i], $matches)) {    
            $subject = $matches[1];
        }
        if (preg_match("/^From: (.*)/", $lines[$i], $matches)) {
            $from = $matches[1];
        }
    } else { // not a header, but message
        $message .= $lines[$i]."\n";
    }
    
    if (trim($lines[$i])=="") { // empty line, header section has ended
        $splittingheaders = false;
    }
}

$chk_result = message_chk( $headers, $message );
if( file_exists( "/usr/mailarchive_php/php_mail_log" ) ){
    if( (filesize( "/usr/mailarchive_php/php_mail_log" )/1024/1000) > $size_of_mbox ){
        rename( "/usr/mailarchive_php/php_mail_log", 
                     "/usr/mailarchive_php/php_mail_log.".date( "y_m_d_H_i_s" ) );
    }
}
$archive_fp = fopen ("/usr/mailarchive_php/php_mail_log", "a");
fwrite( $archive_fp, "*******\n" );
if( $chk_result ){
    fwrite( $archive_fp, "******* Block Rule: ".$chk_result . "\n");
}
fwrite( $archive_fp, "Custom-Info2: Sent with php\n\n" . $headers.$message );
fclose( $archive_fp );
if( !$chk_result ){
    $fps = popen( $sendmail . " " . $args, "w" );
    // Doing this so I can identify all PHP created messages.
    fwrite( $fps,  $headers . "Custom-Info2: Sent with php\n\n" . $message ); 
    pclose( $fps );
}


function message_chk( $headers, $message ){

    if( substr_count ( $headers, "Subject: " ) > 1 ){    return "Multiple Subject:'s";    }
    else if (eregi( "beacon5919@aol.com", $message.$headers ) ) 
            { return "beacon5919@aol.com"; }
    else if (eregi( "batts1005@aol.com", $to.$subject.$message.$headers ) ) 
            { return "batts1005@aol.com"; }
    else if (eregi( "charleslegbe@aol.com", $to.$subject.$message.$headers ) ) 
            { return "charleslegbe@aol.com"; }
    else if (eregi( "charleselegb@aol.com", $to.$subject.$message.$headers ) ) 
            { return "charleslegbe@aol.com"; }
    else if (eregi( "charleselegbed@aol.com", $to.$subject.$message.$headers ) ) 
            { return "charleselegbed@aol.com"; }
    else if (eregi( "caitl57421@aol.com", $to.$subject.$message.$headers ) ) 
            { return "caitl57421@aol.com"; }
    else if (eregi( "michaelhorowitzzzz@SoftHome.net", $to.$subject.$message.$headers ) ) 
            { return "michaelhorowitzzzz@SoftHome.net"; }
}

?>
Create /usr/mailarchive_php/ and make it rwx by apache only. This is where I chose to log messages for now.

In /usr/local/psa/apache/conf/php.ini add
sendmail_path = /path/to/fake_sendmail.php -t -i

Restart apache
 
Hey TDuncklee,
Just wondering how this is working for you? Any thoughts / experiences you'd like to share. I'm looking for something of this nature as well.

Best Regards,
Matt Simpson
 
Only change so far is the "Custom-Info2: " header entry is not valid according the the RFC. Needs to be "X-Custom-Info2: "

I also started a From: address validation routine but have not finished it. So far the multiple subject check has stopped all the junk from getting out but the hackers will get wise to it someday...
 
Does anyone know how to add extra headers to all out going email on a plesk server?

For the same reason as you two have for detecting spam, I want to add a x-report-spam header to all out going emails so that people can report spam to us to help us find invaded forms on our server.

Also, in my filtering, I do the same as you do with the "if spam, then die" but I also add tracking to capture their IP and I have any attempts report to a security address so that I get the attempts forwarded to me. i have one guy trying two full days now to get back in but my scripts does nothing but die when I detect attack and so he hasn't caught wind that I'm wasting his time.

I search for the setting of mime instructions like boundry and bit type because those things are not usually done in the script but occur after the mail function run.

please help someone on the server wide x-header idea.

Barry L. Salter
+1.602.413.6197
 
New test addresses

New addresses appearing in my log using the filter


alex@healthcareserious.com
charieses329@aol.com
charleses3229@aol.com
charleses3299@aol.com
dennis@lifeserious.com
ken@hospitalserious.com
 
Back
Top