Gēlmholca informācijas drošības centra (CISPA) un Zviedrijas Karaliskā tehniskā institūta pētnieki ir analizējuši prototipa piesārņojuma paņēmiena pielietojamību JavaScript objektu uzbrukumiem Node.js platformai un populārām programmām, kas balstītas uz to, kas noved pie kodu izpildes.
Prototipa piesārņojuma metode izmanto JavaScript valodas īpatnību, kas ļauj pievienot jaunus īpašumus visiem objektu saknes prototipiem. Programmās var parādīties koda daļas (gadžeti), kuru darbību ietekmē nodrošinātais īpašums, piemēram, kodā var būt konstrukcija ‘const cmd = options.cmd || "/bin/sh"‘, un tās darbība tiks mainīta, ja uzbrucējs varēs iestatīt ‘cmd’ īpašumu saknes prototipā.
Lai veiksmīgi veiktu uzbrukumu, ir nepieciešams, lai programmā iekļautie ārējie dati varētu tikt izmantoti, lai izveidotu jaunu īpašumu objektu saknes prototipā, kā arī lai izpildes laikā būtu sastopams gadžets, kas ir atkarīgs no mainītā īpašuma. Prototipa maiņa tiek veikta, apstrādājot Node.js pakalpojuma īpašumus ‘__proto__’ un ‘constructor’. Īpašums ‘__proto__’ atgriež objekta klases prototipu, bet īpašums ‘constructor’ atgriež funkciju, kas tiek izmantota objekta izveidei.
Ja kodā sastopama piešķiršana ‘obj[a][b] = value’ un vērtības tiek iegūtas no ārējiem datiem, uzbrucējs var iestatīt ‘a’ uz ‘__proto__’ un panākt, ka viņa īpašums ar nosaukumu ‘b’ un vērtību ‘value’ tiek izveidots saknes prototipā (obj.__proto__.b = value;), šajā gadījumā izveidotais prototipa īpašums būs redzams visos objetos. Līdzīgi, ja kodā sastopama izteiksme ‘obj[a][b][c] = value’, iestatot ‘a’ uz ‘constructor’ un ‘b’ uz ‘prototype’, var izveidot jaunu īpašumu ar nosaukumu ‘c’ un vērtību ‘value’ visos esošajos objetos.
Prototipa maiņas piemērs: const o1 = {}; const o2 = new Object(); o1.__proto__.x = 42; // izveidojam saknes prototipa īpašumu ‘x’ console.log(o2.x); // piekļūstam īpašumam ‘x’ no cita objekta // rezultātā iegūsim 42, jo caur objektu o1 tika mainīts saknes prototips, kas tiek izmantots arī objektā o2.
Vulnerabla koda piemērs: function entryPoint(arg1, arg2, arg3){ const obj = {}; const p = obj[arg1]; p[arg2] = arg3; return p; }
Ja funkcijas entryPoint argumenti tiek veidoti no ievades datiem, uzbrucējs var nodot arg1 vērtību «__proto__» un izveidot saknes prototipā īpašību ar jebkuru nosaukumu. Ja arg2 tiek nodota vērtība «toString», bet arg3 — 1, var noteikt īpašību «toString» (Object.prototype.toString=1) un panākt programmas avāriju, kad tiek izsaukta funkcija toString().
Par piemēru situācijām, kas var novest pie uzbrucēja koda izpildes, ir iepriekš minētās īpašības «main», «shell», «exports», «contextExtensions» un «env». Piemēram, uzbrucējs var izveidot saknes prototipā objekta īpašību «main», ierakstot tajā ceļu uz savu skriptu (Object.prototype.main = «.\/..\/..\/pwned.js») un šī īpašība tiks izsaukta, kad tiks izpildīts kods, kurā ir konstrukcija require(«my-package»), ja iekļautais pakotnes nav noteicis package.json īpašību «main» (ja īpašība nav definēta, tā tiks iegūta no saknes prototipa). Līdzīgi var tikt ierakstītas īpašības «shell», «exports» un «env»: let rootProto = Object.prototype; rootProto[«exports»] = {«.»:«.\/changelog.js»}; rootProto[«1»] = «\/path\/to\/npm\/scripts\/»; \/\/ izsaukt izsaukumu require («.\/target.js»); Object.prototype.main = «\/path\/to\/npm\/scripts\/changelog.js»; Object.prototype.shell = «node»; Object.prototype.env = {}; Object.prototype.env.NODE_OPTIONS = «—inspect-brk=0.0.0.0:1337»; \/\/ izsaukt izsaukumu require («bytes»);
Pētnieki ir analizējuši 10 tūkstošus NPM pakotņu ar vislielāko atkarību skaitu un secinājuši, ka 1958 no tām nav īpašības main package.json, 4420 izmanto relatīvus ceļus, lai izsauktu require, un 355 tieši izmanto API, lai ievietotu komandas.
Kā funkcionālu piemēru var minēt eksplojītu uzbrukumu Parse Server aizmugurējai daļai, kas pārraksta evalFunctions īpašību. Lai atvieglotu līdzīgu ievainojamību noteikšanu, ir izstrādāts rīku komplekts, kas apvieno statiskās un dinamiskās analīzes metodes. Testējot Node.js, tika atrasti 11 izstrādājumi, kurus var izmantot, lai organizētu uzbrukumus, kas noved pie uzbrucēja koda izpildes. Papildus Parse Server divas eksploitējamas ievainojamības arī ir atklātas NPM CLI.
Avots: opennet.lv
