Om en sårbarhed i...

Om en sårbarhed i...

For et år siden, den 21. marts 2019, i bug bounty-program Mail.Ru en meget god en kom til HackerOne fejlrapport fra maxarr. Når en nulbyte (ASCII 0) blev introduceret i POST-parameteren for en af ​​webmail API-anmodningerne, der returnerede en HTTP-omdirigering, var stykker af uinitialiseret hukommelse synlige i omdirigeringsdataene, hvori fragmenter fra GET-parametre og overskrifter fra andre anmodninger til samme server.

Dette er en kritisk sårbarhed, fordi... anmodninger indeholder også sessionscookies. Et par timer senere blev der lavet en midlertidig rettelse, der filtrerede nulbyten (som det viste sig senere, var dette ikke nok, fordi der stadig var mulighed for at injicere CRLF / ASCII 13, 10, som giver dig mulighed for at manipulere overskrifterne og data fra HTTP-svaret, dette er mindre kritisk, men stadig ubehageligt). Samtidig blev problemet overført til sikkerhedsanalytikere og udviklere for at finde og fjerne årsagerne til fejlen.

Mail.ru mail er en meget kompleks applikation; et stort antal forskellige front-end/back-end komponenter, både open source (meget tak til alle gratis softwareudviklere) og internt udviklede, kan være involveret i at generere svaret. Vi formåede at udelukke alle komponenter undtagen nginx og openresty og lokalisere problemet før vi ringede ngx.req.set_uri() i et OpenResty-script, der ikke opførte sig som forventet (indsættelse af en null-byte eller linjefeed via GET-parametre med rewrite i ngx_http_rewrite_module, som ifølge dokumentationen bruges, og som det ser ud til, skulle fungere på nøjagtig samme måde, vil ikke arbejde). Mulige konsekvenser blev elimineret, filtrering blev tilføjet så strengt som muligt, og filtrering blev verificeret for at eliminere alle mulige vektorer. Men mekanismen, der førte til lækagen af ​​hukommelsesindhold, forblev et mysterium. En måned senere blev fejlrapporten lukket som løst, og analysen af ​​årsagerne til fejlen blev udskudt til bedre tider.

OpenResty er et meget populært plugin, der giver dig mulighed for at skrive Lua-scripts inde i nginx, og det bruges i flere Mail.ru-projekter, så problemet blev ikke betragtet som løst. Og efter nogen tid vendte de endelig tilbage til det for at forstå de sande årsager, mulige konsekvenser og komme med anbefalinger til udviklere. Deltog i udgravningen af ​​kildekoden Denis Denisov и Nikolay Ermishkin. Det viste sig at:

  • I nginx, når du bruger omskrivning med brugerdata, er der mulighed for mappegennemgang (og sandsynligvis SSRF) i nogle konfigurationer, men dette er et kendt faktum og bør detekteres af statiske konfigurationsanalysatorer i Nginx forstærker и gixy fra Yandex (ja, det bruger vi også, tak). Når du bruger OpenResty, er denne funktion let at gå glip af, men dette påvirkede ikke vores konfiguration.

    konfigurationseksempel:

    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 fejl, der får hukommelse til at lække, hvis omskrivningslinjen indeholder en null-byte. Når der udstedes en omdirigering, allokerer nginx en ny hukommelsesbuffer svarende til den fulde længde af linjen, men kopierer linjen dertil gennem en linjefunktion, hvor nulbyten er en linjeterminator, så linjen kopieres kun op til nul byte; resten af ​​bufferen indeholder ikke-initialiserede data. En detaljeret analyse kan findes her.

    konfigurationseksempel (^@ nul 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-parametre mod indsprøjtning af servicekarakterer og gør det muligt kun at bruge GET-parametre til omskrivning. Derfor er det ikke muligt at udnytte injektion gennem brugerkontrollerede parametre i nginx. POST-parametre er ikke beskyttet. OpenResty giver dig mulighed for at arbejde med både GET- og POST-parametre, så når du bruger POST-parametre gennem OpenResty, bliver det muligt at injicere specialtegn.

    konfigurationseksempel:

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

Yderligere reaktion

Problemet blev rapporteret til udviklerne af nginx og OpenResty, udviklerne betragter ikke problemet som en sikkerhedsfejl i nginx, fordi i nginx selv er der ingen måde at udnytte fejlen gennem indsprøjtning af specialtegn, fix afsløring af hukommelsen blev offentliggjort den 16. december. I de 4 måneder siden rapporten er der ikke foretaget ændringer i OpenResty, selvom der var en forståelse af, at en sikker version af ngx.req.set_uri()-funktionen var nødvendig. Den 18. marts 2020 offentliggjorde vi oplysninger, den 21. marts udgav OpenResty version 1.15.8.3, som tilføjer URI-validering.

Portswigger jeg skrev god artikel og tog kommentarer fra OpenResty og Nginx (selvom kommentaren om, at kun et lille fragment af hukommelsen er afsløret er forkert og vildledende, bestemmes dette af længden af ​​linjen efter null-byten og, i mangel af eksplicitte begrænsninger på længde, kan kontrolleres af angriberen).

Så hvad var fejlen, og hvad kan man gøre for at forhindre det?

Var der en fejl i nginx? Ja, det var det, for en hukommelseslækage er under alle omstændigheder en fejl.

Var der en fejl i OpenResty? Ja, i det mindste er spørgsmålet om sikkerheden af ​​den funktionalitet, der tilbydes af OpenResty, ikke blevet undersøgt og dokumenteret.

Var der en konfigurations-/brugsfejl med OpenResty? Ja, for i mangel af en eksplicit erklæring blev der foretaget en ubekræftet antagelse om sikkerheden af ​​den funktionalitet, der anvendes.

Hvilken af ​​disse fejl er en sikkerhedssårbarhed med en dusør på $10000? For os er dette generelt ikke vigtigt. I enhver software, især i skæringspunktet mellem flere komponenter, især dem, der leveres af forskellige projekter og udviklere, kan ingen nogensinde garantere, at alle funktionerne i deres arbejde er kendte og dokumenterede, og at der ikke er nogen fejl. Derfor opstår enhver sikkerhedssårbarhed præcis dér, hvor den påvirker sikkerheden.

Under alle omstændigheder er det god praksis at normalisere eller begrænse/filtrere så meget som muligt de inputdata, der går ind i ethvert eksternt modul/API, medmindre der er eksplicitte instruktioner og en klar forståelse af, at dette ikke er påkrævet.

trykfejl

Af erfaring tidligere artikel, for at bevare sprogets renhed:

bug dusør — fejljagtkonkurrence
fejlrapport - fejlmeddelelse
omdirigere - omdirigering
åben kildekode - open source
fejl - arbejde på fejl

Kilde: www.habr.com

Tilføj en kommentar