Ühest haavatavusest


Ühest haavatavusest


Aasta tagasi, 21. mĂ€rtsil 2019, Mail.Ru bug bounty programmi HackerOne'ile tuli vĂ€ga hea bugiraport alates maxarr. Ühe web-maili API-pĂ€ringu POST-parameetritesse nullbaiti (ASCII 0) sisestades ilmnes HTTP-ĂŒmber suunamise andmetes mitte-initsialiseeritud mĂ€lu osi, milles sageli ilmusid teistele pĂ€ringutele saadetud GET-parameetrite ja pĂ€iste killud, mis suundusid samale serverile.

See on kriitiline haavatavus, kuna pĂ€ringud sisaldavad ka sessioonikuki. MĂ”ne tunni pĂ€rast tehti ajutine lahendus, mis filtreeris nullbaiti (nagu hiljem selgus, oli seda ebapiisav, kuna jĂ€i vĂ”imalus CRLF / ASCII 13, 10 sisestamiseks, mis vĂ”imaldab HTTP-pealkirjade ja vastuse andmete manipuleerimist, see on vĂ€hem kriitiline, kuid siiski ebameeldiv). Samal ajal edastati probleem turvaanalĂŒĂŒtikutele ja arendajatele pĂ”hjuse vĂ€ljaselgitamiseks ja vea kĂ”rvaldamiseks.

