Ahultasun bati buruz...

Ahultasun bati buruz...

Duela urtebete, 21ko martxoaren 2019ean, orduetan akatsen sari programa Mail.Ru oso ona etorri zen HackerOnera akatsen txostena tik maxarr. Zero byte bat (ASCII 0) POST parametroan HTTP birbideraketa itzultzen zuen web-mailako API eskaeraren baten POST parametroan sartzean, hasieratu gabeko memoria zatiak ikusten ziren birbideratze datuetan, zeinetan GET parametroetako zatiak eta beste eskaeren goiburukoak. zerbitzari bera.

Hau ahultasun kritikoa da, zeren... eskaerek saio-cookieak ere badituzte. Ordu batzuk geroago, zero byte iragazten zuen behin-behineko konponketa bat egin zen (geroago ikusi zenez, hori ez zen nahikoa, oraindik ere CRLF / ASCII 13, 10 injektatzeko aukera zegoelako, goiburuak eta goiburuak manipulatzeko aukera ematen duena). HTTP erantzunaren datuak, hau ez da hain kritikoa, baina oraindik desatsegina). Aldi berean, arazoa segurtasun analista eta garatzaileei transferitu zitzaien akatsaren kausak aurkitzeko eta ezabatzeko.

Mail.ru posta oso aplikazio konplexua da; front-end/back-end osagai ezberdinen kopuru handi batek parte hartu dezake erantzuna sortzen, bai kode irekiko (esker asko software libreko garatzaile guztiei) bai barne garatutakoak. Osagai guztiak baztertzea lortu dugu nginx eta openresty izan ezik eta arazoa lokalizatu egin dugu deitu aurretik ngx.req.set_uri() espero bezala jokatu ez zuen OpenResty script batean (byte nulua edo lerro-jarrera GET parametroen bidez ngx_http_rewrite_module-n berridazketarekin txertatzea, dokumentazioaren arabera, erabiltzen dena eta, antza denez, modu berean funtzionatu beharko lukeena). ez da lana). Gerta daitezkeen ondorioak ezabatu ziren, iragazketa ahalik eta zorrotzen gehitu zen eta iragazketa egiaztatu zen bektore posible guztiak ezabatzeko. Baina memoriaren edukien ihesa eragin zuen mekanismoak misterio bat izaten jarraitzen zuen. Hilabete beranduago, akatsen txostena konpondu zen bezala itxi zen, eta akatsaren kausen azterketa garai hobeetara arte atzeratu zen.

OpenResty nginx-en Lua script-ak idazteko aukera ematen duen plugin oso ezaguna da eta Mail.ru-ren hainbat proiektutan erabiltzen da, beraz, arazoa ez zen konpondutzat jo. Eta denbora pixka bat igaro ondoren, azkenean bertara itzuli ziren benetako arrazoiak, ondorio posibleak ulertzeko eta garatzaileentzako gomendioak egiteko. Iturburu-kodearen indusketan parte hartu du Denis Denisov ΠΈ Nikolay Ermishkin. Hori atera zen:

  • Nginx-en, erabiltzailearen datuekin berridazketa erabiltzean, direktorioa zeharkatzeko aukera dago (eta ziurrenik SSRF) konfigurazio batzuetan, baina hori gauza ezaguna da eta konfigurazio-analizzatzaile estatikoek detektatu beharko lukete. Nginx Amplify ΠΈ gixy Yandex-etik (bai, hori ere erabiltzen dugu, eskerrik asko). OpenResty erabiltzean, funtzio hau erraz galtzen da, baina horrek ez du gure konfigurazioan eraginik izan.

    konfigurazio adibidea:

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

    ondorioz,

    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-ek akats bat du, memoria ihesa eragiten duena, berridazketa lerroak byte nulu bat badu. Birbideratze bat igortzen denean, nginx-ek lerroaren luzerari dagokion memoria-buffer berri bat esleitzen du, baina lerroa bertan kopiatzen du lerro-funtzio baten bidez, zeinetan zero bytea lerro amaiera den, beraz, lerroa zeroraino bakarrik kopiatzen da. byte; gainerako buffer-ak hasieratu gabeko datuak ditu. Azterketa zehatza aurki daiteke Hemen.

    konfigurazio adibidea (^@ zero byte)

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

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

  • Nginx-ek GET parametroak zerbitzu karaktereen injekziotik babesten ditu eta berridazketan GET parametroak soilik erabiltzea posible egiten du. Hori dela eta, ezin da injekzioa ustiatu erabiltzaileak kontrolatutako parametroen bidez nginx-en. POST parametroak ez daude babestuta. OpenResty-k GET eta POST parametroekin lan egiteko aukera ematen du, beraz, POST parametroak OpenResty bidez erabiltzean, karaktere bereziak sartzea posible egiten da.

    konfigurazio adibidea:

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

    emaitza:

    curl localhost:8337 -d "url=secret" -vv
    ...
    curl localhost:8337 -d "url=%00asdfasdfasdfasdfasdfasdfasdfasdf" -vv
    ...
    Location: http://localhost:8337/{...ΠΌΠΎΠΆΠ΅Ρ‚ ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Ρ‚ΡŒ secret...}
    ...

