Om en sårbarhet i...

Om en sårbarhet i...

For ett år siden, 21. mars 2019, i bug bounty-program Mail.Ru en veldig god en kom til HackerOne feilrapport fra maxarr. Når du introduserte en nullbyte (ASCII 0) i POST-parameteren til en av webmail API-forespørslene som returnerte en HTTP-omdirigering, var deler av uinitialisert minne synlige i omdirigeringsdataene, der fragmenter fra GET-parametere og overskrifter til andre forespørsler til samme server.

Dette er en kritisk sårbarhet fordi... forespørsler inneholder også øktinformasjonskapsler. Noen timer senere ble det laget en midlertidig rettelse som filtrerte nullbyten (som det viste seg senere, dette var ikke nok, fordi det fortsatt var mulighet for å injisere CRLF / ASCII 13, 10, som lar deg manipulere overskriftene og data fra HTTP-svaret, er dette mindre kritisk, men fortsatt ubehagelig). Samtidig ble problemet overført til sikkerhetsanalytikere og utviklere for å finne og eliminere årsakene til feilen.

Mail.ru mail er en veldig kompleks applikasjon; et stort antall forskjellige front-end/back-end-komponenter, både åpen kildekode (takk til alle gratis programvareutviklere) og egenutviklede, kan være involvert i å generere responsen. Vi klarte å ekskludere alle komponenter unntatt nginx og openresty og lokalisere problemet før vi ringte ngx.req.set_uri() i et OpenResty-skript som ikke oppførte seg som forventet (å sette inn en nullbyte eller linjefeed via GET-parametere med rewrite i ngx_http_rewrite_module, som i følge dokumentasjonen brukes og, det ser ut til, skal fungere på nøyaktig samme måte, vil fungerer ikke). Mulige konsekvenser ble eliminert, filtrering ble lagt til så strengt som mulig, og filtrering ble verifisert for å eliminere alle mulige vektorer. Men mekanismen som førte til lekkasje av minneinnhold forble et mysterium. En måned senere ble feilrapporten stengt som løst, og analysen av årsakene til feilen ble utsatt til bedre tider.

OpenResty er en veldig populær plugin som lar deg skrive Lua-skript inne i nginx, og den brukes i flere Mail.ru-prosjekter, så problemet ble ikke ansett som løst. Og etter en tid kom de endelig tilbake til det for å forstå de sanne årsakene, mulige konsekvenser og komme med anbefalinger til utviklere. Deltok i utgravingen av kildekoden Denis Denisov и Nikolay Ermishkin. Det viste seg at:

  • I nginx, når du bruker omskriving med brukerdata, er det mulighet for kataloggjennomgang (og sannsynligvis SSRF) i noen konfigurasjoner, men dette er et kjent faktum og bør oppdages av statiske konfigurasjonsanalysatorer i Nginx Amplify и gixy fra Yandex (ja, vi bruker det også, takk). Når du bruker OpenResty er denne funksjonen lett å gå glipp av, men dette påvirket ikke konfigurasjonen vår.

    konfigurasjonseksempel:

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

    resultere

    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 har en feil som får minne til å lekke hvis omskrivingslinjen inneholder en nullbyte. Når en omdirigering utstedes, tildeler nginx en ny minnebuffer som tilsvarer hele lengden av linjen, men kopierer linjen dit gjennom en linjefunksjon der nullbyten er en linjeavslutning, så linjen kopieres bare opp til null byte; resten av bufferen inneholder uinitialiserte data. En detaljert analyse kan bli funnet her.

    konfigurasjonseksempel (^@ null byte)

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

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

  • Nginx beskytter GET-parametere fra injeksjon av tjenestekarakterer og gjør det mulig å bruke kun GET-parametere i omskriving. Derfor er det ikke mulig å utnytte injeksjon gjennom brukerkontrollerte parametere i nginx. POST-parametere er ikke beskyttet. OpenResty lar deg jobbe med både GET- og POST-parametere, så når du bruker POST-parametere gjennom OpenResty, blir det mulig å injisere spesialtegn.

    konfigurasjonseksempel:

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

Videre reaksjon

Problemet ble rapportert til utviklerne av nginx og OpenResty, utviklerne anser ikke problemet som en sikkerhetsfeil i nginx, fordi i selve nginx er det ingen måte å utnytte feilen gjennom injeksjon av spesialtegn, fiks minneavsløring ble publisert 16. desember. I løpet av de 4 månedene etter rapporten har det ikke blitt gjort endringer i OpenResty, selv om det var en forståelse av at en sikker versjon av ngx.req.set_uri()-funksjonen var nødvendig. 18. mars 2020 publiserte vi informasjon, 21. mars ble OpenResty utgitt versjon 1.15.8.3, som legger til URI-validering.

Portswigger jeg skrev god artikkel og tok kommentarer fra OpenResty og Nginx (selv om kommentaren om at bare et lite fragment av minnet er avslørt er feil og misvisende, dette bestemmes av lengden på linjen etter null-byten og, i fravær av eksplisitte begrensninger på lengde, kan kontrolleres av angriperen).

Så hva var feilen og hva kan gjøres for å forhindre det?

Var det en feil i nginx? Ja, det var det, fordi lekkasje av minneinnhold er en feil i alle fall.

Var det en feil i OpenResty? Ja, i det minste er ikke spørsmålet om sikkerheten til funksjonaliteten som tilbys av OpenResty blitt undersøkt og dokumentert.

Var det en konfigurasjons-/bruksfeil med OpenResty? Ja, fordi i fravær av en eksplisitt uttalelse, ble det gjort en ubekreftet antagelse om sikkerheten til funksjonaliteten som brukes.

Hvilken av disse feilene er en sikkerhetssårbarhet med en dusør på $10000 XNUMX? For oss er dette generelt ikke viktig. I enhver programvare, spesielt i skjæringspunktet mellom flere komponenter, spesielt de som leveres av forskjellige prosjekter og utviklere, kan ingen garantere at alle funksjonene i arbeidet deres er kjent og dokumentert og at det ikke er noen feil. Derfor oppstår ethvert sikkerhetssårbarhet akkurat der det påvirker sikkerheten.

I alle fall er det god praksis å normalisere eller begrense/filtrere så mye som mulig inndataene som går inn i en ekstern modul/API, med mindre det er eksplisitte instruksjoner og en klar forståelse av at dette ikke er nødvendig.

trykkfeil

Av erfaring forrige artikkel, for å bevare språkets renhet:

bug dusør — insektjaktkonkurranse
feilrapport - feilmelding
omdirigere - omdirigering
åpen kilde - åpen kilde
feil - jobbe med feil

Kilde: www.habr.com

Legg til en kommentar