Tungkol sa isang kahinaan sa...

Tungkol sa isang kahinaan sa...

Isang taon na ang nakalipas, Marso 21, 2019, sa bug bounty program na Mail.Ru isang napakahusay na dumating sa HackerOne ulat ng bug mula sa maxarr. Kapag naglalagay ng zero byte (ASCII 0) sa POST parameter ng isa sa mga kahilingan sa webmail API na nagbalik ng HTTP redirect, ang mga piraso ng hindi nasimulang memorya ay makikita sa redirect data, kung saan ang mga fragment mula sa mga parameter ng GET at mga header ng iba pang mga kahilingan sa parehong server.

Ito ay isang kritikal na kahinaan dahil... ang mga kahilingan ay naglalaman din ng cookies ng session. Pagkalipas ng ilang oras, isang pansamantalang pag-aayos ang ginawa na nag-filter ng zero byte (tulad ng nangyari sa paglaon, hindi ito sapat, dahil mayroon pa ring posibilidad na mag-inject ng CRLF / ASCII 13, 10, na nagpapahintulot sa iyo na manipulahin ang mga header at data ng tugon ng HTTP, ito ay hindi gaanong kritikal, ngunit hindi pa rin kasiya-siya). Kasabay nito, inilipat ang problema sa mga security analyst at developer para hanapin at alisin ang mga sanhi ng bug.

Ang Mail.ru mail ay isang napakakomplikadong application; isang malaking bilang ng iba't ibang front-end/back-end na bahagi, parehong open source (maraming salamat sa lahat ng libreng software developer) at in-house na binuo, ay maaaring kasangkot sa pagbuo ng tugon. Nagawa naming ibukod ang lahat ng mga bahagi maliban sa nginx at openresty at i-localize ang problema bago tumawag ngx.req.set_uri() sa isang OpenResty script na hindi kumikilos gaya ng inaasahan (pagpasok ng null byte o line feed sa pamamagitan ng GET na mga parameter na may muling pagsulat sa ngx_http_rewrite_module, na, ayon sa dokumentasyon, ay ginagamit at, tila, ay dapat gumana nang eksakto sa parehong paraan, ay hindi gumagana). Ang mga posibleng kahihinatnan ay inalis, ang pag-filter ay idinagdag nang mahigpit hangga't maaari, at ang pag-filter ay na-verify upang maalis ang lahat ng posibleng mga vector. Ngunit ang mekanismo na humantong sa pagtagas ng mga nilalaman ng memorya ay nanatiling isang misteryo. Pagkalipas ng isang buwan, ang ulat ng bug ay isinara bilang nalutas, at ang pagsusuri ng mga sanhi ng bug ay ipinagpaliban hanggang sa mas magandang panahon.

Ang OpenResty ay isang napaka-tanyag na plugin na nagpapahintulot sa iyo na magsulat ng mga script ng Lua sa loob ng nginx, at ito ay ginagamit sa ilang mga proyekto ng Mail.ru, kaya ang problema ay hindi itinuturing na nalutas. At pagkaraan ng ilang oras, sa wakas ay bumalik sila dito upang maunawaan ang mga totoong dahilan, posibleng kahihinatnan at gumawa ng mga rekomendasyon para sa mga developer. Lumahok sa paghuhukay ng source code Denis Denisov ΠΈ Nikolay Ermishkin. Ito pala ay:

  • Sa nginx, kapag gumagamit ng rewrite gamit ang data ng user, may posibilidad ng directory traversal (at marahil SSRF) sa ilang mga configuration, ngunit ito ay isang kilalang katotohanan at dapat na makita ng mga static na configuration analyzer sa Nginx Amplify ΠΈ gixy mula sa Yandex (oo, ginagamit din namin iyon, salamat). Kapag gumagamit ng OpenResty, madaling makaligtaan ang feature na ito, ngunit hindi ito nakaapekto sa aming configuration.

    halimbawa ng pagsasaayos:

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

    magbunga

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

  • Ang Nginx ay may bug na nagiging sanhi ng pagtagas ng memorya kung ang linya ng muling pagsulat ay naglalaman ng null byte. Kapag naglabas ng redirect, ang nginx ay naglalaan ng bagong memory buffer na tumutugma sa buong haba ng linya, ngunit kinokopya ang linya doon sa pamamagitan ng isang function ng linya kung saan ang zero byte ay isang terminator ng linya, kaya ang linya ay kinopya lamang hanggang sa zero byte; ang natitirang bahagi ng buffer ay naglalaman ng hindi nasimulang data. Ang isang detalyadong pagsusuri ay matatagpuan dito.

    halimbawa ng configuration (^@ zero byte)

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

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

  • Pinoprotektahan ng Nginx ang mga parameter ng GET mula sa pag-iniksyon ng mga character ng serbisyo at ginagawang posible na gumamit lamang ng mga parameter ng GET sa muling pagsulat. Samakatuwid, hindi posible na samantalahin ang iniksyon sa pamamagitan ng mga parameter na kinokontrol ng gumagamit sa nginx. Ang mga parameter ng POST ay hindi protektado. Binibigyang-daan ka ng OpenResty na magtrabaho kasama ang parehong mga parameter ng GET at POST, kaya kapag gumagamit ng mga parameter ng POST sa pamamagitan ng OpenResty, nagiging posible na mag-inject ng mga espesyal na character.

    halimbawa ng pagsasaayos:

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

    resulta:

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

