طبقة الكيك وcom_weblinks Joomla. الاختراقات والإضافات روابط الويب القذرة php


لنبدأ بالنظر إلى المكونات من خلال النظر في كيفية عمل مكون Weblinks الأساسي في الجزء الإداري لموقع الويب. هذا المكون، الذي يعد نموذجيًا لهذا الجزء من موقع الويب، يشبه إلى حد كبير مكوناته الأخرى المصممة لإدارة المقالات والمستخدمين والوحدات النمطية وما إلى ذلك.

يتم سرد ملفات البرنامج لهذا المكون أدناه. كل هذه الملفات موجودة في المجلد المسؤول/المكونات/com_weblinks. طوال بقية هذا الفصل، تتم الإشارة إلى جميع أسماء ملفات مكونات Weblinks بالنسبة إلى مجلد البداية هذا ما لم تتم الإشارة إلى خلاف ذلك. يتم تنظيم معظم الملفات وفقًا لنمط MVC. على وجه التحديد، كافة ملفات العرض موجودة في المجلد الفرعي لطرق العرض، وجميع ملفات النموذج ووحدة التحكم الرئيسية موجودة في المجلدين الفرعيين للنماذج ووحدات التحكم، على التوالي. يتم استكمالها أيضًا بالتثبيت والتكوين والملفات المساعدة.

ملفات الجزء الإداري لمكون Weblinks، باستثناء ملفات Index.html

  • وحدات التحكم/weblink.php - وحدة التحكم الرئيسية لتحرير وحدة تحكم واحدة لرابط الويب
  • وحدات التحكم/weblinks.php - وحدة التحكم الرئيسية لتجميع وحدة التحكم وعرض قائمة روابط الويب على شاشة Weblinks Manager
  • helpers/weblinks.php - يوفر طرقًا مختلفة مستخدمة في وحدات التحكم وطرق العرض
  • models/fields/ordering.php - نموذج JformField يعرض عمود ترتيب رابط الويب على شاشة Weblinks Manager
  • models/forms/weblink.xml - ملف XML يستخدم في فئة Jform-Model Field لتخطيط نموذج مع حقول الإدخال وتحرير روابط الويب على الشاشة
  • models/weblink.php - نموذج لنموذج رابط الويب لنموذج شاشة واحدة
  • models/weblinks.php - نموذج لنموذج شاشة المدير نموذج روابط الويب
  • sql/install.mysql.utf8.sql - ملف SQL لإنشاء جدول روابط الويب أثناء التثبيت
  • sql/uninstall.mysql.ut8.sql - ملف SQL لإزالة جدول رابط الويب أثناء التثبيت
  • Tables/weblink.php - يوفر فئة النموذج
  • views/weblink/tmpl/edit_metadata.php - ملف تخطيط المصدر لتحرير البيانات التعريفية لرابط الويب

الجزء الإداري لمكون Weblinks

  • views/weblink/tmpl/edit_params.php - ملف تخطيط المصدر لتحرير خيارات تحديد رابط الويب الفردي
  • views/weblink/tmpl/edit.php - ملف تخطيط المصدر لتحرير رابط الويب
  • views/view.html.php - فئة العرض الرئيسية لعرض رابط ويب واحد بتنسيق HTML ملف تخطيط المصدر لمدير ارتباط الويب
  • views/weblinks/view.html.php - فئة العرض الرئيسية لعرض روابط الويب بتنسيق HTML مباشرة على شاشة Weblinks Manager
  • Access.xml - ملف XML ​​يوفر قائمة بالإجراءات لنظام قائمة التحكم في الوصول (ACL).
  • config.xml - ملف XML ​​يوفر قائمة من الخيارات لتحديد تكوين المكون
  • Controller.php - فئة وحدة التحكم الرئيسية
  • weblinks.php - نقطة الدخول للطلب
  • weblinks.xml - ملف XML يستخدم للتحكم في عملية التثبيت

كعكة الطبقات

