طلب HTTP المتشعب - طرق جديدة

في 7 أكتوبر 2019 ، نشر مدير الأبحاث في PortSwigger (منتج BurpSuite) دراسة حول الأساليب الجديدة لتهريب طلب HTTP. بمساعدتهم ، حصل على حوالي 70،000 دولار على bugbounty. في هذه المقالة ، اكتشفنا لفترة وجيزة جوهر الهجوم والأدوات وطرق البحث في خوادم الويب المعرضة لهذه الثغرة الأمنية.


ما هو تهريب طلب HTTP


تهريب طلب HTTP - هجوم يهدف إلى مزامنة الواجهة الأمامية لخادم الويب والخلفية لخادم الويب ، ونتيجة لذلك يمكن للمهاجم تهريب طلب HTTP بعد خادم الواجهة الأمامية. الصورة من المقال الأصلي بمثابة دليل جيد:


صورة


يمكن أن يؤدي هذا الهجوم إلى مجموعة متنوعة من النتائج - إدخال XSS في جلسة المستخدمين الآخرين ، وإعادة توجيه المستخدمين إلى موارد الطرف الثالث ، وتسمم ذاكرة التخزين المؤقت للخادم ، والتشابه مع SSRF ، وعدد آخر.


في 2019 Smuggling Incarnation لعام 2019 ، استغل James Kettle معالجة رأس خادم الويب بشكل غير صحيح


Transfer-Encoding: chunked 

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


لإجراء بحث سريع ، قام James بتطوير مكون إضافي لـ BurpSuit ، والذي يتلقى طلبًا للإدخال ويقوم بإنشاء ملاحظة حول مشكلة عدم حصانة الخدمة (إن وجدت) عند الإخراج.


أمثلة على خوادم الويب الضعيفة


يجب أن أقول أن مشكلة التهريب وغيرها من نقاط الضعف المتعلقة بتشغيل خوادم الويب قد تم التعامل معها منذ فترة طويلة من قبل باحث آخر تحت الاسم المستعار regilero . على مدار السنوات الثلاث الماضية ، نشر ثلاث مقالات تصف نقاط الضعف التي وجدها في خوادم الويب الشهيرة ، والتي تم تعيين معظمها على CVEs متوسطة وعالية الأهمية. من بين الخوادم الضعيفة خادم Apache Traffic Server و Jetty و Apsis.


في أعقاب الاهتمام بالمشكلة ، اكتشف باحث آخر ، ناثان دافيسون ، ثغرة أمنية في HAProxy ، والتي تجاهلت رأسًا تم تشكيله بشكل غير صحيح.


 Transfer-Encoding:[\x0b]chunked 

وتحويلها إلى النموذج التالي:


 Transfer-Encoding: chunked 

لكن الخادم الخلفي - gunicorn ، وكيل التطبيق على Flask ، وقراءة الرأس ، الأمر الذي أثار ثغرة أمنية.


بعد ذلك بقليل ، اكتشف عدد من الباحثين الآخرين ثغرة أمنية (تم تعيينها CVE-2019-16276) في تنفيذ golang http - خادم تطبيع الرأس إذا كان هناك مساحة قبل prelet.
الاستعلام:


صورة


بعد المعالجة بواسطة الخادم:


صورة


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


خادم الويب Caddy المكتوب في Go كان عرضة أيضًا لأنه يستخدم نفس مكتبة net / http. أكد المطورون أنه بعد تحديث GO وإعادة إنشاء الحزمة ، تختفي المشكلة.


وجد مؤلف هذه المقالة مشكلة مماثلة في خادم lighthttpd (لم يتم تعيين CVE). توضح لقطة الشاشة أن الخادم يقبل ويعالج الرأس الذي يحتوي على مسافة:


صورة


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


