PĂ«r njĂ« vulnerabilitet në 

PĂ«r njĂ« vulnerabilitet në 

Një vit më parë, më 21 mars 2019, në programin për gjetjen e gabimeve të Mail.Ru në HackerOne erdhi një raport shumë i mirë raporti i defekteve nga maxarr. Gjatë implementimit të bajtit zero (ASCII 0) në parametrin POST të një nga API-kërkesave të web-mailit, që ktheu një HTTP-redirect, në të dhënat e redirektimit u dukën fragmente të memories të pa inicializuara, ku shpesh shfaqeshin fragmentet nga parametrat GET dhe kreurat e kërkesave të tjera ndaj të njëjtit server.

Kjo është një vulnerabilitet kritik, pasi kërkesat përfshijnë gjithashtu cookie-t e sesionit. Pas disa orësh, u bë një rregullim temporary, që filtronte bajtin zero (siç u zbulua më pas, kjo ishte e pamjaftueshme, pasi mbeti mundësia e injektimit CRLF /ASCII 13, 10, e cila lejon manipulimin e të dhënave dhe kreuarve të HTTP- përgjigjeve, kjo është më pak kritike, por ende e pakëndshme). Në të njëjtën kohë, problemi iu transferua analistëve të sigurisë dhe zhvilluesve për të gjetur dhe eliminuar shkaqet e shfaqjes së gabimit.

Mail.ru është një aplikacion shumë kompleks, në formimin e përgjigjes mund të marrë pjesë një numër të madh komponentësh të ndryshëm frontend/backend, si komponentë open-source (falë shumë zhvilluesve të softuerit të lirë), ashtu edhe ata të zhvilluar vetë. Arriti të përjashtohet të gjithë komponentët përveç nginx dhe openresty dhe lokalizoi problemin deri në thirrjen ngx.req.set_uri() në skriptin OpenResty, i cili nuk u comportua siç pritej (nuk mund të futni bajtin zero ose vijën e re përmes parametrave GET me rewrite në ngx_http_rewrite_module, i cili, sipas dokumentacionit, përdoret dhe, duke u dukur, duhet të funksiononte njëlloj, nuk do të ndodhte). U eliminuan pasojat e mundshme, u shtua filtrimi më i rreptë dhe u kontrollua që filtrimi eliminon të gjitha vektoret e mundshëm. Por mekanizmi që çonte në rrjedhjen e përmbajtjes së memories mbeti një mister. Pas një muaji, raporti i gabimeve u mbyll si i zgjidhur, ndërsa analiza e shkaqeve të shfaqjes së gabimit u shty për më vonë.

OpenResty është një plugin shumë i njohur, që lejon të shkruhen skripta Lua brenda nginx, dhe ai përdoret në disa projekte të Mail.ru, prandaj problemi nuk konsiderohej i zgjidhur. Dhe pas një kohë, ata u kthyen përsëri në të për të kuptuar shkaqet e vërteta, pasojat e mundshme dhe për të përgatitur rekomandime për zhvilluesit. Në kërkimet e kodit burimor morën pjesë Denis Denisov dhe Nikolay Yermishkin. U zbulua se:

  • NĂ« nginx, kur pĂ«rdoren rewrite me tĂ« dhĂ«na tĂ« personalizuara, ekziston mundĂ«sia pĂ«r kalimin e drejtpĂ«rdrejtĂ« tĂ« drejtorive (dhe ndoshta SSRF) nĂ« disa konfiguracione, por kjo Ă«shtĂ« njĂ« fakt i njohur, dhe duhet tĂ« zbulohet nga analizat statike tĂ« konfiguracioneve nĂ« Nginx Amplify dhe Gixy nga Yandex (po, ne e pĂ«rdorim edhe atĂ«, faleminderit). Kur pĂ«rdoret OpenResty, mundĂ«sia lehtĂ« mund tĂ« shpĂ«rfillĂ«t, por konfigurimi ynĂ« nuk e prekte kĂ«tĂ«.

    shembuj konfigurimi:

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

    rezultati

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

  • NĂ« nginx ka njĂ« gabim qĂ« çon nĂ« rrjedhjen e pĂ«rmbajtjes sĂ« memories, nĂ«se vargu rewrite pĂ«rmban bajtin zero. Kur jep njĂ« redirect, nginx alokuar njĂ« buffer tĂ« ri memorie, qĂ« i pĂ«rgjigjet gjatĂ«si tĂ« plotĂ« tĂ« vargut, por kopjon aty vargun pĂ«rmes njĂ« funksioni tĂ« vargut, nĂ« tĂ« cilin bajti zero Ă«shtĂ« terminator i vargut, prandaj vargu kopjohet vetĂ«m deri nĂ« bajtin zero, pjesa tjetĂ«r e bufferit pĂ«rmban tĂ« dhĂ«na tĂ« pa inicializuara. NjĂ« analizĂ« tĂ« detajuar mund tĂ« gjendet kĂ«tu.

    shembuj konfigurimi (^@ bajti zero)

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

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

  • Nginx mbron parametrat GET nga injeksioni i simboleve speciale dhe lejon pĂ«rdorimin nĂ« rewrite vetĂ«m tĂ« parametrave GET. Prandaj, shfrytĂ«zimi i injeksionit pĂ«rmes parametrave tĂ« kontrolluar nga pĂ«rdoruesit nĂ« nginx nuk Ă«shtĂ« i mundur. Parametrat POST nuk janĂ« tĂ« mbrojtur. OpenResty lejon tĂ« punoni me tĂ« dy parametrat GET dhe POST, prandaj, duke pĂ«rdorur parametrat POST pĂ«rmes OpenResty, ekziston mundĂ«sia pĂ«r injeksionin e simboleve speciale.

    shembuj konfigurimi:

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

    rezultati:

    curl localhost:8337 -d "url=secret" -vv
    ...
    curl localhost:8337 -d "url=asdfasdfasdfasdfasdfasdfasdfasdf" -vv
    ...
    Location: http://localhost:8337/{...mund mundore secret...}
    ...

