Attack mot Node.js genom manipulering av JavaScript-objektprototyper

Forskare från Helmholtz centrum för informationssäkerhet (CISPA) och Kungliga Tekniska Högskolan (Sverige) analyserade användbarheten av JavaScript-prototypens föroreningsteknik för att skapa attacker mot Node.js-plattformen och populära applikationer baserade på den, vilket ledde till kodexekvering.

Prototypföroreningsmetoden använder en funktion i JavaScript-språket som låter dig lägga till nya egenskaper till rotprototypen för vilket objekt som helst. Applikationer kan innehålla kodblock (gadgets) vars funktion påverkas av en ersatt egenskap, till exempel kan koden innehålla en konstruktion som 'const cmd = options.cmd || "/bin/sh"', vars logik kommer att ändras om angriparen lyckas ersätta "cmd"-egenskapen i rotprototypen.

En lyckad attack kräver att applikationen kan använda extern data för att skapa en ny egenskap i objektets rotprototyp, och att exekvering stöter på en gadget som beror på den modifierade egenskapen. Att ändra prototypen görs genom att bearbeta tjänsteegenskaperna "__proto__" och "constructor" i Node.js. Egenskapen "__proto__" returnerar prototypen för objektets klass, och egenskapen "constructor" returnerar funktionen som användes för att skapa objektet.

Om applikationskoden innehåller tilldelningen "obj[a][b] = värde" och värdena är inställda från externa data, kan en angripare ställa in "a" till värdet "__proto__" och få installationen av sin egen egenskap med namnet "b" och värdet "värde" i rotprototypen för objektet (obj.__proto__.b = värde;), och egenskapsuppsättningen i prototypen kommer att vara synlig i alla objekt. På liknande sätt, om koden innehåller uttryck som "obj[a][b][c] = värde", genom att ställa in "a" till "konstruktor"-värdet och "b" till "prototyp" i alla befintliga objekt, kan du definiera en ny egenskap med namnet "c" och värdet "värde".

Exempel på att ändra prototypen: const o1 = {}; const o2 = nytt objekt(); o1.__proto__.x = 42; // skapa egenskapen "x" i rotprototypen console.log (o2.x); // få tillgång till egenskapen "x" från ett annat objekt // utdata kommer att vara 42, eftersom rotprototypen ändrades genom objekt o1, som också används i objekt o2

Exempel på sårbar kod: function entryPoint (arg1, arg2, arg3){ const obj = {}; const p = obj[arg1]; p[arg2] = arg3; returnera p; }

Om entryPoint-funktionsargumenten bildas från indata kan en angripare skicka värdet "__proto__" till arg1 och skapa en egenskap med valfritt namn i rotprototypen. Om du skickar arg2 värdet "toString" och arg3 värdet 1, kan du definiera egenskapen "toString" (Object.prototype.toString=1) och krascha applikationen under anropet till toString().

Exempel på situationer som kan leda till exekvering av angriparkod inkluderar skapandet av egenskaperna "main", "shell", "exports", "contextExtensions" och "env". Till exempel kan en angripare skapa en "main" -egenskap i rotprototypen för ett objekt, skriva sökvägen till hans skript i den (Object.prototype.main = "./../../pwned.js") och den här egenskapen kommer att anropas vid tidpunkten för exekvering i koden för konstruktionen require("my-package"), om det inkluderade paketet inte uttryckligen definierar egenskapen "main" i package.json (om egenskapen inte är definierad, det kommer att erhållas från rotprototypen). Egenskaperna "skal", "export" och "env" kan ersättas på liknande sätt: let rootProto = Object.prototype; rootProto["exports"] = {".":"./changelog.js"}; rootProto["1"] = "/sökväg/till/npm/skript/"; // trigger call require("./target.js"); Object.prototype.main = "/sökväg/till/npm/scripts/changelog.js"; Object.prototype.shell = "nod"; Object.prototype.env = {}; Object.prototype.env.NODE_OPTIONS = "—inspect-brk=0.0.0.0:1337"; // trigger call require("bytes");

Forskarna analyserade 10 1958 NPM-paket med det största antalet beroenden och fann att 4420 355 av dem inte har en huvudegenskap i package.json, XNUMX XNUMX använder relativa sökvägar i sina require-satser och XNUMX använder direkt kommandosubstitutions-API:et.

Ett fungerande exempel är en exploatering för att attackera Parse Server-backend som åsidosätter egenskapen evalFunctions. För att förenkla identifieringen av sådana sårbarheter har en verktygslåda utvecklats som kombinerar statiska och dynamiska analysmetoder. Under testning av Node.js identifierades 11 gadgets som kan användas för att organisera attacker som leder till exekvering av angriparens kod. Förutom Parse Server identifierades även två exploateringsbara sårbarheter i NPM CLI.

Källa: opennet.ru

Lägg en kommentar