بشكل افتراضي ، يقوم lighttpd بتوزيع (وتطبيع) الطلبات قبل عكسها إلى الوراء. القيام بذلك يحبط الهجمات المذكورة في https://portswigger.net/research/http-desync-attacks-request-smuggling-reborn إلى خوادم المنبع من lighttpd.
ومع ذلك ، كما ذكر stbuehler أعلاه ، فإن الوكلاء المتلقين للمعلومات من lighttpd قد ينقلون أي شيء إلى lighttpd.
سيكون التغيير الذي سيتم إجراؤه في الإصدار التالي من lighttpd هو رفض الطلبات ذات المسافة أو علامة التبويب بعد اسم الحقل وقبل النقطتين ، ولكن فقط عندما يتم تكوين lighttpd في الوضع (الافتراضي) للتحليل الدقيق لرأس http.

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


الشروط الضرورية والكافية لضعف


إذن ، ما هي الشروط الضرورية لفحص مشكلة عدم الحصانة واستغلالها:


  • طلب ما بعد. على الرغم من أن RFC لا تحظر صراحة استخدام رؤوس طول المحتوى وترميز النقل لطلبات GET ، إلا أنها في الحقيقة تُستخدم فقط في طلبات POST.
  • وجود خوادم الواجهة الأمامية والخلفية - إذا لم يكن هناك أي منها ، فلن يكون هناك شيء للمزامنة.
  • يجب أن تقوم خوادم الويب بتحليل رأس ترميز النقل بطريقة مختلفة ، أي يجب على المرء "قراءته" ، ويجب تجاهل الثاني.

الاختبارات المعملية


لفهم واستكشاف الأخطاء وإصلاحها بشكل أفضل في خوادم الويب والوكلاء الحاليين ، من الحكمة نشر بيئة اختبار محليًا باستخدام Docker.


مثال على مخطط بيئة الاختبار:


صورة


رمز التطبيق:


 from flask import Flask, request, jsonify app = Flask(__name__) @app.route('/', methods=['GET', 'POST']) def main(): # the next line is required for Transfer-Encoding support in the request request.environ['wsgi.input_terminated'] = True headers = {} for header in request.headers: headers[header[0]] = header[1] print (request.data) print (headers) return jsonify(body=str(request.data), headers=headers) 

ملف مع إعدادات الواجهة الأمامية ، على سبيل المثال ، العلبة:


 localhost:80 log ../access.log proxy / host.docker.internal:8888 

ثم كل شيء بسيط ، قم بتشغيل التطبيق:


 gunicorn --keep-alive 10 -k gevent --bind 0.0.0.0:8888 -w 4 backend:app 

والحاوية:


 docker run -d -t --name caddy -p 80:80 -p 443:443 -v /Users/sun/work/caddyfile:/etc/Caddyfile abiosoft/caddy:latest 

من متجر Burp ، نقوم بتثبيت HTTP طلب Smuggler و Logger ++ لتصحيح الأخطاء. التالي في Repeater نقوم بتكوين طلب بسيط ، على سبيل المثال هذا:


 POST / HTTP/1.1 Host: localhost Content-Length: 8 Connection: close body=123 

وأرسله للتحقق من أن كل شيء تم تكوينه بشكل صحيح:


 HTTP/1.1 200 OK Content-Length: 202 Content-Type: application/json Date: Mon, 07 Oct 2019 13:17:18 GMT Server: Caddy Server: gunicorn/19.9.0 Connection: close {"body":"b'body=123'","headers":{"Accept-Encoding":"gzip","Connection":"close","Content-Length":"8","Host":"host.docker.internal:8888","User-Agent":"Go-http-client/1.1","X-Forwarded-For":"172.17.0.1"}} 

الآن قم بتشغيل Launch Smuggle Probe واطلع على الإجابات.


صورة


الأكثر إثارة للاهتمام يبدأ في هذه اللحظة. من الضروري تحليل الطلبات والردود لفهم ما إذا كانت الخدمات ضعيفة أم لا. يتم ترك هذا الجزء للقارئ فضولي.

Source: https://habr.com/ru/post/ar468489/


All Articles