Напад на Node.js преку манипулација со прототипови на објекти на JavaScript

Истражувачите од Центарот за информациска безбедност на Хелмхолц (CISPA) и Кралскиот институт за технологија (Шведска) ја анализираа применливоста на техниката за загадување на прототипот на JavaScript за создавање напади на платформата Node.js и популарните апликации базирани на неа, што доведува до извршување на кодот.

Методот за загадување на прототипот користи карактеристика на јазикот JavaScript што ви овозможува да додадете нови својства на коренскиот прототип на кој било објект. Апликациите може да содржат кодни блокови (гаџети) чија работа е под влијание на заменето својство; на пример, кодот може да содржи конструкција како „const cmd = options.cmd || „/bin/sh“', чија логика ќе се промени доколку напаѓачот успее да го замени својството „cmd“ во коренскиот прототип.

Успешниот напад бара апликацијата да може да користи надворешни податоци за да создаде нова сопственост во прототипот на коренот на објектот и дека извршувањето ќе наиде на гаџет што зависи од модифицираното својство. Промената на прототипот се постигнува со обработка на својствата на услугата „__proto__“ и „конструктор“ во Node.js. Својството „__proto__“ го враќа прототипот на класата на објектот, а својството „конструктор“ ја враќа функцијата користена за креирање на објектот.

Ако кодот на апликацијата ја содржи задачата „obj[a][b] = вредност“ и вредностите се поставени од надворешни податоци, напаѓачот може да постави „a“ на вредноста „__proto__“ и да постигне инсталирање на сопствената сопственост со името „b“ и вредноста „вредност“ во коренскиот прототип на објектот (obj.__proto__.b = вредност;), а својството поставено во прототипот ќе биде видливо во сите објекти. Слично, ако кодот содржи изрази како „obj[a][b][c] = вредност“, со поставување на „a“ на вредноста „конструктор“ и „b“ на „прототип“ во сите постоечки објекти, можете да дефинирајте ново својство со името „c“ и вредноста „вредност“.

Пример за промена на прототипот: const o1 = {}; const o2 = нов објект(); o1.__proto__.x = 42; // креирајте својство „x“ во root прототипот конзола.log (o2.x); // пристап до својството „x“ од друг објект // излезот ќе биде 42, бидејќи коренскиот прототип е променет преку објектот o1, кој исто така се користи во објектот o2

Пример за ранлив код: функција entryPoint (arg1, arg2, arg3){ const obj = {}; const p = obj[arg1]; p[arg2] = arg3; врати p; }

Ако аргументите на функцијата entryPoint се формираат од влезните податоци, тогаш напаѓачот може да ја пренесе вредноста „__proto__“ на arg1 и да создаде својство со кое било име во прототипот на root. Ако ја предадете arg2 вредноста „toString“ и arg3 вредноста 1, можете да го дефинирате својството „toString“ (Object.prototype.toString=1) и да ја скршите апликацијата за време на повикот до toString().

Примери на ситуации кои би можеле да доведат до извршување на кодот на напаѓачот вклучуваат создавање на својствата "главна", "школка", "извоз", "contextExtensions" и "env". На пример, напаѓачот може да создаде својство „главно“ во коренскиот прототип на објектот, пишувајќи во него патеката до неговата скрипта (Object.prototype.main = „./../../pwned.js“) и ова својство ќе биде повикано во моментот на извршување во кодот на конструкцијата бара („my-package“), доколку вклучениот пакет не ја дефинира експлицитно „главната“ сопственост во package.json (ако својството не е дефинирано, ќе се добие од коренскиот прототип). Својствата „shell“, „exports“ и „env“ може да се заменат слично: нека rootProto = Object.prototype; rootProto["exports"] = {".":"./changelog.js"}; rootProto["1"] = "/path/to/npm/scripts/"; // повик за активирање бара("./target.js"); Object.prototype.main = "/path/to/npm/scripts/changelog.js"; Object.prototype.shell = "јазол"; Object.prototype.env = {}; Object.prototype.env.NODE_OPTIONS = "—inspect-brk=0.0.0.0:1337"; // Потребен е повик за активирање ("бајти");

Истражувачите анализирале 10 NPM пакети со најголем број на зависности и откриле дека 1958 од нив немаат главно својство во package.json, 4420 користат релативни патеки во нивните барања, а 355 директно го користат API за замена на команди.

Работен пример е експлоатација за напад на заднината на серверот Parse која го отфрла својството evalFunctions. За да се поедностави идентификацијата на таквите пропусти, развиен е пакет со алатки што комбинира статички и динамички методи на анализа. За време на тестирањето на Node.js, беа идентификувани 11 гаџети кои можат да се користат за организирање напади што водат до извршување на кодот на напаѓачот. Покрај серверот за анализирање, две експлоатирачки пропусти беа исто така идентификувани во NPM CLI.

Извор: opennet.ru

Додадете коментар