
Mautic < 5.2.3 ثغرة تنفيذ أكواد عن بُعد بعد المصادقة
يعمل التعقيم السيئ لمحتوى الملف المرفوع ونوعه وامتداده في ميزة تحرير الأصول (Asset Edition) على تمكين مهاجم مصادق من كتابة كود PHP تعسفي داخل دليل الويب وتحديد مكان كتابة هذا الملف. يؤدي هذا إلى تنفيذ تعليمات برمجية عن بُعد.
كما تتيح ثغرة اجتياز المسار (path traversal) استغلال هذه الوظيفة لحذف أي دليل على نظام الملفات بشكل متكرر يملك مستخدم الويب صلاحية تعديله.

عند تحرير أحد الأصول عبر المسار /assets/view/{assetID}، تتاح إمكانية تغيير ملف الأصل.
يؤدي رفع ملف جديد في النهاية إلى استدعاء الدالة التالية داخل app/Bundles/AssetBundle/Controller/AssetController.php:
public function editAction(Request $request, UploaderHelper $uploaderHelper, AssetModel $model, $objectId, $ignorePost = false)
يمكن العثور على منطق الرفع هنا:
if (!$ignorePost && 'POST' == $method) {
$valid = false;
if (!$cancelled = $this->isFormCancelled($form)) {
if ($valid = $this->isFormValid($form)) {
$entity->setUploadDir($this->coreParametersHelper->get('upload_dir'));
$entity->preUpload();
$entity->upload();
بشكل أكثر تحديدًا، نحن مهتمون بالطريقتين preUpload() و upload()، حيث تتعاملان مع كتابة الملف الفعلية على القرص.
يقع الخلل الأول في preUpload() في app/Bundles/AssetBundle/Entity/Asset.php، حيث يسمح لنا التنفيذ بتحديد امتداد ملف تعسفي (وبالتالي تجاوز الحماية التي توفرها عادةً مصفوفة allowed_extensions):
$filename = sha1(uniqid(mt_rand(), true));
$extension = $this->getFile()->guessExtension();
if (empty($extension)) {
// get it from the original name
$extension = pathinfo($this->originalFileName, PATHINFO_EXTENSION);
}
$this->path = $filename.'.'.$extension;
سيُرجع السطر $extension = $this->getFile()->guessExtension(); قيمة NULL إذا قدمنا اسم ملف ينتهي بـ .php ومحتوى يبدأ بوسم <?php.
سيعطي فحص empty($extension) قيمة true بعد ذلك، وسيتم استخراج امتداد الملف عبر استدعاء pathinfo()، مما يسمح لنا برفع ملفات مؤقتة بمحتوى وامتداد تعسفيين. لا يمكننا التحكم بالاسم الفعلي للملف لأنه يتم إنشاؤه باستخدام sha1().
بعد ذلك، داخل الطريقة اللاحقة upload()، سيتم كتابة الملف فعليًا على القرص داخل دليل الويب من خلال الاستدعاء التالي:
$this->getFile()->move($this->getUploadDir(), $this->path);
إنه يستخدم امتدادنا التعسفي (الموجود في متغير $this->path). يمكن بعد ذلك استرجاع اسم الملف عن طريق تحديث صفحة تفاصيل الأصل (/assets/view/{assetId})، تحت إدخال الجدول Local filename.
ملاحظة: يعمل هذا أيضًا عن طريق تغيير الطلبات المرسلة عند إنشاء أصل جديد. سيؤدي هذا إلى استدعاء الدالة newAction()، لكن المنطق مطابق، وما تزال العيوب قائمة في الطريقتين preUpload() و upload().
لن يُنشر إثبات المفهوم إلا بعد حوالي شهر أو أكثر.
يُمنح هذا الوقت للمؤسسات التي تعتمد على هذا البرنامج لتحديثه دون خوف من قيام هواة الاختراق بتخريب أنظمتها.
بعد ذلك، سيتم تحديث هذا المستودع ببرنامج الاستغلال الكامل والإثباتات. توجد بالفعل معلومات كافية في هذه الصفحة على أي حال.
عند التحقق من رفع مؤقت (عبر /s/assets/new أو /s/assets/edit/{assetId})، يتم حذف الدليل الذي يخزن الملف المؤقت بشكل متكرر في نهاية الطلب. المعامل المسؤول عن الاحتفاظ باسم الدليل المؤقت معرض لهجمات اجتياز المسار، مما يسمح لمهاجم مصادق بحذف أي دليل على النظام، بشرط أن يكون لدى مستخدم الويب صلاحية القيام بذلك. يمكن أن يؤدي هذا إلى فقدان البيانات، أو حتى تدمير نظام الملفات بالكامل إذا صادف أن الخادم يعمل كمستخدم جذر.
حدد أي ملف موجود على النظام من خلال نقطة النهاية المستخدمة أدناه. إذا كان الملف موجودًا، سيحاول الخادم حذف الدليل الذي يتم تخزينه فيه.

الاستيلاء على الخادم حرمان الخدمة فقدان البيانات