Om en sÄrbarhet i


Om en sÄrbarhet i


För ett Är sedan, den 21 mars 2019, i bug bounty-programmet Mail.Ru pÄ HackerOne kom en mycket bra bugrapport frÄn maxarr. Vid införandet av en noll-byte (ASCII 0) i POST-parametern för en av API-förfrÄgningarna till webbmailen, som returnerade en HTTP-redirect, syntes bitar av icke-initierat minne i redirect-datan, dÀr det oftast förekom fragment frÄn GET-parametrar och rubriker frÄn andra förfrÄgningar till samma server.

Detta Àr en kritisk sÄrbarhet, eftersom förfrÄgningarna ocksÄ innehÄller sessionscookies. Inom nÄgra timmar gjordes en tillfÀllig fix som filtrerade nollbytet (som senare visade sig vara otillrÀckligt, eftersom möjligheten till CRLF-injektion / ASCII 13, 10 kvarstod, vilket möjliggör manipulation av rubriker och HTTP-svar, vilket Àr mindre kritiskt, men fortfarande otrevligt). Samtidigt överlÀmnades problemet till sÀkerhetsanalytiker och utvecklare för att identifiera och ÄtgÀrda orsakerna till buggen.

Mail.ru Àr en mycket komplex applikation, i formandet av svaret kan ett stort antal olika frontend/backend-komponenter delta, bÄde öppen kÀllkod (ett stort tack till alla utvecklare av fri programvara), och egna utvecklingar. Det lyckades utesluta alla komponenter utom nginx och openresty och lokalisera problemet till anropet ngx.req.set_uri() i OpenResty-skriptet, som inte upptrÀdde som förvÀntat (att införa noll-byte eller radbrytningar via GET-parametrar med rewrite i ngx_http_rewrite_module, som enligt dokumentationen anvÀnds och som borde fungera exakt som det skulle Àr inte möjligt). Eventuella konsekvenser ÄtgÀrdades, strikt filtrering infördes och det kontrollerades att filtreringen eliminerade alla möjliga vektorer. Men mekanismen som ledde till lÀckage av minnesinnehÄll förblev en gÄta. En mÄnad senare stÀngdes buggrapporten som löst, och analysen av orsakerna till buggen sköts upp till en senare tid.

OpenResty Àr en mycket populÀr plugin som gör det möjligt att skriva Lua-skript inuti nginx, och den anvÀnds i flera projekt av Mail.ru, sÄ problemet ansÄgs inte löst. Och efter en tid ÄtervÀnde man till det för att förstÄ de verkliga orsakerna, möjliga konsekvenser och formulera rekommendationer för utvecklarna. I granskningen av kÀllkoden deltog Denis Denisov och Nikolai ErmishkinDet visade sig att:

  • I nginx finns det en möjlighetsbegripning för katalogtraversering (och troligtvis SSRF) i vissa konfigurationer nĂ€r man anvĂ€nder rewrite med anvĂ€ndardata, men detta Ă€r en kĂ€nd lösning, och den bör upptĂ€ckas av statiska analysatorer av konfigurationer i Nginx Amplify och Gixy frĂ„n Yandex (ja, vi anvĂ€nder det ocksĂ„, tack). NĂ€r man anvĂ€nder OpenResty Ă€r det lĂ€tt att missa denna möjlighet, men vĂ„r konfiguration pĂ„verkades inte.

    exempel pÄ konfiguration:

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

    resultatet

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

  • I nginx finns det ett fel som leder till lĂ€ckage av minnesinnehĂ„ll om rewrite-strĂ€ngen innehĂ„ller en nollbyte. NĂ€r nginx ger en omdirigering allokerar det en ny minnesbuffert som motsvarar den fulla lĂ€ngden av strĂ€ngen, men kopierar strĂ€ngen via en strĂ€ngfunktion dĂ€r nollbytet Ă€r en strĂ€ngterminator, sĂ„ strĂ€ngen kopieras endast fram till nollbytet och resten av bufferten innehĂ„ller oinitierade data. En detaljerad analys kan hittas hĂ€r.

    exempel pÄ konfiguration (^@ nollbyte)

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

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

  • Nginx skyddar GET-parametrar mot injektion av kontrolltecken och ger möjlighet att anvĂ€nda i rewrite endast GET-parametrar. DĂ€rför gĂ„r det inte att utnyttja injektion via anvĂ€ndarkontrollerade parametrar i nginx. POST-parametrar Ă€r dĂ€remot inte skyddade. OpenResty tillĂ„ter att arbeta bĂ„de med GET- och POST-parametrar, vilket innebĂ€r att det finns möjlighet till injektion av specialtecken nĂ€r man anvĂ€nder POST-parametrar genom OpenResty.

    exempel pÄ konfiguration:

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

    resultat:

    curl localhost:8337 -d "url=hemlig" -vv
    ...
    curl localhost:8337 -d "url=%00asdfasdfasdfasdfasdfasdfasdfasdf" -vv
    ...
    Plats: http://localhost:8337/{...kan innehÄlla hemlig...}
    ...

