Egy sebezhetőségről a…

Egy sebezhetőségről a…

Egy évvel ezelőtt, 2019. március 21-én, a Mail.Ru bug bounty programja nagyon jó jelentést kapott a HackerOnén. hiba jelentés tól maxarr. A webmail egyik API-kérésének POST-paraméterében zéró bájt (ASCII 0) beillesztésekor a HTTP-átirányítási adatain belül inicializálatlan memória darabjai jelentek meg, amelyek gyakran GET-paraméterekből és más kérések fejlécéből származó töredékeket tartalmaztak, amelyek ugyanehhez a szerverhez irányultak.

Ez egy kritikus sebezhetőség, mivel a kérések tartalmazzák a munkamenet sütiket is. Néhány órán belül készítettek egy ideiglenes javítást, amely kiszűrte a zéró bájtot (ahogy később kiderült, ez nem volt elegendő, mivel fennmaradt a CRLF / ASCII 13, 10 befecskendezésének lehetősége, ami lehetővé tette a HTTP-válasz fejléceinek és adataival való manipulálást; ez kevésbé kritikus, de mégis kellemetlen). Ezzel egy időben a probléma a biztonsági elemzők és a fejlesztők figyelmébe került, hogy megtalálják és megszüntessék a hiba okait.

A Mail.ru levelezés egy nagyon bonyolult alkalmazás, amelyben a válasz előállításában számos különböző frontend/backend komponens vehet részt, mind nyílt forráskódú (nagy köszönet minden nyílt forráskódú fejlesztőnek), mind saját fejlesztésű. Minden komponenst sikerült kizárni, kivéve az nginx-t és az openresty-t, és a hibát a következő hívásra lokalizálni: ngx.req.set_uri() az OpenResty-szkriptben, amely nem úgy viselkedett, ahogyan várták (zéró bájt vagy új sor beillesztése a GET-paramétereken keresztül az ngx_http_rewrite_module észlelésében, amely, a dokumentáció szerint, használatban van és látszólag pontosan úgy kell működnie, ahogyan az elvárható). A lehetséges következményeket kizárták, maximálisan szigorú szűrést vezettek be, és ellenőrizték, hogy a szűrés minden lehetséges vektort kiiktat. De a memória tartalom szivárgását előidéző mechanizmus továbbra is rejtély maradt. Egy hónap múlva a hibajelentést a megoldott kategóriába sorolták, a hiba okának felderítése pedig később is váratott magára.

Az OpenResty egy nagyon népszerű plugin, amely lehetővé teszi Lua-szkriptek írását az nginx belsejében, és több Mail.ru projektben is használják, ezért a probléma nem számított megoldottnak. Néhány idő elteltével visszatértek a kérdéshez, hogy megértsék az igazi okokat, a lehetséges következményeket és ajánlásokat készítsenek a fejlesztők számára. A forráskód ásatásában részt vettek: Denis Denisov és Nyikolaj JermiskinKiderült, hogy:

  • Az nginx-nél a rewrite használatakor a felhasználói adatokkal bizonyos konfigurációkban lehetőség van könyvtárbejárásra (és valószínűleg SSRF-re) is, de ez ismert tény, és ezt a statikus konfiguráció-elemzőknek fel kellene fedezniük. Nginx Amplify és Gixy a Yandex-től (igen, mi is használjuk, köszönjük). Az OpenResty használatakor ezt könnyen figyelmen kívül lehet hagyni, de a mi konfigurációnkat ez nem érintette.

    példa konfiguráció:

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

    az eredményt

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

  • Az nginx-nél van egy hiba, amely memória tartalom szivárgásához vezet, ha a rewrite sor tartalmaz egy null byte-ot. A redirect kiszolgálásakor az nginx új memóriabuffert foglal el, amely megfelel a teljes sor hosszának, de a sort egy karakterlánc funkcióval másolja, amelyben a null byte a sor terminátora, így a sor csak a null byte-ig másolódik, a buffer maradéka inicializálatlan adatokat tartalmaz. Részletes elemzést találhat itt. itt.

    példa konfiguráció (^@ null byte)

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

    az eredményt
    curl localhost:8337/secret -vv
    ...
    curl localhost:8337/memleak -vv
    ...
    Hely: http://localhost:8337/secret
    ...

  • Az nginx védi a GET paramétereket a vezérlő karakterek injektálásától, és lehetővé teszi a rewrite-ban csak GET paraméterek használatát. Ezért az nginx-nél nem lehet kihasználni a felhasználó által vezérelt paraméterek injekcióját. Eközben a POST paraméterek nincsenek védve. Az OpenResty lehetővé teszi a GET és POST paraméterek használatát is, így az OpenResty használatakor a POST paraméterek esetében lehetőség van vezérlő karakterek injektálására.

    példa konfiguráció:

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

    eredmény:

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

