Umbes üks haavatavus...

Umbes üks haavatavus...

Aasta tagasi, 21. märtsil 2019, kl bug bounty programm Mail.Ru väga hea tuli HackerOne'ile veateade pärit maxarr. Nullbaidi (ASCII 0) sisestamisel ühe HTTP-ümbersuunamise tagastanud veebimeili API päringu POST-parameetrisse, olid ümbersuunamisandmetes nähtavad initsialiseerimata mälutükid, milles fragmendid GET-parameetritest ja muude päringute päised sama server.

See on kriitiline haavatavus, kuna... päringud sisaldavad ka seansiküpsiseid. Paar tundi hiljem tehti ajutine parandus, mis filtreeris nullbaidi (nagu hiljem selgus, sellest ei piisanud, sest endiselt oli võimalus sisestada CRLF / ASCII 13, 10, mis võimaldab manipuleerida päistega ja HTTP vastuse andmed, on see vähem kriitiline, kuid siiski ebameeldiv). Samal ajal anti probleem üle turvaanalüütikutele ja arendajatele, et leida ja kõrvaldada vea põhjused.

Mail.ru post on väga keeruline rakendus, vastuse genereerimisel saab kaasata palju erinevaid esi-/tagaosa komponente, nii avatud lähtekoodiga (suur tänu kõigile tasuta tarkvara arendajatele) kui ka ettevõttesiseselt arendatud. Meil õnnestus välistada kõik komponendid peale nginxi ja openresty ning enne helistamist probleem lokaliseerida ngx.req.set_uri() OpenResty skriptis, mis ei käitunud ootuspäraselt (nullbaidi või reavahetuse sisestamine GET parameetrite kaudu koos ümberkirjutamisega moodulis ngx_http_rewrite_module, mida vastavalt dokumentatsioonile kasutatakse ja tundub, et see peaks töötama täpselt samamoodi, ei tööta). Võimalikud tagajärjed kõrvaldati, filtreerimine lisati võimalikult rangelt ja filtreerimine kontrolliti kõigi võimalike vektorite kõrvaldamiseks. Kuid mehhanism, mis viis mälusisu lekkimiseni, jäi saladuseks. Kuu aega hiljem suleti veateade lahendatuna ja vea põhjuste analüüs lükati parematesse aegadesse.

OpenResty on väga populaarne pistikprogramm, mis võimaldab nginxi sees Lua skripte kirjutada ja seda kasutatakse mitmes Mail.ru projektis, mistõttu probleemi ei peetud lahendatuks. Ja mõne aja pärast pöördusid nad lõpuks selle juurde tagasi, et mõista tegelikke põhjuseid, võimalikke tagajärgi ja anda arendajatele soovitusi. Osalenud lähtekoodi väljakaevamisel Deniss Denissov и Nikolai Ermiškin. Selgus, et:

  • Nginxis on kasutajaandmetega ümberkirjutamise kasutamisel võimalik mõnes konfiguratsioonis kataloogi läbimine (ja tõenäoliselt ka SSRF), kuid see on teada fakt ja seda peaksid tuvastama staatilised konfiguratsioonianalüsaatorid Nginx Amplify и Gixy Yandexist (jah, me kasutame ka seda, aitäh). OpenResty kasutamisel on seda funktsiooni lihtne kasutamata jätta, kuid see ei mõjutanud meie konfiguratsiooni.

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

  • Nginxis on viga, mis põhjustab mälu lekke, kui ümberkirjutusrida sisaldab nullbaiti. Ümbersuunamise korral eraldab nginx uue mälupuhvri, mis vastab rea täispikkusele, kuid kopeerib rea sinna reafunktsiooni kaudu, milles nullbait on rea lõpetaja, nii et rida kopeeritakse ainult nullini. bait; ülejäänud puhver sisaldab initsialiseerimata andmeid. Üksikasjaliku analüüsi leiate siin.

    konfiguratsiooni näide (^@ null bait)

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

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

  • Nginx kaitseb GET-i parameetreid teenusemärkide sisestamise eest ja võimaldab ümberkirjutamisel kasutada ainult GET-parameetreid. Seetõttu ei ole nginxis kasutaja juhitavate parameetrite kaudu süstimist võimalik kasutada. POST-i parameetrid pole kaitstud. OpenResty võimaldab töötada nii GET-i kui ka POST-i parameetritega, nii et OpenResty kaudu POST-i parameetrite kasutamisel muutub võimalikuks erimärkide sisestamine.

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

Edasine reaktsioon

Probleemist teatati nginxi ja OpenResty arendajatele, arendajad ei pea seda probleemi nginxi turvaveaks, kuna nginxis endas ei saa viga kuidagi erimärkide sisestamise kaudu ära kasutada, parandage mälu avalikustamine avaldati 16. detsembril. Aruandest möödunud 4 kuu jooksul ei ole OpenRestysse muudatusi tehtud, kuigi oli arusaam, et vaja on funktsiooni ngx.req.set_uri() turvalist versiooni. 18. märtsil 2020 avaldasime teabe, 21. märtsil avaldasime OpenResty versioon 1.15.8.3, mis lisab URI valideerimise.

Portswigger kirjutasin hea artikkel ja võttis kommentaarid OpenRestylt ja Nginxilt (kuigi kommentaar, et paljastatakse vaid väike osa mälust, on vale ja eksitav, määrab selle nullbaidile järgneva rea ​​pikkus ja selgete piirangute puudumisel pikkus, saab ründaja juhtida).

Milles siis viga oli ja mida selle vältimiseks teha?

Kas nginxis oli viga? Jah, oligi, sest mälusisu lekkimine on igal juhul viga.

Kas OpenResty's oli viga? Jah, vähemalt OpenResty pakutava funktsionaalsuse turvalisuse küsimust pole uuritud ja dokumenteeritud.

Kas OpenRestyga oli konfiguratsiooni-/kasutusviga? Jah, kuna selgesõnalise avalduse puudumisel tehti kontrollimata oletus kasutatava funktsionaalsuse turvalisuse kohta.

Milline neist vigadest on 10000 XNUMX-dollarilise hüvitusega turvahaavatavus? Meie jaoks pole see üldiselt oluline. Igas tarkvaras, eriti mitme komponendi ristumiskohas, eriti nende, mida pakuvad erinevad projektid ja arendajad, ei saa keegi kunagi garanteerida, et kõik nende töö funktsioonid on teada ja dokumenteeritud ning vigu ei esine. Seetõttu ilmneb igasugune turvanõrkus täpselt seal, kus see turvalisust mõjutab.

Igal juhul on hea tava normaliseerida või piirata/filtreerida võimalikult palju sisendandmeid, mis lähevad mis tahes välisesse moodulisse/API-sse, välja arvatud juhul, kui on olemas selged juhised ja selge arusaam, et see pole vajalik.

Viga

Kogemusest eelmine artikkel, keele puhtuse säilitamise huvides:

vearaha — putukajahivõistlus
veateade - veateade
ümber suunata - ümbersuunamine
avatud lähtekoodiga - avatud lähtekoodiga
eksitus - töötage vigade kallal

Allikas: www.habr.com

Lisa kommentaar