Fortsatt reaktion

Problemet har rapporterats till utvecklarna av nginx och OpenResty, utvecklarna ser inte problemet som en sÀkerhetsbrist i nginx, eftersom det inte finns nÄgot sÀtt att utnyttja felet genom injektion av specialtecken, fix av lÀckage av minnesinnehÄll publicerades den 16 december. Fyra mÄnader efter rapporteringen har det inte heller gjorts nÄgra Àndringar i OpenResty, trots att man förstod att det behövdes en sÀker version av funktionen ngx.req.set_uri(). Den 18 mars 2020 publicerade vi information och den 21 mars slÀppte OpenResty version 1.15.8.3, som lÀgger till kontroll av URI.

Portswigger skrev en bra artikel och jag tog kommentarer frÄn OpenResty och Nginx (men kommentaren om att endast en liten del av minnet avslöjas Àr felaktig och missledande, detta bestÀms av lÀngden pÄ strÀngen som följer efter nollbyte och, vid avsaknad av tydliga begrÀnsningar för lÀngden, kan kontrolleras av en angripare).

SÄ vad var felet och vad kan göras för att förhindra det?

Var felet i nginx? Ja, det var det, eftersom minneslÀckage ÀndÄ Àr ett fel.

Var det nÄgot fel med OpenResty? Ja, Ätminstone har frÄgan om sÀkerheten för den funktionalitet som OpenResty erbjuder inte undersökts eller dokumenterats.

Fanns det ett konfigurations-/anvÀndningsfel i OpenResty? Ja, för i avsaknad av en tydlig angivelse gjordes en otestad antagande om sÀkerheten i den anvÀnda funktionaliteten.

Vilket av dessa fel utgör en sÀkerhetsrisk med ett bountyy pÄ $10000? För oss Àr det i stort sett oviktigt. I all programvara, sÀrskilt i skÀrningspunkten mellan flera komponenter, sÀrskilt de som tillhandahÄlls av olika projekt och utvecklare, kan ingen nÄgonsin garantera att alla aspekter av deras funktion Àr kÀnda och dokumenterade och att det inte finns nÄgra fel. DÀrför uppstÄr varje sÀkerhetsrisk dÀr den pÄverkar sÀkerheten.

I vilket fall som helst Àr det en bra praxis att normalisera eller begrÀnsa/filtera indata som gÄr till nÄgot externt modul/API, om det inte finns tydliga angivelser och en entydig förstÄelse av att detta inte Àr nödvÀndigt.

Errata

Enligt erfarenhet den tidigare artikeln, för att bevara sprÄkets renhet:

bug bounty — en tĂ€vling för att hitta fel
bugrapport — felanmĂ€lan
redirect — omdirigering
öppen kĂ€llkod — öppen kĂ€llkod
errata — arbete med fel

KĂ€lla: habr.com

Köp pĂ„litlig webbhotell med DDoS-skydd, VPS VDS-servrar đŸ”„ Köp pĂ„litlig webbhotell med DDoS-skydd, VPS VDS-servrar | ProHoster