További reakció

A problémáról értesítettük az nginx és OpenResty fejlesztőit, akik nem biztonsági hibaként kezelik a problémát az nginx-ban, mivel magában az nginx-ben nincs lehetőség a hiba kihasználására a vezérlő karakterek injektálásával, a fix a memória tartalom szivárgására december 16-án került publikálásra. A jelentést követő 4 hónapban az OpenResty-nél semmilyen változtatást nem hajtottak végre, bár tudták, hogy a ngx.req.set_uri() funkció biztonságosabb változata szükséges. 2020. március 18-án közzétettük az információt, március 21-én az OpenResty kiadta a 1.15.8.3 verziót, amely hozzáad egy URI ellenőrzést.

Portswigger írt jó cikket írt, és visszajelzést kért az OpenResty-től és a Nginx-től (bár a hibaüzenet, hogy csak egy kis memóriafragments részletezhető, téves és félrevezető, ezt a null-byte utáni sor hosszúságának hossza határozza meg, és a hosszúságra vonatkozó kifejezett korlátozások hiányában a támadó irányíthatja).

Mi volt a hiba, és mit tehetünk, hogy megelőzzük?

Volt hiba a nginx-ben? Igen, volt, mert a memória tartalmának szivárgása mindenképpen hiba.

Volt hiba az OpenResty-ben? Igen, legalábbis a biztonsági kérdések kutatása és dokumentálása nem történt meg az OpenResty által kínált funkciókkal kapcsolatban.

Volt-e konfigurációs / használati hiba az OpenResty-ben? Igen, mert a kifejezett irányítás hiánya miatt ellenőrizetlen feltételezést tettünk a használt funkciók biztonságáról.

Melyik az ezek közül a hibák közül biztonsági rés, amelyre $10000-os jutalom van? Számunkra ez lényegében nem fontos. Bármilyen szoftverben, különösen több összetevő határán, amelyek különböző projektek és fejlesztők által nyújtottak, senki és soha nem tudja garantálni, hogy minden működési jellemző ismert és dokumentált, és nincsenek hibák. Ezért bármilyen biztonsági rés éppen ott keletkezik, ahol az hatással van a biztonságra.

Bármilyen esetben jó gyakorlat, ha normalizáljuk vagy maximálisan korlátozzuk/filtráljuk a bemeneteket, amelyek bármilyen külső modulhoz/API-hoz kerülnek, ha nincsenek konkrét utasítások és egyértelmű megértés arról, hogy erre nincs szükség.

Errata

Tapasztalat alapján amely az előző cikkből származik., a nyelv tisztaságának megőrzése érdekében:

bug bounty — hibavadász verseny
hiba jelentés — hibaértesítés
redirect — átirányítás
nyílt forráskódú — nyílt forráskódú
errata — hiba javítás

Forrás: habr.com

Megbízható hosting vásárlása weboldalak számára, DDoS védelemmel, VPS VDS szerverek. 🔥 Megbízható webtárhely vásárlása DDoS védelemmel, VPS VDS szerverek | ProHoster