Dagdag reaksyon

Ang problema ay iniulat sa mga developer ng nginx at OpenResty, hindi isinasaalang-alang ng mga developer ang problema bilang isang security bug sa nginx, dahil sa nginx mismo walang paraan upang samantalahin ang error sa pamamagitan ng pag-iniksyon ng mga espesyal na character, ayusin pagsisiwalat ng memorya ay nai-publish noong Disyembre 16. Sa 4 na buwan mula noong ulat, walang pagbabagong ginawa sa OpenResty, bagama't nagkaroon ng pag-unawa na kailangan ang isang ligtas na bersyon ng ngx.req.set_uri() function. Noong Marso 18, 2020 nag-publish kami ng impormasyon, noong Marso 21 inilabas ang OpenResty bersyon 1.15.8.3, na nagdaragdag ng URI validation.

Portswigger Isinulat ni magandang artikulo at kumuha ng mga komento mula sa OpenResty at Nginx (bagaman ang komento na maliit na fragment ng memorya lamang ang nakalantad ay hindi tama at nakaliligaw, ito ay tinutukoy ng haba ng linya na sumusunod sa null byte at, sa kawalan ng tahasang mga paghihigpit sa haba, maaaring kontrolin ng umaatake).

Kaya ano ang pagkakamali at ano ang maaaring gawin upang maiwasan ito?

Nagkaroon ba ng bug sa nginx? Oo, ito ay, dahil ang pagtulo ng mga nilalaman ng memorya ay isang error sa anumang kaso.

Nagkaroon ba ng bug sa OpenResty? Oo, hindi bababa sa isyu ng seguridad ng functionality na inaalok ng OpenResty ay hindi pa naimbestigahan at naidokumento.

Nagkaroon ba ng error sa pagsasaayos/paggamit sa OpenResty? Oo, dahil sa kawalan ng tahasang pahayag, ginawa ang isang hindi na-verify na pagpapalagay tungkol sa seguridad ng ginagamit na functionality.

Alin sa mga bug na ito ang isang kahinaan sa seguridad na may $10000 na bounty? Para sa amin, ito ay karaniwang hindi mahalaga. Sa anumang software, lalo na sa intersection ng ilang mga bahagi, lalo na ang mga ibinigay ng iba't ibang mga proyekto at mga developer, walang sinuman ang makakagarantiya na ang lahat ng mga tampok ng kanilang trabaho ay kilala at dokumentado at walang mga error. Samakatuwid, ang anumang kahinaan sa seguridad ay nangyayari nang eksakto kung saan ito nakakaapekto sa seguridad.

Sa anumang kaso, magandang kasanayan na gawing normal o limitahan/i-filter hangga't maaari ang data ng input na napupunta sa anumang panlabas na module/API, maliban kung may tahasang mga tagubilin at malinaw na pag-unawa na hindi ito kinakailangan.

Erratum

Mula sa karanasan nakaraang artikulo, para sa kapakanan ng pagpapanatili ng kadalisayan ng wika:

bug bounty β€” kumpetisyon sa pangangaso ng bug
ulat ng bug - abiso ng error
pag-redirect - pag-redirect
open source - open source
nagkakamali - magtrabaho sa mga pagkakamali

Pinagmulan: www.habr.com

Magdagdag ng komento