سنتحدث عن مكون com_weblinks وترميز html لصفحة Joomla. حول كيفية إنشاء دليل الروابط على موقع Joomla بسهولة وبساطة.

تم إنشاء نظام إدارة المحتوى هذا للعمل التفاعلي مع مستخدم مسجل، دون الحاجة إلى ترميز مباشر. على الرغم من أن اتجاه تطوير Joomla يؤدي إلى التخلي عن مكون com_weblinks باعتباره عديم الفائدة تمامًا على الموقع، وإضافة وزن إضافي (أكثر من 100 كيلو بايت - 90 ملفًا) إلى نظام "ثقيل" بالفعل. لكن في الوقت الحالي لا يزال هذا المكون موجودًا في التوزيع ويستخدمه بعض المبرمجين.

إن صفحة موقع Joomla المرئية على الشاشة هي عبارة عن كعكة ذات طبقات، حيث تشارك في بنائها العديد من الكتل (وبالتالي العديد من القوالب) في وقت واحد. هذا هو المكان الذي تلعب فيه فلسفة Joomla - بناء موقع كبير الحجم. يجب أن يكون لكل كتلة قالب ترميز HTML (تخطيط) خاص بها.

الكتل الرئيسية:

قالب الصفحة الرئيسية (site_template/index.php)، والذي من خلال ترميز html الخاص به يحدد مواضع الوحدات والمكونات ويعرض هذه الوحدات والمكونات.
- قالب الصفحة
- قوالب الوحدة
- قوالب المكونات

كل من هذه الكتل الكبيرة متاحة للتحرير (التغييرات). أي أنه يمكنك تحرير قالب أي وحدة أو مكون بشكل منفصل، على سبيل المثال، وسيبدو جديدًا على الصفحة. الشيء نفسه ينطبق على قالب الصفحة.

قد يكون من الصعب على المبرمج المبتدئ أن يفهم أن السطر الأول في جزء المحتوى بالصفحة يتم عرضه كعنوان للصفحة ويتم تحريره في صفحة التحرير الخاصة بعنصر القائمة الذي يشير إلى هذه الصفحة. أن السطر الثاني مشتق من قالب مكون com_content أو com_weblinks. والسلاسل الموجودة في القوالب عادة ما تكون متغيرات سلسلة ويتم تنفيذ تهيئتها وترجمتها في ملفات اللغة، مثل language\ru-RU\ru-RU.mod_weblinks.ini وما شابه.

في بعض الأحيان يكون المبتدئ في حيرة من أمره بشأن القالب الذي أنتج هذا السطر أو ذاك، والذي يبدو على صفحة الشاشة وكأنه استمرار منطقي لنفس السرد. اتضح أن سطرًا واحدًا في قالب واحد، وآخر في القالب الثاني، وثالث في القالب الثالث. والجدول المبوب أدناه هو الناتج من قالب الوحدة النمطية mod_tabform.

في بعض الأحيان تسمى قوالب الوحدات النمطية بالتخطيطات. لكن هذه مسألة مصطلحات. الجوهر هو نفسه - إنه "الملابس" للمحتوى. سيكون من الأصح أن نقول وضع العلامات. لذا، فإن علامة صفحة شاشة واحدة موجودة في ملفات دليل Joomla المختلفة.

قائمة طعام

غالبًا ما لا يفهم العديد من مبرمجي Joomla الجدد أن عناصر القائمة يمكن أن تحتوي على أنواع مختلفة. بمعنى آخر، يمكن أن تشير عناصر القائمة إلى كائنات Joomla من أنواع مختلفة. يمكن أن تكون هذه كائنات مختلفة، مثل: المكونات (التصويت، البحث، دليل الارتباط، وما إلى ذلك).

تحديد نوع عنصر القائمة:

جهات الاتصال (com_contact)
قائمة فئات الاتصال (الفئات)
قائمة جهات الاتصال لفئة معينة (الفئة)
اتصال
جهات الاتصال المفضلة (مميزة)