Reagimi i mëtejshëm

U njoftuan zhvilluesit e nginx dhe OpenResty për problemin, zhvilluesit nuk e konsiderojnë këtë problem si një gabim sigurie në nginx, pasi në vetë nginx nuk ka mundësi për të shfrytëzuar gabimin përmes injeksionit të simboleve speciale, rregullimi i rrjedhjes së përmbajtjes së memories u publikua më 16 dhjetor. Pas 4 muajve nga raportimi, në OpenResty gjithashtu nuk ishin bërë ndonjë ndryshim, megjithëse ishte e kuptueshme se nevojitet një variant i sigurt i funksionit ngx.req.set_uri(). Më 18 mars 2020, publikuan informacionin, më 21 mars OpenResty publikoi versionin 1.15.8.3, i cili shton kontrollin e URI.

Portswigger shkrova artikull të mirë dhe kam marrë komentet nga OpenResty dhe Nginx (përndryshe, komenti që tregohet vetëm një fragment i vogël i memories është i pasaktë dhe i mashtron, kjo përcaktohet nga gjatësia e vargut që ndjek byte-in zero dhe, në mungesë të kufizimeve të qarta mbi gjatësi, mund të kontrollohet nga sulmuesi).

Pra, ku qëndronte gabimi dhe çfarë të bëjmë për ta parandaluar atë?

A kishte gabim në nginx? Po, kishte, sepse rrjedhja e përmbajtjes së memories është në çdo rast një gabim.

A kishin gabim në OpenResty? Po, të paktën çështja e sigurisë së funksionalitetit të ofruar nga OpenResty nuk ishte hetuar dhe dokumentuar.

A ishte bërë një gabim konfigurimi / përdorimi në OpenResty? Po, sepse në mungesë të një indikacioni të qartë, ishte bërë një supozim i pa verifikuar mbi sigurinë e funksionalitetit të përdorur.

Cila nga këto gabime përbën një vulnerabilitet sigurie me një shpërblim prej $10000? Për ne, në thelb, kjo nuk ka rëndësi. Në çdo software, veçanërisht në ndërveprimin e disa komponenteve, sidomos të ofruara nga projekte dhe zhvillues të ndryshëm, askush nuk mund të garantojë se të gjitha karakteristikat e operimit të tyre janë të njohura dhe të dokumentuara dhe se nuk ka gabime. Prandaj, çdo vulnerabilitet sigurie shfaqet atje ku ndikon në siguri.

Në çdo rast, një praktikë e mirë do të ishte normalizimi ose maksimumi kufizimi / filtrimi i të dhënave hyrëse që dërgohen në çdo modul / API të jashtëm, nëse nuk ka indikacione të qarta dhe një kuptim të qartë se kjo nuk është e nevojshme.

Errata

Nga përvoja artikulli i mëparshëm, për të ruajtur pastërtinë e gjuhës:

bug bounty — garĂ« e gjetjes sĂ« gabimeve
raporti i defekteve — njoftimi pĂ«r njĂ« gabim
redirect — ridrejtim
open source — me kod burimi tĂ« hapur
errata — puna mbi gabimet

Burimi: habr.com

Bleni hostim tĂ« besueshĂ«m pĂ«r faqe me mbrojtje nga DDoS, serverĂ« VPS VDS đŸ”„ Bleni hostim tĂ« besueshĂ«m pĂ«r faqe me mbrojtje nga DDoS, serverĂ« VPS VDS | ProHoster