Təxminən bir zəiflik…

Təxminən bir zəiflik…

Bir il əvvəl, 21 mart 2019-cu il, saat səhv mükafat proqramı Mail.Ru HackerOne-a çox yaxşı biri gəldi səhv hesabatı etibarən maxarr. HTTP yönləndirməsini qaytaran veb-poçt API sorğularından birinin POST parametrinə sıfır bayt (ASCII 0) daxil edilərkən, GET parametrlərindən fraqmentlər və digər sorğuların başlıqları olan istiqamətləndirmə məlumatında işə salınmamış yaddaş parçaları görünürdü. eyni server.

Bu kritik zəiflikdir, çünki... sorğularda sessiya kukiləri də var. Bir neçə saat sonra sıfır baytı süzən müvəqqəti bir düzəliş edildi (sonradan məlum oldu ki, bu kifayət deyildi, çünki hələ də başlıqları manipulyasiya etməyə imkan verən CRLF / ASCII 13, 10 yeritmək imkanı var idi. HTTP cavabının məlumatları, bu daha az kritikdir, lakin yenə də xoşagəlməzdir). Eyni zamanda, problem səhvin səbəblərini tapmaq və aradan qaldırmaq üçün təhlükəsizlik analitikləri və tərtibatçılarına verildi.

Mail.ru poçtu çox mürəkkəb proqramdır; cavabın yaradılmasında həm açıq mənbə (bütün pulsuz proqram təminatçılarına çox təşəkkürlər), həm də daxili işlənmiş çoxlu sayda müxtəlif front-end/back-end komponentləri cəlb edilə bilər. Nginx və openresty istisna olmaqla, bütün komponentləri xaric edə bildik və zəng etməzdən əvvəl problemi lokallaşdıra bildik ngx.req.set_uri() gözlənildiyi kimi davranmayan OpenResty skriptində (ngx_http_rewrite_module-də yenidən yazma ilə GET parametrləri vasitəsilə null bayt və ya sətir lentinin daxil edilməsi, sənədlərə görə istifadə olunur və görünür, eyni şəkildə işləməlidir. işləmir). Mümkün nəticələr aradan qaldırıldı, filtrləmə mümkün qədər ciddi şəkildə əlavə edildi və bütün mümkün vektorları aradan qaldırmaq üçün filtrləmə yoxlanıldı. Ancaq yaddaş məzmununun sızmasına səbəb olan mexanizm sirr olaraq qaldı. Bir ay sonra, səhv hesabatı həll edildiyi üçün bağlandı və səhvin səbəblərinin təhlili daha yaxşı vaxtlara qədər təxirə salındı.

OpenResty nginx daxilində Lua skriptləri yazmağa imkan verən çox məşhur plagindir və o, bir neçə Mail.ru layihəsində istifadə olunur, ona görə də problem həll edilmiş hesab olunmayıb. Və bir müddət sonra əsl səbəbləri, mümkün nəticələri başa düşmək və tərtibatçılar üçün tövsiyələr vermək üçün nəhayət ona qayıtdılar. Mənbə kodunun qazılmasında iştirak etmişdir Denis Denisov и Nikolay Ermişkin. Məlum oldu ki:

  • Nginx-də, istifadəçi məlumatları ilə yenidən yazmaqdan istifadə edərkən, bəzi konfiqurasiyalarda kataloq keçidi (və yəqin ki, SSRF) imkanı var, lakin bu məlum faktdır və statik konfiqurasiya analizatorları tərəfindən aşkar edilməlidir. Nginx Gücləndirin и gixy Yandex-dən (bəli, biz də istifadə edirik, təşəkkürlər). OpenResty istifadə edərkən bu funksiyanı əldən vermək asandır, lakin bu bizim konfiqurasiyamıza təsir etmədi.

    konfiqurasiya nümunəsi:

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

    nəticə

    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
    ...

  • Yenidən yazma sətirində null bayt varsa, Nginx-də yaddaşın sızmasına səbəb olan bir səhv var. Yönləndirmə verildikdə, nginx xəttin tam uzunluğuna uyğun yeni yaddaş buferi ayırır, lakin sətri sıfır baytın xətt terminatoru olduğu bir xətt funksiyası vasitəsilə kopyalayır, buna görə də xətt yalnız sıfıra qədər kopyalanır. bayt; buferin qalan hissəsi işə salınmamış məlumatları ehtiva edir. Ətraflı təhlil tapa bilərsiniz burada.

    konfiqurasiya nümunəsi (^@ sıfır bayt)

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

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

  • Nginx GET parametrlərini xidmət simvollarının inyeksiyasından qoruyur və yenidən yazarkən yalnız GET parametrlərindən istifadə etməyə imkan verir. Buna görə də, nginx-də istifadəçi tərəfindən idarə olunan parametrlər vasitəsilə inyeksiyadan istifadə etmək mümkün deyil. POST parametrləri qorunmur. OpenResty həm GET, həm də POST parametrləri ilə işləməyə imkan verir, ona görə də OpenResty vasitəsilə POST parametrlərindən istifadə edərkən xüsusi simvolları yeritmək mümkün olur.

    konfiqurasiya nümunəsi:

    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;
    }
    

    nəticə:

    curl localhost:8337 -d "url=secret" -vv
    ...
    curl localhost:8337 -d "url=%00asdfasdfasdfasdfasdfasdfasdfasdf" -vv
    ...
    Location: http://localhost:8337/{...может содержать secret...}
    ...