المواد (com_content)
المواد الأرشيفية (أرشيفية)
المادة (المادة)
قائمة بجميع الفئات (الفئات)
فئة المدونة
قائمة فئة المواد (الفئة)
مواد مميزة
إنشاء المواد

البحث الذكي (com_search)
يبحث

مرحبا بالعالم! (com_helloworld)
رسالة (مرحبا بالعالم)

خلاصات الأخبار (com_newsfeeds)
قائمة بجميع فئات موجز الأخبار (الفئات)
قائمة خلاصات الأخبار في الفئة (الفئة)
ملف الأخبار

البحث (com_search)
نموذج البحث وقائمة نتائج البحث (بحث)

مدير المستخدم (com_users)
نموذج التفويض (تسجيل الدخول)
ملف تعريف المستخدم (ملف التعريف)
تغيير ملف تعريف المستخدم
إستمارة تسجيل
استعادة اسم المستخدم (تذكير)
تغيير كلمة المرور (إعادة تعيين)

المجمع (com_wrapper)
غلاف

كما ترون، هنا جميع أنواع القائمة هي مكونات. من خلال اسمه، يشير نوع عنصر القائمة فعليًا إلى اسم القالب الخاص بنوع المكون الخاص به. وتقع قوالب المكونات في أدلة المشاهدات:

جملة\مكونات\com_weblinks\طرق العرض\الفئات
جملة\مكونات\com_weblinks\طرق العرض\الفئة
جملة\مكونات\com_weblinks\views\weblink
جملة\مكونات\com_users\views\login

كما ترون، فإن أسماء أنواع الارتباطات في القائمة وأسماء القوالب الموجودة في أدلة vews هي نفسها.

يتمتع المطور بالقدرة على إنشاء قوالب (تخطيطات) جديدة غير قياسية للمكونات. ستنعكس هذه التخطيطات الجديدة أيضًا كأنواع قائمة جديدة في نافذة تحديد نوع القائمة. هذا موضوع منفصل.

المحتوى التجريبي لتوزيع Joomla

دعونا نرى كيف تم إنشاء التسلسل الهرمي لعناصر القائمة "حول Joomla" لعرض مكون com_weblinks في قالب Joomla للمحتوى التجريبي الافتراضي (Beez2 - الافتراضي).

دعنا نذهب إلى لوحة الإدارة لتحرير مكون com_weblinks: المكونات->الروابط. نرى أنه في المحتوى التجريبي الذي يأتي مع التوزيع، تم إنشاء خمس فئات لمكون com_weblinks. وهذا يعني أنه سيتم توزيع الروابط إلى خمس فئات. سيتم حفظ جميع الفئات التي تم إنشاؤها في جدول قاعدة البيانات #_categories. يتم أيضًا تخزين فئات المكونات الأخرى في نفس الجدول.

نموذج بيانات-روابط الويب
|-بارك لينكس
|- جملة! روابط محددة
|-|-موارد أخرى
غير مصنف

في قائمة About Joomla (في محرر القائمة)، تم إنشاء تسلسل هرمي لعناصر القائمة وفقًا لذلك:

التسلسل الهرمي لعناصر القائمة:

باستخدام جملة! (النوع: مادة)
|-استخدام الامتدادات (النوع: قائمة جميع الفئات) :: قائمة الفئات في المواد
|-|-المكونات (النوع: فئة المدونة) :: الفئة في المواد
|-|-|-مكون روابط الويب (النوع: مادة)
|-|-|-|-أرسل رابط ويب (النوع: إنشاء رابط) :: في مكون الروابط
|-|-|-|-فئة روابط الويب الفردية (النوع: قائمة الروابط في فئة ما) :: في مكون الروابط
|-|-|-|-فئات روابط الويب (النوع: قائمة فئات الروابط) :: في مكون الروابط

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

Index.php?option=com_weblinks&view=form&layout=edit

