ثغرة أمنية في OpenSMTPD تسمح بتنفيذ تعليمات برمجية عن بعد بامتيازات الجذر

في خادم البريد الذي تم تطويره بواسطة مشروع OpenBSD أوبنسمتبد المحددة ضعف حرج (CVE-2020-7247)، والذي يسمح لك بتنفيذ أوامر shell عن بعد على الخادم مع حقوق المستخدم الجذر. تم التعرف على الثغرة الأمنية أثناء عملية إعادة التدقيق التي أجرتها شركة Qualys Security (تدقيق OpenSMTPD السابق عقدت في عام 2015، وكانت الثغرة الأمنية الجديدة موجودة منذ مايو 2018). مشكلة مستبعد في إصدار OpenSMTPD 6.6.2. يُنصح جميع المستخدمين بتثبيت التحديث على الفور (بالنسبة لـ OpenBSD، يمكن تثبيت التصحيح عبر syspatch).

تم اقتراح خيارين للهجوم. يعمل الخيار الأول في تكوين OpenSMTPD الافتراضي (يقبل الطلبات من المضيف المحلي فقط) ويسمح لك باستغلال المشكلة محليًا، عندما يكون المهاجم قادرًا على الوصول إلى واجهة الشبكة المحلية (الاسترجاع) على الخادم (على سبيل المثال، على أنظمة الاستضافة) . يحدث الخيار الثاني عندما يتم تكوين OpenSMTPD لتلقي طلبات الشبكة الخارجية (خادم بريد يقبل بريد الطرف الثالث). لقد أعد الباحثون نموذجًا أوليًا للبرمجية المستغلة التي تعمل بنجاح مع كل من إصدار OpenSMTPD المضمن في OpenBSD 6.6 ومع الإصدار المحمول لأنظمة التشغيل الأخرى (تم إجراؤه في اختبار دبيان).

سبب المشكلة هو خطأ في الدالة smtp_mailaddr() التي يتم استدعاؤها للتحقق من صحة القيم في حقلي "MAIL FROM" و"RCPT TO" اللذين يحددان المرسل/المستلم ويتم تمريرهما أثناء الاتصال مع خادم البريد. للتحقق من جزء عنوان البريد الإلكتروني الذي يأتي قبل الرمز "@"، يتم استدعاء الدالة smtp_mailaddr()
valid_localpart()، الذي يقبل (MAILADDR_ALLOWED) الأحرف "!#$%&'*/?^`{|}~+-=_"، كما هو مطلوب بواسطة RFC 5322.

في هذه الحالة، يتم تنفيذ الهروب المباشر من السلسلة في الدالة mda_expand_token()، والتي تحل محل الأحرف "!#$%&'*?`{|}~" فقط (MAILADDR_ESCAPE). بعد ذلك، يتم استخدام السطر المجهز في mda_expand_token() عند استدعاء وكيل التسليم (MDA) باستخدام الأمر 'execle("/bin/sh"، "/bin/sh"، "-c"، mda_command،...' في حالة وضع الحروف على mbox عبر /bin/sh، يتم إطلاق السطر "/usr/libexec/mail.local -f %%{mbox.from} %%{user.username}" حيث القيمة "% يتضمن {mbox.from}" البيانات التي تم تجاوزها من المعلمة "MAIL FROM".

جوهر الثغرة الأمنية هو أن smtp_mailaddr() به خطأ منطقي، ونتيجة لذلك، إذا تم إرسال مجال فارغ إلى البريد الإلكتروني، فإن الوظيفة ترجع رمز التحقق الناجح، حتى لو كان جزء العنوان قبل "@" يحتوي على أحرف غير صالحة . علاوة على ذلك، عند إعداد سلسلة، لا تفلت الدالة mda_expand_token() من جميع أحرف الصدفة الخاصة المحتملة، ولكن فقط الأحرف الخاصة المسموح بها في عنوان البريد الإلكتروني. وبالتالي، لتشغيل الأمر الخاص بك، يكفي استخدام الرمز "؛" في الجزء المحلي من البريد الإلكتروني. والمساحة، والتي لم يتم تضمينها في مجموعة MAILADDR_ESCAPE ولم يتم الهروب منها. على سبيل المثال:

127.0.0.1 25 دولارًا أمريكيًا

مرحبا أستاذ فالكين
بريد من:
RCPT إلى:
بيانات
.
تقلع

بعد هذه الجلسة، سيقوم OpenSMTPD، عند تسليمه إلى mbox، بتشغيل الأمر عبر الصدفة

/usr/libexec/mail.local -f ;sleep 66; جذر

وفي الوقت نفسه، فإن احتمالات الهجوم محدودة بسبب حقيقة أن الجزء المحلي من العنوان لا يمكن أن يتجاوز 64 حرفًا، ويتم استبدال الأحرف الخاصة "$" و"|" بـ ":" عند الهروب. لتجاوز هذا القيد، نستخدم حقيقة أن نص الرسالة يتم إرساله بعد تشغيل /usr/libexec/mail.local من خلال دفق الإدخال، أي. من خلال معالجة العنوان، يمكنك فقط تشغيل مترجم أوامر sh واستخدام نص الرسالة كمجموعة من التعليمات. نظرًا لأنه تمت الإشارة إلى رؤوس خدمة SMTP في بداية الرسالة، فمن المقترح استخدام أمر القراءة في حلقة لتخطيها. يبدو استغلال العمل كما يلي:

192.168.56.143 25 دولارًا أمريكيًا

مرحبا أستاذ فالكين
بريد من:
RCPT إلى:[البريد الإلكتروني محمي]>
بيانات
#0
#1
...
#d
لأني في W O P R؛ يفعل
echo -n "($i)" && id || استراحة
تم > /root/x."`id -u`.""$$"
.
تقلع

المصدر: opennet.ru

إضافة تعليق