Əlavə reaksiya

Problem nginx və OpenResty tərtibatçılarına bildirildi, tərtibatçılar problemi nginx-də təhlükəsizlik xətası kimi qəbul etmirlər, çünki nginx-in özündə xüsusi simvolların yeridilməsi ilə səhvdən istifadə etmək üçün heç bir yol yoxdur, düzəldin yaddaşın açıqlanması dekabrın 16-da dərc olunub. Hesabatdan keçən 4 ay ərzində OpenResty-də heç bir dəyişiklik edilməyib, baxmayaraq ki, ngx.req.set_uri() funksiyasının təhlükəsiz versiyasının lazım olduğu anlayışı var idi. 18 Mart 2020-ci ildə məlumat dərc etdik, 21 Martda OpenResty buraxıldı 1.15.8.3 versiyası, URI təsdiqini əlavə edir.

Portswigger написал yaxşı məqalə və OpenResty və Nginx-dən şərhlər götürdü (baxmayaraq ki, yaddaşın yalnız kiçik bir hissəsinin ifşa olunmasına dair şərh yanlış və yanıltıcıdır, bu, sıfır baytdan sonrakı xəttin uzunluğu ilə müəyyən edilir və açıq məhdudiyyətlər olmadıqda. uzunluğu, təcavüzkar tərəfindən idarə oluna bilər).

Bəs səhv nə idi və bunun qarşısını almaq üçün nə etmək olar?

Nginx-də səhv var idi? Bəli, belə idi, çünki yaddaşın məzmununun sızması istənilən halda səhvdir.

OpenResty-də səhv var idi? Bəli, ən azı OpenResty tərəfindən təklif olunan funksionallığın təhlükəsizliyi məsələsi araşdırılmadı və sənədləşdirilmədi.

OpenResty ilə konfiqurasiya/istifadə xətası var idi? Bəli, çünki açıq-aydın bəyanat olmadığından istifadə edilən funksionallığın təhlükəsizliyi ilə bağlı təsdiqlənməmiş bir fərziyyə irəli sürülüb.

Bu səhvlərdən hansı 10000 dollar mükafatı olan təhlükəsizlik zəifliyidir? Bizim üçün bu, ümumiyyətlə, vacib deyil. Hər hansı bir proqram təminatında, xüsusən də bir neçə komponentin kəsişməsində, xüsusən də müxtəlif layihələr və tərtibatçılar tərəfindən təmin edilənlər, heç kim heç vaxt onların işinin bütün xüsusiyyətlərinin məlum və sənədləşdirildiyinə və heç bir səhv olmadığına zəmanət verə bilməz. Buna görə də, hər hansı bir təhlükəsizlik zəifliyi təhlükəsizliyə təsir etdiyi yerdə baş verir.

Hər halda, hər hansı xarici modula/API-yə daxil olan giriş məlumatlarını mümkün qədər normallaşdırmaq və ya məhdudlaşdırmaq/filtr etmək yaxşı təcrübədir, əgər açıq göstərişlər və bunun tələb olunmadığı barədə aydın anlayış yoxdur.

Səhv

Təcrübə ilə əvvəlki məqalə, dilin saflığını qorumaq naminə:

bug mükafatı - böcəklərin ovlanması müsabiqəsi
səhv hesabatı - səhv bildirişi
yönləndirmək - yönləndirmə
açıq mənbə - açıq mənbə
errata - səhvlər üzərində işləmək

Mənbə: www.habr.com

Добавить комментарий