لا يمكن عرض بعض عناصر القائمة إلا للمستخدمين المسجلين! على سبيل المثال، سيكون عنصر القائمة بالنوع "إنشاء رابط" مرئيًا فقط للمستخدمين المسجلين. تم إنشاء هذه الميزة خصيصًا حتى يتمكن المستخدمون المسجلون من إنشاء روابط سيتم نشرها على الصفحة.

وبالتالي، يوفر مكون com_weblinks طريقة جيدة لملء الصفحة بشكل تفاعلي بروابط مثيرة للاهتمام. علاوة على ذلك، فإن جميع الروابط التي سيتم وضعها على هذه الصفحة لها إعادة توجيه، أي لن تتم فهرستها على أنها خارجية. ربما تكون قد شاهدت مثل هذه الروابط في المنتديات. عند تحريك مؤشر الماوس فوق هذا الرابط، سترى عنوان موقعك، وفقط بعد النقر عليه سيتم إعادة توجيهك إلى العنوان الذي حددته.

تعد قدرة المستخدم على إضافة روابط إلى مواقع خارجية هي الميزة والمعنى الرئيسي لمكون com_weblinks، وكذلك قدرة المستخدم على إضافة محتوى جديد - المقالات والصور وملفات الفيديو وما إلى ذلك.

إن السماح للمستخدم المسجل الذي يتمتع بحقوق ملء الموقع بالمحتوى دون الحاجة إلى ترميز مباشر هو الفلسفة الأساسية لـ CMS Joomla.

غير مصنف
بيانات نموذجية-مقالات
|- جملة!
|-|- الامتدادات
|-|-|- المكونات
|-|-|- الوحدات
|-|-|-|- وحدات المحتوى
|-|-|-|- وحدات المستخدم
|-|-|-|- وحدات العرض
|-|-|-|- وحدات المساعدة
|-|-|-|- وحدات الملاحة
|-|-|- القوالب
|-|-|-|- الذرية
|-|-|-|- بيز 20
|-|-|-|- بيز 5
|-|-|- اللغات
|-|-|- الإضافات
|- موقع المنتزه
|-|- مدونة بارك
|-|- معرض الصور
|-|-|- الحيوانات
|-|-|- مشهد
|- موقع محل فواكه
|-|- المزارعون
|-|- وصفات

لا يبدو أن هناك فئات كثيرة جدًا للمحتوى!
يمكنك أيضًا عرض التسلسل الهرمي للفئات في المواد باستخدام استعلام لجدول الفئات في قاعدة البيانات:

اختر * من `#_categories` حيث `الامتداد` = "com_content"

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

ثغرة PHP عند معالجة طلبات HTTP Head المختصرة

في 3 مارس، اكتشف آدم إيفانيوك ميزة مثيرة للاهتمام في مترجم PHP، والتي لا تعالج طلبات HEAD بشكل صحيح تمامًا. أطلق الباحث على هذه الثغرة الأمنية اسم "خدعة طريقة HTTP HEAD في نصوص php".

يصمم العديد من المبرمجين نصوص PHP الخاصة بهم على أمل أن يتم تنفيذ جميع التعليمات المكتوبة فيها بنجاح دون انقطاع في مكان ما في المنتصف (خاصة في النصوص القصيرة). وهذا ما يحدث إذا طلب المستخدم النهائي البرنامج النصي باستخدام أساليب GET وPOST وPUT.

ولكن يجب أن تعلم أن هناك طرق HTTP أخرى - على سبيل المثال، HEAD. عند معالجة هذه الطريقة في PHP، قد تنشأ ثغرة أمنية.

دعونا نلقي نظرة على أحد مصادر المترجم الفوري: ./main/SAPI.c، السطر 315:

