Forskare vid Helmholtz-centret för informationssÀkerhet (CISPA) och Kungliga tekniska högskolan (Sverige) har analyserat tillÀmpningen av tekniken för prototypförorening av JavaScript för att skapa attacker mot Node.js-plattformen och populÀra applikationer baserade pÄ den, vilket leder till kodexekvering.
Prototypsföroreningsmetoden anvĂ€nder en funktion av JavaScript-sprĂ„ket som gör att nya egenskaper kan lĂ€ggas till i den grundlĂ€ggande prototypen för vilket objekt som helst. I applikationer kan det finnas kodblock (widgets) vars funktion pĂ„verkas av den införda egenskapen, till exempel kan koden innehĂ„lla en konstruktion av typen âconst cmd = options.cmd || "/bin/sh"â, vars logik kommer att förĂ€ndras om angriparen lyckas införa egenskapen âcmdâ i den grundlĂ€ggande prototypen.
För att en attack ska lyckas krĂ€vs det att inkommande data i applikationen kan anvĂ€ndas för att skapa en ny egenskap i objektets grundlĂ€ggande prototyp, samt att det under körningen finns en widget som Ă€r beroende av den förĂ€ndrade egenskapen. Ăndringen av prototypen görs genom behandling av Node.js systemegenskaperna â__proto__â och âconstructorâ. Egenskapen â__proto__â returnerar prototypen för objektets klass, medan egenskapen âconstructorâ returnerar funktionen som anvĂ€nds för att skapa objektet.
Om koden i applikationen innehĂ„ller tilldelningen âobj[a][b] = valueâ och vĂ€rdena sĂ€tts frĂ„n externa data, kan angriparen sĂ€tta âaâ till vĂ€rdet â__proto__â och pĂ„ sĂ„ sĂ€tt fĂ„ sitt eget egenskap med namnet âbâ och vĂ€rdet âvalueâ i objektets grundlĂ€ggande prototyp (obj.__proto__.b = value;), dĂ€r den egenskap som sĂ€tts i prototypen kommer att synas i alla objekt. PĂ„ samma sĂ€tt, om koden innehĂ„ller uttryck av typen âobj[a][b][c] = valueâ, kan man sĂ€tta âaâ till vĂ€rdet âconstructorâ och âbâ till âprototypeâ för att definiera en ny egenskap med namnet âcâ och vĂ€rdet âvalueâ i alla existerande objekt.
Exempel pĂ„ Ă€ndring av prototypen: const o1 = {}; const o2 = new Object(); o1.__proto__.x = 42; // skapar egenskapen âxâ i den grundlĂ€ggande prototypen console.log(o2.x); // fĂ„r Ă„tkomst till egenskapen âxâ frĂ„n ett annat objekt // i utsignal fĂ„r vi 42, eftersom den grundlĂ€ggande prototypen Ă€ndrats genom objektet o1, Ă€ven anvĂ€nd i objektet o2
Exempel pÄ sÄrbar kod: function entryPoint(arg1, arg2, arg3){ const obj = {}; const p = obj[arg1]; p[arg2] = arg3; return p; }
Om argumenten för funktionen entryPoint genereras frÄn indata kan en angripare skicka vÀrdet «__proto__» i arg1 och skapa en egenskap med valfritt namn i rotprototypen. Om man skickar vÀrdet «toString» i arg2 och 1 i arg3 kan man definiera egenskapen «toString» (Object.prototype.toString=1) och Ästadkomma en krasch av applikationen vid anropet av funktionen toString().
Ett exempel pĂ„ situationer som kan leda till att kod frĂ„n angriparen körs Ă€r skapandet av egenskaperna «main», «shell», «exports», «contextExtensions» och «env». Till exempel kan en angripare skapa en egenskap «main» i rotprototypen för objektet genom att skriva in sökvĂ€gen till sin skript (Object.prototype.main = «. /.. /.. /pwned.js») och denna egenskap kommer att anropas vid körning av koden i konstruktionen require(«my-package»), om det anslutna paketet inte uttryckligen definierar egenskapen «main» i package.json (om egenskapen inte Ă€r definierad kommer den att hĂ€mtas frĂ„n rotprototypen). PĂ„ samma sĂ€tt kan egenskaperna «shell», «exports» och «env» infogas: let rootProto = Object.prototype; rootProto[«exports»] = {«.»:«./changelog.js»}; rootProto[«1»] = «/path/to/npm/scripts/»; // utlös anrop 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»; // utlös anrop require («bytes»);
Forskare har analyserat 10 000 NPM-paket med det högsta antalet beroenden och funnit att 1958 av dem saknar egenskapen main i package.json, 4420 anvÀnder relativa sökvÀgar i require-uttrycket, och 355 anvÀnder direkt API för att infoga kommandon.
Som ett fungerande exempel kan en exploatering för en attack pÄ backend för Parse Server nÀmnas, som omdefinierar egenskapen evalFunctions. För att underlÀtta identifieringen av sÄdana sÄrbarheter har ett verktyg utvecklats som kombinerar metoder för statisk och dynamisk analys. Under tester av Node.js identifierades 11 gadgets som kan anvÀndas för att utföra attacker som leder till att angriparkod körs. Förutom Parse Server har tvÄ utnyttjade sÄrbarheter ocksÄ identifierats i NPM CLI.
KĂ€lla: opennet.ru
