Napad na Node.js z manipulacijo prototipov objektov JavaScript

Raziskovalci Helmholtz Centra za informacijsko varnost (CISPA) in Kraljevega inštituta za tehnologijo (Švedska) so analizirali uporabnost tehnike onesnaževanja prototipa JavaScript za ustvarjanje napadov na platformo Node.js in priljubljene aplikacije, ki temeljijo na njej, kar vodi do izvajanja kode.

Metoda onesnaževanja prototipa uporablja funkcijo jezika JavaScript, ki vam omogoča dodajanje novih lastnosti korenskemu prototipu katerega koli predmeta. Aplikacije lahko vsebujejo kodne bloke (pripomočke), na katerih delovanje vpliva nadomeščena lastnost; koda lahko na primer vsebuje konstrukt, kot je 'const cmd = options.cmd || “/bin/sh”‘, katerega logika se bo spremenila, če napadalcu uspe nadomestiti lastnost “cmd” v korenskem prototipu.

Uspešen napad zahteva, da lahko aplikacija uporabi zunanje podatke za ustvarjanje nove lastnosti v korenskem prototipu objekta in ta izvedba naleti na pripomoček, ki je odvisen od spremenjene lastnosti. Spreminjanje prototipa je doseženo z obdelavo lastnosti storitve »__proto__« in »constructor« v Node.js. Lastnost "__proto__" vrne prototip razreda predmeta, lastnost "constructor" pa vrne funkcijo, uporabljeno za ustvarjanje predmeta.

Če koda aplikacije vsebuje dodelitev »obj[a][b] = vrednost« in so vrednosti nastavljene iz zunanjih podatkov, lahko napadalec nastavi »a« na vrednost »__proto__« in doseže namestitev lastne lastnosti z imenom »b« in vrednostjo »vrednost« v korenskem prototipu objekta (obj.__proto__.b = vrednost;), lastnost, nastavljena v prototipu, pa bo vidna v vseh objektih. Podobno, če koda vsebuje izraze, kot je »obj[a][b][c] = vrednost«, z nastavitvijo »a« na vrednost »konstruktor« in »b« na »prototip« v vseh obstoječih objektih, lahko definirajte novo lastnost z imenom "c" in vrednostjo "value".

Primer spreminjanja prototipa: const o1 = {}; const o2 = nov objekt(); o1.__proto__.x = 42; // ustvari lastnost “x” v korenskem prototipu console.log (o2.x); // dostop do lastnosti “x” iz drugega objekta // izhod bo 42, ker je bil korenski prototip spremenjen z objektom o1, ki se uporablja tudi v objektu o2

Primer ranljive kode: funkcija entryPoint (arg1, arg2, arg3){ const obj = {}; const p = obj[arg1]; p[arg2] = arg3; vrni p; }

Če so argumenti funkcije entryPoint oblikovani iz vhodnih podatkov, lahko napadalec posreduje vrednost »__proto__« arg1 in ustvari lastnost s poljubnim imenom v korenskem prototipu. Če posredujete arg2 vrednost "toString" in arg3 vrednost 1, lahko definirate lastnost "toString" (Object.prototype.toString=1) in zrušite aplikacijo med klicem toString().

Primeri situacij, ki bi lahko vodili do izvajanja kode napadalca, vključujejo ustvarjanje lastnosti "main", "shell", "exports", "contextExtensions" in "env". Napadalec lahko na primer ustvari "glavno" lastnost v korenskem prototipu predmeta in vanjo zapiše pot do svojega skripta (Object.prototype.main = "./../../pwned.js") in ta lastnost bo poklicana v času izvajanja v kodi konstrukta require("my-package"), če vključeni paket ne definira izrecno "main" lastnosti v package.json (če lastnost ni definirana, pridobljen bo iz korenskega prototipa). Lastnosti »shell«, »exports« in »env« je mogoče nadomestiti podobno: naj rootProto = Object.prototype; rootProto["exports"] = {".":"./changelog.js"}; rootProto["1"] = "/path/to/npm/scripts/"; // sproži klic require("./target.js"); Object.prototype.main = "/path/to/npm/scripts/changelog.js"; Object.prototype.shell = "vozlišče"; Object.prototype.env = {}; Object.prototype.env.NODE_OPTIONS = "—inspect-brk=0.0.0.0:1337"; // sproži klic require("bytes");

Raziskovalci so analizirali 10 paketov NPM z največjim številom odvisnosti in ugotovili, da jih 1958 nima glavne lastnosti v package.json, 4420 uporablja relativne poti v svojih zahtevanih izjavah, 355 pa neposredno uporablja API za zamenjavo ukazov.

Delujoč primer je izkoriščanje za napad na zaledje strežnika Parse Server, ki preglasi lastnost evalFunctions. Za poenostavitev prepoznavanja takšnih ranljivosti je bil razvit komplet orodij, ki združuje metode statične in dinamične analize. Med testiranjem Node.js je bilo identificiranih 11 pripomočkov, ki jih je mogoče uporabiti za organizacijo napadov, ki vodijo do izvedbe napadalčeve kode. Poleg strežnika Parse Server sta bili v NPM CLI identificirani tudi dve ranljivosti, ki ju je mogoče izkoristiti.

Vir: opennet.ru

Dodaj komentar