إذا (SG(request_info).request_method &&
!strcmp(SG(request_info).request_method, "HEAD"))
{
SG(request_info).headers_only = 1;
...

عند وصول أي بيانات، يتم تنفيذ وظيفة php_ub_body_write. بعد ذلك، انظر إلى main/output.c، السطر 699:

إذا (SG(request_info).headers_only) (
إذا (سان جرمان (headers_sent))
{
العودة 0؛
}
php_header(TSRMLS_C);
zend_bailout();
}

هنا يمكنك أن ترى أنه في المرة الأولى التي تتم طباعتها على الشاشة وعند استخدام طريقة HEAD، تقوم وظيفة zend_bailout بكسر البرنامج النصي.

يستغل

الآن دعنا نصل إلى هذا البرنامج النصي باستخدام طريقة HEAD:

كما تتوقع، سيتوقف دفتر الزوار الخاص بنا عن التنفيذ عند السطر "echo $data;"، لذلك سيتم ببساطة إعادة تعيين ملف book.txt إلى الصفر.
هذا المثال مدمر إلى حد ما في الطبيعة. في المثال الثاني، يمكننا تجاوز التفويض في لوحة الإدارة البدائية:

في هذا البرنامج النصي، عند تسجيل الدخول باستخدام الطرق المعتادة، يتم تعيين متغير إداري في الجلسة. وبعد ذلك، إذا أدخل المستخدم كلمة مرور غير صحيحة، تتم إعادة تعيين هذا المتغير ولا يصبح المستخدم مسؤولاً.

إذا وصلنا إلى لوحة الإدارة عبر HEAD، فسيتم مقاطعة تنفيذها عند جزء التعليمات البرمجية باستخدام "echo"، وبالتالي لن تتم إعادة تعيين المتغير الإداري، ويمكننا التجول بأمان حول الجزء المغلق من التطبيق. الشيء الذي يجب أخذه في الاعتبار هنا هو أن معظم خوادم الويب لديها قيمة التخزين المؤقت للإخراج مضبوطة على 4096 بايت، لذا في مثال عملي قد نحتاج إلى السلسلة "سلسلة طويلة تحتوي على حوالي 4090 حرفًا".

يستغل
  • بي أتش بي

    هنا تحتوي مصفوفة $check على بيانات POST الخاصة بنا، والمتغير $locked عبارة عن سلسلة متسلسلة مشوشة باستخدام الدالة str_rot13()، والتي تقع تحت سيطرتنا تمامًا.

    في هذه المرحلة، من المفيد إجراء استطراد صغير لأولئك الذين لم يقرؤوا المقالات المقابلة في ] [، والتحدث بإيجاز عن الخطأ الذي يتجلى في الأساليب السحرية لـ PHP. لذلك، في PHP الإصدار 5، ظهر المفهوم الأساسي لبرمجة OOP: المنشئ والمدمر. يتم تنفيذ المنشئ باستخدام طريقة "__construct" ويتم تنفيذ المدمر باستخدام طريقة "__destruct". عند الانتهاء من عمله وعند استدعائه من خلال الدالة unserialize()، يقوم كل كائن بتنفيذ طريقة التدمير __ الخاصة به، إذا كانت مكتوبة في الكود.

    لنعد الآن إلى إطار عملنا ونلقي نظرة على أداة تدمير فئة التطبيق من الملف ./libs/configure.php:

    الدالة __تدمير()
    {
    إذا (هذا -> __ ذاكرة التخزين المؤقت)
    {
    $core = App::core("كعكة");
    unset($this->__paths);
    ذاكرة التخزين المؤقت::write("dir_map"، array_fi lter($this->__paths)،
    "cake_core");
    ذاكرة التخزين المؤقت::write("fi le_map"، array_fi lter($this->__map)،
    "cake_core");
    ذاكرة التخزين المؤقت::write("object_map"، $this->__objects،
    "cake_core");
    }
    }

    من الكود أعلاه، يمكنك أن ترى أن هذه الطريقة يمكن اختراقها عن طريق كتابة قيم عشوائية إلى كائن ذاكرة التخزين المؤقت. المفتاح الأكثر إثارة للاهتمام للكسر هو "file_map". فهو يدير الاتصالات بين الفئات وملفات PHP المقابلة، ويستخدم أيضًا لتحميل فئات إضافية أثناء تنفيذ البرنامج النصي.

    يعد الكود الفعلي لتحميل الفئات أكثر تعقيدًا بعض الشيء، ولكنه يتلخص في الكود التالي من التابع __load داخل فئة التطبيق:

    البنغو! من خلال استبدال المتغير $file، يمكننا تضمين كود PHP الخاص بنا! علاوة على ذلك، سيكون هذا خطأ حقيقيًا في تضمين الملفات عن بعد - وبالتالي، لن نحتاج إلى أي حيل إضافية لتحميل الملفات المحلية إلى الخادم. ومع ذلك، يقدم مؤلف الثغرة الأمنية التي تم العثور عليها خيار LFI لاستغلال هذه الثغرة، لأن CakePHP يستخدم ذاكرة تخزين مؤقت محلية قائمة على الملف، والتي توجد في شكل متسلسل في دليل معروف للمهاجم.

    يستغل

    باعتباره PoC صغيرًا لإنشاء سلسلة متسلسلة سامة، يقدم felix الكود التالي:

    بالطبع، يجب عليك أولاً تضمين الفئات الضرورية من CakePHP. هناك أيضًا ثغرة Python كاملة الوظائف، والتي يمكنك العثور عليها على malloc.im/burnedcake.py.

    يجب أن يعمل هذا الاستغلال في كل تطبيق مبني على CakePHP، باستخدام نماذج POST مع رموز الأمان، والتي لم يتم فيها تغيير الموقع القياسي لملفات ذاكرة التخزين المؤقت. افتراضيًا، تعرض الثغرة تكوين قاعدة البيانات، ويمكن إضافة ميزات مفيدة أخرى بسهولة عن طريق تغيير حمولة PHP المضمنة.

    الأهداف
    • CakePHP getState("fi lter_order_dir");
      $fi lter_order = JFilterInput::clean($fi lter_order, "cmd");
      $fi lter_order_dir =
      JFilterInput::clean($fi lter_order_dir, "word");
      // نحن بحاجة للحصول على قائمة للجميع
      // روابط الويب في الفئة المحددة
      $query = "SELECT *" .
      "من #__weblinks" .
      "أين كاتيد = ". (كثافة العمليات) $this->_id.
      "ونشر = 1" .
      "والمؤرشفة = 0".
      "ترتيب حسب". $fi lter_order "".
      $fi lter_order_dir .", ordering";
      إرجاع استعلام $؛
      }

      هنا يمكنك أن ترى أن المتغيرات $filter_order و $filter_order_dir لم يتم التحقق منها للتأكد من توافقها الصارم مع عبارات SQL؛ ويتم الفحص فقط باستخدام الطريقة النظيفة القياسية من فئة JFilterInput:

      نقوم بلصق هذا الكود في أي مكان بالموقع، والذي يعرض 5 روابط عشوائية من قاعدة البيانات ومرساة عشوائية. من الأفضل تخفيف المراسي بدلاً من كتابة 1 فقط على الرابط. من خلال الارتباط المناسب بموقعك على الويب، ستلاحظ على الفور زيادة في عدد الزيارات وتحسنًا في مؤشرات مواقع الويب الأخرى.

      وإنني أتطلع إلى أسئلتك في التعليقات على هذا المنصب.

      تاريخ النشر: 03 مارس 2014
        التقييمات والتعليقات:

        ديمتري :
        شكرا على السيناريو، سأقوم بتنفيذه. من المستحيل نسخ الكود المصدري من الموقع، حيث يتم نسخه فقط في أجزاء صغيرة، وسيكون أكثر ملاءمة في مجمله.

        كيريل :
        شكرًا على الملاحظة المتعلقة بالنسخ، لقد رأيتها للتو، وسأحاول إصلاحها قريبًا.

        أليكسي بافلوف:
        خطأ في السطر $tex = انفجار(":":$sendlist[$count] أنت بحاجة إلى فاصلة منقوطة، وليس نقطتين. لقد قمت بتغيير الكود قليلاً لجعله أكثر وضوحًا: