حول ثغرة واحدة في ...



منذ عام واحد ، 21 مارس 2019 ، في برنامج مكافأة الخطأ Mail.ru على HackerOne جاء تقرير خطأ جيد جدًا من maxarr . عند تضمين صفر بايت (ASCII 0) في معلمة POST لأحد طلبات واجهة برمجة تطبيقات بريد الويب التي أعادت إعادة توجيه HTTP ، شوهدت أجزاء من الذاكرة غير المهيأة في بيانات إعادة التوجيه ، حيث توجد أجزاء من معلمات GET ورؤوس الطلبات الأخرى إلى نفس الخادم.

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

Mail.ru هو تطبيق معقد للغاية ، يمكن لعدد كبير من المكونات الأمامية / الخلفية المختلفة المختلفة ، سواء مفتوحة المصدر (بفضل الكثير من مطوري البرمجيات المجانية) وتطويرنا الخاص ، المشاركة في الاستجابة. كان من الممكن استبعاد جميع المكونات باستثناء nginx و openresty وتوطين المشكلة قبل استدعاء ngx.req.set_uri ()في برنامج OpenResty النصي ، الذي لم يتصرف كما هو متوقع (قم بتثبيت صفر بايت أو تغذية سطر من خلال معلمات GET من إعادة الكتابة إلى ngx_http_rewrite_module ، والتي ، وفقًا للوثائق ، يتم استخدامها ، ويبدو أنها يجب أن تعمل بنفس الطريقة تمامًا). تم القضاء على العواقب المحتملة ، وأضيف الترشيح الأكثر صرامة ، وتم التحقق من أن الترشيح يلغي جميع المتجهات المحتملة. لكن الآلية التي أدت إلى تسرب محتويات الذاكرة ظلت غامضة. بعد شهر ، تم إغلاق تقرير الخطأ كما هو مصرح به ، وتم تأجيل تحليل أسباب الخطأ حتى أوقات أفضل.

OpenResty هو مكون إضافي شائع جدًا يسمح لك بكتابة نصوص Lua داخل nginx ، ويتم استخدامه في العديد من مشاريع Mail.ru ، لذلك لم يتم اعتبار المشكلة محلولة. وبعد مرور بعض الوقت ، عادوا إليها لفهم الأسباب الحقيقية والعواقب المحتملة وتقديم توصيات للمطورين. تم حفرها شفرة المصدر من قبل دينيس دينيسوف و نيكولاي Ermishkin . اتضح أن:

  • nginx rewrite directory traversal ( SSRF) , , Nginx Amplify Gixy (, , ). OpenResty , .

    :

    location ~ /rewrite {
        rewrite ^.*$ $arg_x;
    }
    
    location / {
        root html;
        index index.html index.htm;
    }




    curl localhost:8337/rewrite?x=/../../../../../../../etc/passwd
    root:x:0:0:root:/root:/bin/bash
    daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
    bin:x:2:2:bin:/bin:/usr/sbin/nologin
    ...


  • nginx , , rewrite . nginx , , , , , . .

    (^@ )
    
    location ~ /memleak {
        rewrite ^.*$ "^@asdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdasdf";
    }
    
    location / {
        root html;
        index index.html index.htm;
    }



    curl localhost:8337/secret -vv
    ...
    curl localhost:8337/memleak -vv
    ...
    Location: http://localhost:8337/secret
    ...

  • Nginx GET- rewrite GET-. nginx . POST . OpenResty GET POST , POST OpenResty .

    :

    location ~ /memleak {
        rewrite_by_lua_block {
            ngx.req.read_body();
            local args, err = ngx.req.get_post_args();
            ngx.req.set_uri( args["url"], true );
        }
    }
    
    location / {
        root html;
        index index.html index.htm;
    }
    


    :

    curl localhost:8337 -d "url=secret" -vv
    ...
    curl localhost:8337 -d "url=%00asdfasdfasdfasdfasdfasdfasdfasdf" -vv
    ...
    Location: http://localhost:8337/{... secret...}
    ...



تم الإبلاغ عن المشكلة لمطوري nginx و OpenResty ، لا يعتبر المطورون المشكلة على أنها خطأ أمان في nginx ، لأن في nginx نفسها ، لا توجد طريقة لاستغلال الخطأ من خلال إدخال أحرف خاصة ، وقد تم نشر الإصلاح الخاص بكشف محتويات الذاكرة في 16 ديسمبر. في الأشهر الأربعة منذ التقرير ، لم يتم إجراء أي تغييرات على OpenResty ، على الرغم من وجود فهم بأن هناك حاجة إلى نسخة آمنة من دالة ngx.req.set_uri (). في 18 مارس 2020 ، نشرنا المعلومات ؛ في 21 مارس ، أصدر OpenResty الإصدار 1.15.8.3 ، والذي يضيف فحص URI. كتب

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

إذن ما هو الخطأ وماذا تفعل لمنعه؟


هل كان هناك خطأ في nginx؟ نعم ، كان ذلك ، لأن تسرب الذاكرة خطأ على أي حال.

هل كان هناك خطأ في OpenResty؟ نعم ، على الأقل لم يتم التحقيق في مسألة أمان الوظائف التي تقدمها OpenResty وتوثيقها.

هل حدث خطأ في تكوين / استخدام OpenResty؟ نعم ، لأنه في حالة عدم وجود إشارة صريحة ، تم عمل افتراض غير مؤكد حول سلامة الوظيفة المستخدمة.

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

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

Errata


وفقًا لتجربة المقالة السابقة ، من أجل الحفاظ على نقاء اللغة:

مكافأة الخطأ - مسابقة الصيد
لتقرير الأخطاء -
إعادة توجيه إخطار الخطأ - إعادة توجيه
openorsny - مصدر مفتوح
يعرف بالخطأ - العمل على الأخطاء

All Articles