
Aasta tagasi, 21. mĂ€rtsil 2019, HackerOne'ile tuli vĂ€ga hea alates . Ăhe web-maili API-pĂ€ringu POST-parameetritesse nullbaiti (ASCII 0) sisestades ilmnes HTTP-ĂŒmber suunamise andmetes mitte-initsialiseeritud mĂ€lu osi, milles sageli ilmusid teistele pĂ€ringutele saadetud GET-parameetrite ja pĂ€iste killud, mis suundusid samale serverile.
See on kriitiline haavatavus, kuna pĂ€ringud sisaldavad ka sessioonikuki. MĂ”ne tunni pĂ€rast tehti ajutine lahendus, mis filtreeris nullbaiti (nagu hiljem selgus, oli seda ebapiisav, kuna jĂ€i vĂ”imalus CRLF / ASCII 13, 10 sisestamiseks, mis vĂ”imaldab HTTP-pealkirjade ja vastuse andmete manipuleerimist, see on vĂ€hem kriitiline, kuid siiski ebameeldiv). Samal ajal edastati probleem turvaanalĂŒĂŒtikutele ja arendajatele pĂ”hjuse vĂ€ljaselgitamiseks ja vea kĂ”rvaldamiseks.
Mail.ru post on vĂ€ga keeruline rakendus, mille vastamise vormimisel vĂ”ib osaleda suur hulk erinevaid frontend/backendi komponente, nii avatud lĂ€htekoodiga (suur tĂ€nu kĂ”ikidele vabatahtlike arendajatele) kui ka omatooted. Ănnestus vĂ€lja jĂ€tta kĂ”ik komponendid peale nginx ja openresty ning lokaliseerida probleem kuni vĂ€ljakutse OpenResty skriptis, mis ei kĂ€itunud ootuspĂ€raselt (nullbaiti vĂ”i reavahetuse sisestamine GET-parameetrite kaudu rewrite-s ngx_http_rewrite_module'i, mis vastavalt dokumentatsioonile kasutatakse ja peaks töötama tĂ€iesti samamoodi, ei Ă”nnestu). VĂ”imalikud tagajĂ€rjed kĂ”rvaldati, kasutusele vĂ”eti vĂ”imalikult range filtreerimine ning kontrolliti, et filtreerimine kĂ”rvaldab kĂ”ik vĂ”imalikud vektorid. Kuid mehanism, mis viis mĂ€lu sisu lekke tekkimiseni, jĂ€i endiselt mĂŒsteeriumiks. Kuu aja pĂ€rast suleti viga lahendatuks ja vea tekkimise pĂ”hjuste analĂŒĂŒs lĂŒkati edasi paremate aegade tarbeks.
OpenResty on populaarne plugin, mis vÔimaldab kirjutada Lua skripte nginx-s, ja seda kasutatakse mitmes Mail.ru projektis, mistÔttu probleemi ei peetud lahendatuks. Aja möödudes naaseti sellesse, et mÔista tÔelisi pÔhjuseid, vÔimalikud tagajÀrjed ja koostada soovitused arendajatele. Algkoodi uurimisse osalesid ja . Selgus, et:
- nginx-is, kui kasutatakse rewrite'i koos kohandatud andmetega, on vĂ”imalik directory traversal (vĂ”imalik, et ka SSRF) teatud konfigureerimiste korral, kuid see on tuntud fakt, ja seda peaksid avastama konfiguratsiooni staatilised analĂŒsaatorid ja Yandexist (jah, me kasutame seda ka, aitĂ€h). OpenResty kasutamisel on selline vĂ”imalus kergesti mööda lastav, kuid meie konfiguratsioon seda ei puudutanud.
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
... - Nginx'il on vigastus, mis pĂ”hjustab mĂ€lu lekkimist, kui rewrite rida sisaldab nullbaiti. Ămber suunamise korral eraldab nginx uue mĂ€lu puhversalviku, mis vastab kogu rea pikkusele, kuid kopeerib rea tĂŒhja funktsiooni kaudu, kus nullbitt on rea terminator, mistĂ”ttu rida kopeeritakse ainult nullbaiti kuni, ĂŒlejÀÀnud puhver sisaldab mitteinihiseeritud andmeid. Ăksikasjalik analĂŒĂŒs on saadaval .
konfiguratsiooni nÀide (^@ nullbitt)
location ~ /memleak { rewrite ^.*$ "^@asdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdasdf"; } location / { root html; index index.html index.htm; }tulemus
curl localhost:8337/secret -vv
...
curl localhost:8337/memleak -vv
...
Asukoht: http://localhost:8337/secret
...
- Nginx kaitseb GET parameetreid sĂŒmbolite sisestamise eest ja vĂ”imaldab rewrite'is kasutada ainult GET parameetreid. SeetĂ”ttu ei saa kasutaja mÀÀratud parameetrite kaudu nginx'is sisestamist Ă€ra kasutada. POST parameetrid ei ole samas kaitstud. OpenResty vĂ”imaldab töötada nii GET kui ka POST parameetritega, mistĂ”ttu OpenResty kaudu POST parameetrite kasutamisel tekib vĂ”imalus sisestada spetsiaalseid sĂŒmboleid.
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=salad" -vv
...
curl localhost:8337 -d "url=%00asdfasdfasdfasdfasdfasdfasdfasdf" -vv
...
Aadress: http://localhost:8337/{...vÔib sisaldada saladust...}
...
Edasi minev reaktsioon
Probleemi on teatanud Nginx'i ja OpenResty arendajad, kes ei pea seda probleemiks Nginx'is, kuna Nginx'is ei ole vĂ”imalust vea Ă€ra kasutamiseks spetsiaalsete mĂ€rkide sĂŒstimise kaudu, lahendus oli avaldatud 16. detsembril. Nelja kuu jooksul pĂ€rast raportit OpenResty's ei ole samuti tehtud mingeid muudatusi, kuigi oli arusaam, et vajalik on ohutum funktsiooni ngx.req.set_uri() variant. 18. mĂ€rtsil 2020 avaldasime teabe, 21. mĂ€rtsil avaldas OpenResty , mis lisab URI kontrolli.
Portswigger hea artikkel, millele sai tagasisidet OpenResty ja Nginx'ilt (kuid vĂ€ide, et avatakse vaid vĂ€ike mĂ€lufragment, on vale ja eksitav, see sĂ”ltub nullbaiti jĂ€rgnevast stringi pikkusest ja rikka piirangute puudumisel vĂ”ib seda juhtida rĂŒndaja).
Mis siis oli vale ja mida teha, et seda vÀltida?
Kas viga oli Nginx'is? Jah, oli, kuna mÀlu sisu leke on igal juhul viga.
Kas viga oli OpenResty's? Jah, vĂ€hemalt ei ole uuritud ja dokumenteeritud avatud OpenResty funktsionaalsuse turvalisuse kĂŒsimus.
Kas OpenResty konfiguratsioonis vÔi kasutamises oli viga? Jah, kuna selge viiteta tehti kontrollimata oletus kasutatava funktsionaalsuse turvalisuse kohta.
Milline neist vigadest on turvaaukus, mille pealt on $10000 preemia? Meie jaoks ei ole see pÔhimÔtteliselt oluline. Igas tarkvaras, eriti seal, kus on mitu komponenti, mis on pakutud erinevate projektide ja arendajate poolt, ei saa keegi kunagi garanteerida, et kÔik töövÔtted on teada, dokumenteeritud ja et vigu ei esine. SeetÔttu tekib iga turvavigastus seal, kus see mÔjutab turvalisust.
Igatahes on hea praktika normaliseerida vĂ”i vĂ”imalikult palju piirata/filtreerida sisendandmeid, mis suunduvad igasse vĂ€list moodulisse/API-sse, kui ei ole selgeid viiteid ja ĂŒheselt mĂ”istetavat arusaamist, et seda ei ole vajalik teha.
Errata
Kogemuse pÔhjal , keele puhtuse sÀilitamiseks:
bug bounty â vigade jahiks mĂ”eldud vĂ”istlus
bugiraport â vea teatis
suunamine â ĂŒmbersuunamine
avatud lĂ€htekoodiga â avatud koodiga
errata â vigade parandamine
Allikas: habr.com
