CVE-2023-25690 — إثبات مفهوم استغلال لثغرة تهريب طلبات HTTP CVE-2023-25690 في Apache mod_proxy. يتضمن بيئة معملية مع Docker، وشرح BurpSuite، وتجاوز ضوابط الوصول إلى الوكيل للوصول إلى نقاط نهاية إدارية داخلية. | Kitploit
إثبات مفهوم استغلال لثغرة تهريب طلبات HTTP CVE-2023-25690 في Apache mod_proxy. يتضمن بيئة معملية مع Docker، وشرح BurpSuite، وتجاوز ضوابط الوصول إلى الوكيل للوصول إلى نقاط نهاية إدارية داخلية.
بعض تكوينات mod_proxy على Apache HTTP Server من الإصدار 2.4.0 إلى 2.4.55 تسمح بهجوم HTTP Request Smuggling (تقنية هجوم تتدخل في عملية معالجة موقع الويب لسلاسل طلبات HTTP المستلمة من مستخدم واحد أو أكثر).
تتأثر هذه التكوينات عندما يتم تمكين mod_proxy مع بعض أشكال RewireRule أو ProxyPassMatch حيث يمكن للمهاجم عن بُعد استغلال هذه الثغرة لتجاوز تدابير التحكم في الوصول على الخادم الوكيل، وبالتالي توجيه عناوين URL غير مرغوب فيها إلى الخادم الأصلي.
تسمح هذه الثغرة للمهاجم باستهداف والوصول إلى التطبيقات الداخلية المخفية بواسطة الوكيل، مما قد يؤدي إلى وصول غير مصرح به أو تسرب بيانات أو استغلال أعمق للنظام.
تجربة CVE-2023-25690
استخدام جهاز ويندوز (Windows) كجهاز مهاجم.
يتم نشر خادم الواجهة الخلفية (backend-server) وخادم الوكيل (proxy-server) عبر Docker على جهاز Kali Linux.
هيكل ملف المختبر:
نموذج التجربة
عنوان IP لجهاز Windows 10: 192.168.1.177
عنوان IP لجهاز Kali Linux: 192.168.27.139
عنوان IP لخادم Backend-Server: 172.18.0.2
عنوان IP لخادم Proxy-Server: 172.18.0.3
عند وصول جهاز Windows 10 إلى Apache HTTP Server المستضاف على جهاز Kali على المنفذ 80، سيتم توجيه حركة المرور إلى المنفذ 80 على Proxy-Server ثم إعادة توجيهها إلى Backend-Server عبر المنفذ 8080.
متطلبات النظام
جهاز المهاجم:
نظام التشغيل Windows 10
تثبيت الأدوات: Pycharm, BurpSuite, VScode
استخدام متصفح FireFox وتثبيت إضافة FoxyProxy لتكوين الوكيل (proxy)
جهاز الضحية:
تثبيت الأدوات والخدمات: Docker, Tcpdum
تكوين Docker File (انظر قسم الملحق)
هدف الاستغلال: استغلال ثغرة HTTP Request Smuggling لتجاوز قيود الخادم الوكيل والوصول إلى الوظيفة المخفية في صفحة admin.php
نشر التجربة:
استخدام BurpSuite Community كخادم وكيل (proxy) لاعتراض الطلبات (requests) وتعديلها
في المتصفح، قم بتنزيل إضافة FoxyProxy وإضافة معلومات الوكيل:
قم بتشغيل FoxyProxy على شريط الأدوات (في قسم الإضافات بالمتصفح) وتحويل الحالة من Turn Off إلى BurpSuite Commu:
في BurpSuite، قم بتشغيل وضع الاعتراض (intercept) على on لاعتراض الحزم:
على جهاز Kali، استخدم الأمر cd للانتقال إلى مجلد المختبر (lab) الذي يحتوي على ملف docker-composer.yml وتشغيل docker composer بالأمر: docker-composer up --build
اختبار حقن CRLF:
أولاً، نرسل طلبًا (Request) يحتوي على أحرف التحكم (CRLF) إلى النظام كما يلي: HTTP/1.1\r\nFoo: baarr\r\r\n\n وتشفير عنوان URL إلى: %20HTTP/1.1%0d%0aFoo:%20baarr
=> يمكن ملاحظة أنه عند إدخال أحرف CRLF (%0d%0a)، يعالج الخادم طلبنا دون إرجاع أي خطأ أو تقييد، مما يشير إلى أنه يمكننا تمامًا إدخال أحرف CRLF.
اختبار HTTP Request Smuggling:
بعد ذلك، لدينا URI كما يلي:
/categories/1 HTTP/1.1\r\nHost: Localhost\r\n\r\nGET /SMUGGLED، وبعد تشفير عنوان URL نحصل على: /categories/1%20HTTP/1.1%0d%0aHost:%20localhost%0d%0a%0d%0aGET%20/SMUGGLED/
بعد تطبيق RewriteRule، يمكن ملاحظة أنه سيتم تحليل عنوان URL (parsing)، والطلب الذي أرسلناه بعد مروره عبر الوكيل سيتحول إلى التنسيق التالي:
يمكن ملاحظة أنه مع طلب واحد أرسلناه، يستلم الخادم ويعيد استجابتين (2 response)، الأولى لـ GET /categories والثانية لـ GET /SMUGGLED
استغلال HTTP Request Smuggling:
لنفترض أننا قمنا في ملف httpd.conf بتكوين Proxy-Server لمنع الوصول إلى صفحة /admin/
يمكننا الاستفادة من HTTP Request Smuggling لتجاوز آلية الفحص الخاصة بـ apache-proxy مع الطلب:
عند فحص السجلات (log)، نلاحظ أننا نجحنا في تجاوز apache-proxy، وتم إرسال الطلب إلى /admin بنجاح، كما قام الخادم الخلفي (backend) بإرجاع رمز الحالة 200 (status code) لـ GET /admin
لنفترض أنه يوجد في ملف admin.php دالة تنفذ أمر النظام nslookup للاستعلام إلى أي نطاق (domain) كما يلي، هدفنا هو تجاوز آلية الوكيل والوصول إلى هذه الوظيفة المخفية لإرسال استعلام DNS إلى أي نطاق، وهنا نستعلم إلى جهاز Kali الخاص بنا.
لدينا كود الاستغلال (ملف CVE-2023-25690.py) - وملف pre.txt (يحتوي على طلب التهريب (smuggled request) الذي نريد تجاوزه عبر Proxy-Server لإرساله إلى النظام، وهنا هو /admin.php)، حيث يقوم هذا الكود بإنشاء طلب تهريب (smuggling request) مع الطلب الذي نريده داخل ملف pre.txt وإرساله إلى الخادم. وفي الوقت نفسه، تسجيل نتائج الطلب والاستجابة في ملفين مناظرين هما req.txt وres.txt
في الوقت نفسه، على جهاز Kali نستخدم TCPDUMP لالتقاط حزم DNS على المنفذ 53
يمكن ملاحظة أن الطلب الذي أرسلناه قد تجاوز الوكيل بنجاح، حيث اعتبر الوكيل أن هذا طلب صالح. ولكن في backend-server، تم تحليل الطلب مع أحرف التحكم (control characters) أيضًا، لذلك من طلب واحد، قام backend-server بتحليله إلى 3 طلبات: الأول GET /categories.php?id=1، والثاني GET /admin.php?secret=192.168.1.194، والأخير GET /abc
وبذلك نجحنا في إرسال طلب إلى /admin.php، حيث كان الوكيل يمنعنا من إرسال الطلب إليه
=> عند فحص TCPDUMP نلاحظ أنه تم التقاط حزم DNS المرسلة -> تم تنفيذ الوظيفة المخفية في /admin.php بنجاح
الملحق
تكوين ملف DockerFile في مجلد Backend
يحدد ملف التكوين هذا أن جانب Backend-Server يستخدم صورة (image) PHP 7.4-apache، وهي صورة تحتوي على PHP 7.4 مع خادم الويب Apache
الأمر الثاني ينسخ جميع المحتويات من مجلد src/ إلى المجلد /var/www/html - وهذا هو المجلد الافتراضي الذي يستخدمه Apache لبناء محتوى الويب، ويُعرف هذا المجلد أيضًا باسم web root
يستخدم الأمر الثالث sed لاستبدال جميع الحقول 80 إلى 8080. وهذا يسمح بتغيير المنفذ الافتراضي لـ Apache في Backend-Server من 80 إلى 8080.
والأمر الأخير يتم تنفيذه عند تشغيل الحاوية (container)، وهو أمر يستخدم apache لتشغيل خادم الويب Apache
تكوين ملف DockerFile في مجلد Frontend
سيقوم هذا الملف بنسخ ملف httpd.conf الموجود في مجلد Frontend إلى الملف /tmp/httd.conf، وفي النهاية نقل محتوى ملف httpd.conf إلى الملف /usr/local/apache2/conf/httpd.conf
ملف httpd.conf هو ملف التكوين الرئيسي لخادم Apache HTTP، حيث يحدد هذا الملف إعدادات التكوين أو العمليات في الخادم - وهنا هو Proxy-Server
عادةً ما يتم تثبيت ملف httpd.conf في المسار /usr/local/apache2/conf/httpd.conf، ولهذا يجب علينا وضع المحتوى في المسار /usr/local/apache2/conf/httpd.conf، بينما يتم إنشاء ملف httpd.conf في مجلد Frontend لتتمكن من تكوين Apache بمرونة أكبر (دون الحاجة إلى الانتقال عبر cd إلى ذلك المسار لإعادة كتابة ملف httpd.conf)
تكوين ملف docker-compose.yml:
يتم هنا تعريف الخدمات (services) والشبكات (network) وغيرها اللازمة لتشغيل التطبيق
هنا نعلن عن خدمتين رئيسيتين هما apache-proxy وbackend-server:
Apache-Proxy: يتم بناؤه بناءً على ملف ./frontend/DockerFile والشبكة هي backend-network (bridge)، بالإضافة إلى ذلك، يتم تكوين depends_on: backend-server لتحديد أن Apache-Proxy لا يُشغَّل إلا بعد اكتمال تشغيل Backend-Server. وأخيرًا ports: "80:80" لتحديد إعادة توجيه المنفذ (port forward)، حيث سيتم توجيه حركة المرور الواصلة إلى المنفذ 80 على جهاز المضيف (host) إلى المنفذ 80 في الحاوية (container)
Backend-Server: يتم بناؤه بناءً على ملف ./backend/DockerFile مع شبكة backend-network مع Proxy ليتمكنوا من التواصل مع بعضهم البعض، ويقوم تكوين expose بفتح المنفذ 8080 ليتمكن Apache-Proxy من توجيه حركة المرور إلى Backend-Server عبر هذا المنفذ، وأخيرًا بعض ميزات الأمان مثل عدم السماح للمستخدم بإنشاء صلاحيات جديدة (إضافة أو تعديل أو حذف الملفات، أو إضافة صلاحيات للعمليات أو الشبكة، وما إلى ذلك) وتصفية استدعاءات النظام (system calls) التي ينفذها البرنامج
تكوين ملف httpd.conf
أولاً، تكوين تخزين السجلات (log) في مسارين هما /use/local/apache2/logs/error.log و /use/local/apache2/logs/access.log
بعد ذلك، تحميل الوحدات (modules) اللازمة لتطبيق قاعدة إعادة الكتابة (Rewrite Rule)
بعد ذلك، تحديد DocumentRoot وهو المعلمة في ملف تكوين Apache التي تحدد مكان وجود ملفات بيانات الخادم
ثم تطبيق قاعدة إعادة الكتابة (Rewrite Rule) للمسارات إلى /categories/ و /admin/
وأخيرًا، منع إرسال الطلبات إلى /admin/ -> والغرض من ذلك هو عمل مختبر (lab) لتجاوز الوكيل والوصول إلى هذه الصفحة