Erreakzio gehiago

Arazoa nginx eta OpenResty garatzaileei jakinarazi zitzaien, garatzaileek ez dute arazoa nginx-en segurtasun akats gisa hartzen, zeren eta nginx-en bertan ez dago errorea ustiatzeko modurik karaktere berezien injekzio bidez, konpondu memoriaren dibulgazioa abenduaren 16an argitaratu zen. Txostena egin zenetik 4 hilabeteetan, ez da aldaketarik egin OpenResty-n, ngx.req.set_uri() funtzioaren bertsio seguru bat behar zela ulertu bazen ere. 18ko martxoaren 2020an informazioa argitaratu genuen, martxoaren 21ean OpenResty kaleratu zen 1.15.8.3 bertsioa, URI baliozkotzea gehitzen duena.

Portswigger idatzi nuen artikulu ona eta OpenResty eta Nginx-en iruzkinak hartu zituen (memoria zati txiki bat bakarrik azaltzen den iruzkina okerra eta engainagarria den arren, byte nuluaren ondorengo lerroaren luzerak zehazten du eta, murrizketa espliziturik ez dagoenean). luzera, erasotzaileak kontrola dezake).

Beraz, zein izan zen akatsa eta zer egin daiteke hura saihesteko?

Akatsik egon al zen nginx-en? Bai, hala izan zen, memoriaren edukia ihes egitea edozein kasutan errore bat baita.

OpenResty-n akatsik egon al da? Bai, gutxienez OpenResty-k eskaintzen duen funtzionalitatearen segurtasunaren arazoa ez da ikertu eta dokumentatu.

Konfigurazio/erabileraren errorerik egon al da OpenResty-rekin? Bai, adierazpen espliziturik ezean, erabilitako funtzionalitatearen segurtasunari buruz egiaztatu gabeko hipotesi bat egin delako.

Akats hauetako zein da 10000 $-ko sari duen segurtasun ahultasun bat? Guretzat, oro har, hori ez da garrantzitsua. Edozein softwaretan, batez ere hainbat osagairen elkargunean, bereziki proiektu eta garatzaile ezberdinek emandakoetan, inork ezin du inoiz bermatu bere lanaren ezaugarri guztiak ezagutzen eta dokumentatuta daudenik eta akatsik ez dagoenik. Hori dela eta, segurtasun ahultasun oro segurtasunari eragiten dion tokian gertatzen da.

Nolanahi ere, praktika ona da kanpoko edozein modulu/APItan sartzen diren sarrerako datuak ahalik eta gehien normalizatzea edo mugatzea/iragazkia, baldin eta argibide esplizituak eta hori beharrezkoa ez dela ulertzen argi eta garbi ez badago.

Erratea

Esperientziaz aurreko artikulua, hizkuntzaren garbitasuna zaintzeko:

akatsen saria β€” zomorroen ehiza lehiaketa
akatsen txostena - akatsen jakinarazpena
birbideratu - birbideratzea
kode irekia - kode irekia
erratu - akatsak lantzea

Iturria: www.habr.com

Gehitu iruzkin berria