Mail.ru post on vĂ€ga keeruline rakendus, mille vastamise vormimisel vĂ”ib osaleda suur hulk erinevaid frontend/backendi komponente, nii avatud lĂ€htekoodiga (suur tĂ€nu kĂ”ikidele vabatahtlike arendajatele) kui ka omatooted. Õnnestus vĂ€lja jĂ€tta kĂ”ik komponendid peale nginx ja openresty ning lokaliseerida probleem kuni vĂ€ljakutse ngx.req.set_uri() OpenResty skriptis, mis ei kĂ€itunud ootuspĂ€raselt (nullbaiti vĂ”i reavahetuse sisestamine GET-parameetrite kaudu rewrite-s ngx_http_rewrite_module'i, mis vastavalt dokumentatsioonile kasutatakse ja peaks töötama tĂ€iesti samamoodi, ei Ă”nnestu). VĂ”imalikud tagajĂ€rjed kĂ”rvaldati, kasutusele vĂ”eti vĂ”imalikult range filtreerimine ning kontrolliti, et filtreerimine kĂ”rvaldab kĂ”ik vĂ”imalikud vektorid. Kuid mehanism, mis viis mĂ€lu sisu lekke tekkimiseni, jĂ€i endiselt mĂŒsteeriumiks. Kuu aja pĂ€rast suleti viga lahendatuks ja vea tekkimise pĂ”hjuste analĂŒĂŒs lĂŒkati edasi paremate aegade tarbeks.

OpenResty on populaarne plugin, mis vÔimaldab kirjutada Lua skripte nginx-s, ja seda kasutatakse mitmes Mail.ru projektis, mistÔttu probleemi ei peetud lahendatuks. Aja möödudes naaseti sellesse, et mÔista tÔelisi pÔhjuseid, vÔimalikud tagajÀrjed ja koostada soovitused arendajatele. Algkoodi uurimisse osalesid Denis Denisov ja Nikolai Ermiƥkin. Selgus, et:

  • nginx-is, kui kasutatakse rewrite'i koos kohandatud andmetega, on vĂ”imalik directory traversal (vĂ”imalik, et ka SSRF) teatud konfigureerimiste korral, kuid see on tuntud fakt, ja seda peaksid avastama konfiguratsiooni staatilised analĂŒsaatorid Nginx Amplify ja Gixy Yandexist (jah, me kasutame seda ka, aitĂ€h). OpenResty kasutamisel on selline vĂ”imalus kergesti mööda lastav, kuid meie konfiguratsioon seda ei puudutanud.

    konfiguratsiooni nÀide:

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

    tulemus

    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'il on vigastus, mis pĂ”hjustab mĂ€lu lekkimist, kui rewrite rida sisaldab nullbaiti. Ümber suunamise korral eraldab nginx uue mĂ€lu puhversalviku, mis vastab kogu rea pikkusele, kuid kopeerib rea tĂŒhja funktsiooni kaudu, kus nullbitt on rea terminator, mistĂ”ttu rida kopeeritakse ainult nullbaiti kuni, ĂŒlejÀÀnud puhver sisaldab mitteinihiseeritud andmeid. Üksikasjalik analĂŒĂŒs on saadaval siit.

    konfiguratsiooni nÀide (^@ nullbitt)

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

    tulemus
    curl localhost:8337/secret -vv
    ...
    curl localhost:8337/memleak -vv
    ...
    Asukoht: http://localhost:8337/secret
    ...

  • Nginx kaitseb GET parameetreid sĂŒmbolite sisestamise eest ja vĂ”imaldab rewrite'is kasutada ainult GET parameetreid. SeetĂ”ttu ei saa kasutaja mÀÀratud parameetrite kaudu nginx'is sisestamist Ă€ra kasutada. POST parameetrid ei ole samas kaitstud. OpenResty vĂ”imaldab töötada nii GET kui ka POST parameetritega, mistĂ”ttu OpenResty kaudu POST parameetrite kasutamisel tekib vĂ”imalus sisestada spetsiaalseid sĂŒmboleid.

    konfiguratsiooni nÀide:

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

    tulemus:

    curl localhost:8337 -d "url=salad" -vv
    ...
    curl localhost:8337 -d "url=%00asdfasdfasdfasdfasdfasdfasdfasdf" -vv
    ...
    Aadress: http://localhost:8337/{...vÔib sisaldada saladust...}
    ...

Edasi minev reaktsioon

Probleemi on teatanud Nginx'i ja OpenResty arendajad, kes ei pea seda probleemiks Nginx'is, kuna Nginx'is ei ole vĂ”imalust vea Ă€ra kasutamiseks spetsiaalsete mĂ€rkide sĂŒstimise kaudu, lahendus mĂ€lu sisu avamine oli avaldatud 16. detsembril. Nelja kuu jooksul pĂ€rast raportit OpenResty's ei ole samuti tehtud mingeid muudatusi, kuigi oli arusaam, et vajalik on ohutum funktsiooni ngx.req.set_uri() variant. 18. mĂ€rtsil 2020 avaldasime teabe, 21. mĂ€rtsil avaldas OpenResty versiooni 1.15.8.3, mis lisab URI kontrolli.

Portswigger kirjutas hea artikkel, millele sai tagasisidet OpenResty ja Nginx'ilt (kuid vĂ€ide, et avatakse vaid vĂ€ike mĂ€lufragment, on vale ja eksitav, see sĂ”ltub nullbaiti jĂ€rgnevast stringi pikkusest ja rikka piirangute puudumisel vĂ”ib seda juhtida rĂŒndaja).

Mis siis oli vale ja mida teha, et seda vÀltida?

Kas viga oli Nginx'is? Jah, oli, kuna mÀlu sisu leke on igal juhul viga.

Kas viga oli OpenResty's? Jah, vĂ€hemalt ei ole uuritud ja dokumenteeritud avatud OpenResty funktsionaalsuse turvalisuse kĂŒsimus.

Kas OpenResty konfiguratsioonis vÔi kasutamises oli viga? Jah, kuna selge viiteta tehti kontrollimata oletus kasutatava funktsionaalsuse turvalisuse kohta.

Milline neist vigadest on turvaaukus, mille pealt on $10000 preemia? Meie jaoks ei ole see pÔhimÔtteliselt oluline. Igas tarkvaras, eriti seal, kus on mitu komponenti, mis on pakutud erinevate projektide ja arendajate poolt, ei saa keegi kunagi garanteerida, et kÔik töövÔtted on teada, dokumenteeritud ja et vigu ei esine. SeetÔttu tekib iga turvavigastus seal, kus see mÔjutab turvalisust.

Igatahes on hea praktika normaliseerida vĂ”i vĂ”imalikult palju piirata/filtreerida sisendandmeid, mis suunduvad igasse vĂ€list moodulisse/API-sse, kui ei ole selgeid viiteid ja ĂŒheselt mĂ”istetavat arusaamist, et seda ei ole vajalik teha.

Errata

Kogemuse pÔhjal eelmisest artiklist., keele puhtuse sÀilitamiseks:

bug bounty — vigade jahiks mĂ”eldud vĂ”istlus
bugiraport — vea teatis
suunamine — ĂŒmbersuunamine
avatud lĂ€htekoodiga — avatud koodiga
errata — vigade parandamine

Allikas: habr.com

Osta usaldusvÀÀrne veebihosting DDoS kaitsega, VPS VDS serverid đŸ”„ Osta usaldusvÀÀrne veebihosting DDoS kaitsega, VPS VDS serverid | ProHoster