قبل بضعة أيام كشف عن طريقة لتجاوز أنظمة تنفيذ التعليمات البرمجية المعزولة في Python، استنادًا إلى استخدام خطأ معروف منذ فترة طويلة ظهر في Python 2.7 ، والذي تم تحديده في عام 2012 ، ولم يتم إصلاحه بعد في Python 3.
يذكر أن يسمح الخطأ باستخدام كود بيثون مرتبط بشكل خاص لبدء مكالمة إلى الذاكرة التي تم تحريرها بالفعل (Use-After-Free) في Python. في البداية ، كان من المفترض أن الخطأ لا يمثل تهديدًا أمنيًا وفقط في حالات نادرة جدًا ، وعادة ما يتم إنشاؤه بشكل مصطنع ، يمكن أن يؤدي إلى إنهاء غير طبيعي للبرنامج النصي.
أصبح باحث أمني تحت الاسم المستعار kn32 مهتمًا بالمشكلة وتمكن من إعداد ثغرة وظيفية تجعل من الممكن استدعاء أي أمر نظام دون الوصول المباشر إلى طرق مثل os.system.
يتم تنفيذ الاستغلال في لغة Python البحتة ويعمل بدون استيراد مكتبات خارجية وبدون تثبيت برنامج التشغيل "code .__ new__". من الخطافات ، يتم استخدام "معرف ___ مدمج" فقط ، وهو أمر غير محظور بشكل عام. من الناحية العملية ، يمكن استخدام الكود المقترح لتجاوز آليات العزل في مختلف الخدمات والبيئات (على سبيل المثال ، في بيئات التعلم ، والأصداف عبر الإنترنت ، ووحدات التحكم المدمجة ، وما إلى ذلك) التي تسمح بتنفيذ كود Python ، ولكنها تحد من المتاح المكالمات وعدم السماح بطرق الوصول مثل os.system.
الكود المقترح هو تناظري لاستدعاء نظام التشغيل ، والتي تعمل من خلال استغلال ثغرة أمنية في CPython. يعمل الاستغلال مع جميع إصدارات Python 3 على أنظمة x86-64 وهو مستقر على Ubuntu 22.04 حتى مع تمكين أوضاع الأمان PIE و RELRO و CET.
العمل يتلخص في الحصول على معلومات حول عنوان إحدى الوظائف من كود Python في الكود القابل للتنفيذ CPython.
بناءً على هذا العنوان ، يتم حساب العنوان الأساسي لـ CPython في الذاكرة وعنوان وظيفة system () في مثيل libc المحمل. في النهاية ، يتم بدء الانتقال المباشر إلى نظام عنوان معين عن طريق استبدال مؤشر الوسيطة الأولى بالسلسلة "/ bin / sh".
أسهل طريقة للاستغلال هي إنشاء قائمة بطول يساوي طول المخزن المؤقت الذي تم تحريره ، والذي من المرجح أن يتم تخصيص المخزن المؤقت للعنصر الخاص به (ob_item) في نفس المكان مثل المخزن المؤقت الذي تم تحريره.
هذا يعني أننا سنحصل على "رأيين" مختلفين حول نفس القطعة من الذاكرة. تعتقد إحدى وجهات النظر ، وهي طريقة عرض الذاكرة ، أن الذاكرة هي مجرد مجموعة من البايتات ، والتي يمكننا الكتابة إليها أو القراءة منها بشكل عشوائي. وجهة النظر الثانية هي القائمة التي أنشأناها ، والتي تعتقد أن الذاكرة هي قائمة بمؤشرات PyObject. هذا يعني أنه يمكننا إنشاء رسائل بريد إلكتروني مزيفة من PyObject في مكان ما في الذاكرة ، وكتابة عناوينها إلى القائمة عن طريق الكتابة إلى memoryview ، ثم الوصول إليها عن طريق فهرسة القائمة.
في حالة PoC ، يكتبون 0 إلى المخزن المؤقت (السطر 16) ثم يصلون إليه بالطباعة (L [0]). تحصل L [0] على أول كائن * PyObject وهو 0 ، ثم تحاول الطباعة الوصول إلى بعض الحقول فيه ، مما يؤدي إلى عدم إشارة مرجعية للمؤشر.
يذكر أن هذا الخطأ موجود في جميع إصدارات python منذ python 2.7 على الأقل وعلى الرغم من أن الاستغلال مصمم للعمل على أي إصدار من Python 3 تقريبًا ، إلا أن هذا لا يعني أنه غير قابل للتكرار في Python 2 (وفقًا للمؤلف).
الغرض من الاستغلال هو استدعاء النظام ("/ bin / sh") خطواتها كالتالي:
- CPython تسرب مؤشر ثنائي الوظيفة
- حساب عنوان CPython الأساسي
- احسب عنوان النظام أو كعب PLT الخاص بك
- انتقل إلى هذا العنوان مع الإشارة إلى الوسيطة الأولى إلى / bin / sh
- فاز
أخيرًا ، يُذكر أن الاستغلال لن يكون مفيدًا في معظم التكوينات. ومع ذلك ، يمكن أن يكون مفيدًا لمترجمي Python الذين يحاولون عزل الكود أو تقييد الواردات أو استخدام خطافات التدقيق.
أخيرا إذا كنت مهتمًا بمعرفة المزيد عنها حول الملاحظة ، يمكنك الرجوع إلى المنشور الأصلي في الرابط التالي.