Атака Π½Π° Node.js Ρ‡Ρ€Π΅Π· ΠΌΠ°Π½ΠΈΠΏΡƒΠ»Π°Ρ†ΠΈΠΈ с ΠΏΡ€ΠΎΡ‚ΠΎΡ‚ΠΈΠΏΠΈΡ‚Π΅ Π½Π° JavaScript ΠΎΠ±Π΅ΠΊΡ‚ΠΈ

Π˜Π·ΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΠΈ ΠΎΡ‚ Π¦Π΅Π½Ρ‚ΡŠΡ€Π° Π·Π° ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΎΠ½Π½Π° сигурност Π½Π° Π“Π΅Π»ΠΌΡ…ΠΎΠ»Ρ† (CISPA) ΠΈ ШвСдския Ρ‚Π΅Ρ…Π½ΠΎΠ»ΠΎΠ³ΠΈΡ‡Π΅Π½ институт Π°Π½Π°Π»ΠΈΠ·ΠΈΡ€Π°Ρ…Π° прилоТимостта Π½Π° Ρ‚Π΅Ρ…Π½ΠΈΠΊΠ°Ρ‚Π° Π·Π° Π·Π°ΠΌΡŠΡ€ΡΡΠ²Π°Π½Π΅ Π½Π° ΠΏΡ€ΠΎΡ‚ΠΎΡ‚ΠΈΠΏΠΈ Π½Π° JavaScript (β€žprototype pollutionβ€œ) Π·Π° ΠΎΡΡŠΡ‰Π΅ΡΡ‚Π²ΡΠ²Π°Π½Π΅ Π½Π° Π°Ρ‚Π°ΠΊΠΈ срСщу ΠΏΠ»Π°Ρ‚Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π° Node.js ΠΈ популярни прилоТСния, ΠΈΠ·Π³Ρ€Π°Π΄Π΅Π½ΠΈ Π½Π° Π½Π΅ΠΉΠ½Π°Ρ‚Π° основа, ΠΊΠΎΠ΅Ρ‚ΠΎ Π²ΠΎΠ΄ΠΈ Π΄ΠΎ изпълнСниС Π½Π° ΠΊΠΎΠ΄.

ΠœΠ΅Ρ‚ΠΎΠ΄ΡŠΡ‚ Π·Π° Π·Π°ΠΌΡŠΡ€ΡΡΠ²Π°Π½Π΅ Π½Π° ΠΏΡ€ΠΎΡ‚ΠΎΡ‚ΠΈΠΏΠ° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° особСност Π½Π° Π΅Π·ΠΈΠΊΠ° JavaScript, която позволява добавянСто Π½Π° Π½ΠΎΠ²ΠΈ свойства Π² корСнния ΠΏΡ€ΠΎΡ‚ΠΎΡ‚ΠΈΠΏ Π½Π° всякакъв ΠΎΠ±Π΅ΠΊΡ‚. Π’ прилоТСния ΠΌΠΎΠ³Π°Ρ‚ Π΄Π° сС срСщат Π±Π»ΠΎΠΊΠΎΠ²Π΅ ΠΊΠΎΠ΄ (Π³Π°Π΄ΠΆΠ΅Ρ‚ΠΈ), Π½Π° ΠΊΠΎΠΈΡ‚ΠΎ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚Π° ΠΈΠΌ влияС Π΄ΠΎΠ±Π°Π²Π΅Π½ΠΎΡ‚ΠΎ свойство, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π² ΠΊΠΎΠ΄Π° ΠΌΠΎΠΆΠ΅ Π΄Π° ΠΈΠΌΠ° конструкция ΠΎΡ‚ Π²ΠΈΠ΄Π° 'const cmd = options.cmd || "/bin/sh"', Π»ΠΎΠ³ΠΈΠΊΠ°Ρ‚Π° Π½Π° която Ρ‰Π΅ бъдС ΠΏΡ€ΠΎΠΌΠ΅Π½Π΅Π½Π°, Π°ΠΊΠΎ нападатСлят успСС Π΄Π° Π²Π½Π΅Π΄Ρ€ΠΈ свойството 'cmd' Π² корСнния ΠΏΡ€ΠΎΡ‚ΠΎΡ‚ΠΈΠΏ.

Π—Π° ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎΡ‚ΠΎ ΠΎΡΡŠΡ‰Π΅ΡΡ‚Π²ΡΠ²Π°Π½Π΅ Π½Π° Π°Ρ‚Π°ΠΊΠ° Π΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π² ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ ΠΏΠΎΡΡ‚ΡŠΠΏΠ²Π°Ρ‰ΠΈΡ‚Π΅ ΠΎΡ‚ външни ΠΈΠ·Ρ‚ΠΎΡ‡Π½ΠΈΡ†ΠΈ Π΄Π°Π½Π½ΠΈ Π΄Π° ΠΌΠΎΠ³Π°Ρ‚ Π΄Π° сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚ Π·Π° създаванС Π½Π° Π½ΠΎΠ²ΠΎ свойство Π² корСнния ΠΏΡ€ΠΎΡ‚ΠΎΡ‚ΠΈΠΏ Π½Π° ΠΎΠ±Π΅ΠΊΡ‚Π°, ΠΊΠ°ΠΊΡ‚ΠΎ ΠΈ ΠΏΠΎ Π²Ρ€Π΅ΠΌΠ΅ Π½Π° изпълнСниС Π΄Π° сС срСща Π³Π°Π΄ΠΆΠ΅Ρ‚, зависСщ ΠΎΡ‚ ΠΏΡ€ΠΎΠΌΠ΅Π½Π΅Π½ΠΎΡ‚ΠΎ свойство. ΠŸΡ€ΠΎΠΌΡΠ½Π°Ρ‚Π° Π½Π° ΠΏΡ€ΠΎΡ‚ΠΎΡ‚ΠΈΠΏΠ° сС ΠΎΡΡŠΡ‰Π΅ΡΡ‚Π²ΡΠ²Π° Ρ‡Ρ€Π΅Π· ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° Π² Node.js Π½Π° слуТСбнитС свойства '.__proto__' ΠΈ '.constructor'. Бвойството '.__proto__' Π²Ρ€ΡŠΡ‰Π° ΠΏΡ€ΠΎΡ‚ΠΎΡ‚ΠΈΠΏΠ° Π½Π° класа Π½Π° ΠΎΠ±Π΅ΠΊΡ‚Π°, Π΄ΠΎΠΊΠ°Ρ‚ΠΎ свойството '.constructor' Π²Ρ€ΡŠΡ‰Π° функцията, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π° Π·Π° ΡΡŠΠ·Π΄Π°Π²Π°Π½Π΅Ρ‚ΠΎ Π½Π° ΠΎΠ±Π΅ΠΊΡ‚Π°.

Ако Π² ΠΊΠΎΠ΄Π° Π½Π° ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ сС срСща присвояванС 'obj[a][b] = value' ΠΈ стойноститС сС ΠΈΠ·Π²Π΅ΠΆΠ΄Π°Ρ‚ ΠΎΡ‚ външни Π΄Π°Π½Π½ΠΈ, нападатСлят ΠΌΠΎΠΆΠ΅ Π΄Π° Π·Π°Π΄Π°Π΄Π΅ 'a' Π½Π° стойност '.__proto__' ΠΈ Π΄Π° осигури ΡΡŠΠ·Π΄Π°Π²Π°Π½Π΅Ρ‚ΠΎ Π½Π° своС собствСно свойство с ΠΈΠΌΠ΅ 'b' ΠΈ стойност 'value' Π² корСнния ΠΏΡ€ΠΎΡ‚ΠΎΡ‚ΠΈΠΏ Π½Π° ΠΎΠ±Π΅ΠΊΡ‚Π° (obj.__proto__.b = value;), ΠΈ Π·Π°Π΄Π°Π΄Π΅Π½ΠΎΡ‚ΠΎ Π² ΠΏΡ€ΠΎΡ‚ΠΎΡ‚ΠΈΠΏΠ° свойство Ρ‰Π΅ бъдС Π²ΠΈΠ΄ΠΈΠΌΠΎ във всички ΠΎΠ±Π΅ΠΊΡ‚ΠΈ. Подобно, Π°ΠΊΠΎ Π² ΠΊΠΎΠ΄Π° сС срСщат ΠΈΠ·Ρ€Π°Π·ΠΈ ΠΎΡ‚ Π²ΠΈΠ΄Π° 'obj[a][b][c] = value', Π·Π°Π΄Π°Π²Π°ΠΉΠΊΠΈ 'a' Π½Π° стойност '.constructor' ΠΈ 'b' Π½Π° 'prototype', ΠΌΠΎΠΆΠ΅ Π΄Π° сС ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈ Π½ΠΎΠ²ΠΎ свойство с ΠΈΠΌΠ΅ 'c' ΠΈ стойност 'value'.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ Π·Π° промяна Π½Π° ΠΏΡ€ΠΎΡ‚ΠΎΡ‚ΠΈΠΏΠ°: const o1 = {}; const o2 = new Object(); o1.__proto__.x = 42; // създавамС Π² корСнния ΠΏΡ€ΠΎΡ‚ΠΎΡ‚ΠΈΠΏ свойство 'x' console.log(o2.x); // ΠΏΠΎΠ»ΡƒΡ‡Π°Π²Π°ΠΌΠ΅ Π΄ΠΎΡΡ‚ΡŠΠΏ Π΄ΠΎ свойството 'x' ΠΎΡ‚ Π΄Ρ€ΡƒΠ³ ΠΎΠ±Π΅ΠΊΡ‚ // Π½Π° ΠΈΠ·Ρ…ΠΎΠ΄Π° Ρ‰Π΅ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠΌ 42, Ρ‚ΡŠΠΉ ΠΊΠ°Ρ‚ΠΎ корСнният ΠΏΡ€ΠΎΡ‚ΠΎΡ‚ΠΈΠΏ, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½ Π² ΠΎΠ±Π΅ΠΊΡ‚Π° o2, Π΅ ΠΏΡ€ΠΎΠΌΠ΅Π½Π΅Π½ Ρ‡Ρ€Π΅Π· ΠΎΠ±Π΅ΠΊΡ‚ o1.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ Π·Π° уязвим ΠΊΠΎΠ΄: function entryPoint(arg1, arg2, arg3) { const obj = {}; const p = obj[arg1]; p[arg2] = arg3; return p; }

Ако Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΈΡ‚Π΅ Π½Π° функцията entryPoint сС Ρ„ΠΎΡ€ΠΌΠΈΡ€Π°Ρ‚ ΠΎΡ‚ входящи Π΄Π°Π½Π½ΠΈ, атакуващият ΠΌΠΎΠΆΠ΅ Π΄Π° ΠΏΡ€Π΅Π΄Π°Π΄Π΅ Π² arg1 стойността Β«__proto__Β» ΠΈ Π΄Π° създадС Π² корСновия ΠΏΡ€ΠΎΡ‚ΠΎΡ‚ΠΈΠΏ свойство с ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»Π½ΠΎ ΠΈΠΌΠ΅. Ако Π² arg2 сС ΠΏΡ€Π΅Π΄Π°Π΄Π΅ стойност Β«toStringΒ», Π° Π² arg3 β€” 1, ΠΌΠΎΠΆΠ΅ Π΄Π° сС ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈ свойството Β«toStringΒ» (Object.prototype.toString=1) ΠΈ Π΄Π° сС ΠΏΡ€Π΅Π΄ΠΈΠ·Π²ΠΈΠΊΠ° срив Π½Π° ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ ΠΏΠΎ Π²Ρ€Π΅ΠΌΠ΅ Π½Π° ΠΈΠ·Π²ΠΈΠΊΠ²Π°Π½Π΅Ρ‚ΠΎ Π½Π° функцията toString().

ΠšΠ°Ρ‚ΠΎ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Π·Π° ситуации, ΠΊΠΎΠΈΡ‚ΠΎ ΠΌΠΎΠ³Π°Ρ‚ Π΄Π° Π΄ΠΎΠ²Π΅Π΄Π°Ρ‚ Π΄ΠΎ изпълнСниС Π½Π° ΠΊΠΎΠ΄ ΠΎΡ‚ атакуващия, сС Π΄Π°Π²Π° създаванС Π½Π° свойства Β«mainΒ», Β«shellΒ», Β«exportsΒ», Β«contextExtensionsΒ» ΠΈ Β«envΒ». НапримСр, атакуващият ΠΌΠΎΠΆΠ΅ Π΄Π° създадС Π² корСновия ΠΏΡ€ΠΎΡ‚ΠΎΡ‚ΠΈΠΏ Π½Π° ΠΎΠ±Π΅ΠΊΡ‚Π° свойството Β«mainΒ», записвайки Π² Π½Π΅Π³ΠΎ ΠΏΡŠΡ‚Ρ Π΄ΠΎ своя скрипт (Object.prototype.main = Β«.\/..\/..\/pwned.jsΒ») ΠΈ Ρ‚ΠΎΠ²Π° свойство Ρ‰Π΅ бъдС ΠΈΠ·Π²ΠΈΠΊΠ°Π½ΠΎ Π² ΠΌΠΎΠΌΠ΅Π½Ρ‚Π° Π½Π° ΠΈΠ·ΠΏΡŠΠ»Π½Π΅Π½ΠΈΠ΅Ρ‚ΠΎ Π½Π° ΠΊΠΎΠ΄Π° с конструкцията require(Β«my-packageΒ»), Π°ΠΊΠΎ ΡΠ²ΡŠΡ€Π·Π°Π½ΠΈΡΡ‚ ΠΏΠ°ΠΊΠ΅Ρ‚ Π½Π΅ опрСдСля явно Π² package.json свойството Β«mainΒ» (Π°ΠΊΠΎ свойството Π½Π΅ Π΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΎ, Ρ‚ΠΎ Ρ‰Π΅ бъдС ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΎ ΠΎΡ‚ корСновия ΠΏΡ€ΠΎΡ‚ΠΎΡ‚ΠΈΠΏ). Аналогично ΠΌΠΎΠ³Π°Ρ‚ Π΄Π° Π±ΡŠΠ΄Π°Ρ‚ ΠΏΠΎΠ΄ΠΌΠ΅Π½Π΅Π½ΠΈ свойствата Β«shellΒ», Β«exportsΒ» ΠΈ Β«envΒ»: let rootProto = Object.prototype; rootProto[Β«exportsΒ»] = {Β«.Β»:Β«.\/changelog.jsΒ»}; rootProto[Β«1Β»] = Β«\/path\/to\/npm\/scripts\/Β»; \/\/ Ρ‚Ρ€ΠΈΠ³Π΅Ρ€ Π·Π° ΠΈΠ·Π²ΠΈΠΊΠ²Π°Π½Π΅ 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Β»; \/\/ Ρ‚Ρ€ΠΈΠ³Π΅Ρ€ Π·Π° ΠΈΠ·Π²ΠΈΠΊΠ²Π°Π½Π΅ require (Β«bytesΒ»);

Π˜Π·ΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΠΈΡ‚Π΅ Π°Π½Π°Π»ΠΈΠ·ΠΈΡ€Π°Ρ…Π° 10 000 NPM ΠΏΠ°ΠΊΠ΅Ρ‚Π° с Π½Π°ΠΉ-ΠΌΠ½ΠΎΠ³ΠΎ зависимости ΠΈ установиха, Ρ‡Π΅ 1958 ΠΎΡ‚ тях нямат свойство main Π² package.json, 4420 ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚ относитСлни ΠΏΡŠΡ‚ΠΈΡ‰Π° Π² ΠΈΠ·Ρ€Π°Π·Π° require, Π° 355 Π΄ΠΈΡ€Π΅ΠΊΡ‚Π½ΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚ API Π·Π° подмяна Π½Π° ΠΊΠΎΠΌΠ°Π½Π΄ΠΈ.

ΠšΠ°Ρ‚ΠΎ Ρ€Π°Π±ΠΎΡ‚Π΅Ρ‰ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ΠΌΠΎΠΆΠ΅ Π΄Π° сС Π΄Π°Π΄Π΅ Сксплойт Π·Π° Π°Ρ‚Π°ΠΊΠ° Π½Π° Π±Π΅ΠΊΠ΅Π½Π΄Π° Π½Π° Parse Server, ΠΊΠΎΠΉΡ‚ΠΎ прСопрСдСля свойството evalFunctions. Π—Π° улСсняванС Π½Π° ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΡ†ΠΈΡ€Π°Π½Π΅ Π½Π° ΠΏΠΎΠ΄ΠΎΠ±Π½ΠΈ уязвимости Π΅ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Π΅Π½ инструмСнтариум, ΠΊΠΎΠΌΠ±ΠΈΠ½ΠΈΡ€Π°Ρ‰ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΈ Π½Π° статичСн ΠΈ Π΄ΠΈΠ½Π°ΠΌΠΈΡ‡Π΅Π½ Π°Π½Π°Π»ΠΈΠ·. ΠŸΡ€ΠΈ тСстванС Π½Π° Node.js бяха ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΡ†ΠΈΡ€Π°Π½ΠΈ 11 Π³Π°Π΄ΠΆΠ΅Ρ‚Π°, ΠΊΠΎΠΈΡ‚ΠΎ ΠΌΠΎΠ³Π°Ρ‚ Π΄Π° Π±ΡŠΠ΄Π°Ρ‚ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½ΠΈ Π·Π° ΠΎΡ€Π³Π°Π½ΠΈΠ·ΠΈΡ€Π°Π½Π΅ Π½Π° Π°Ρ‚Π°ΠΊΠΈ, Π²ΠΎΠ΄Π΅Ρ‰ΠΈ Π΄ΠΎ изпълнСниС Π½Π° ΠΊΠΎΠ΄Π° Π½Π° атакуващия. ОсвСн Parse Server, Π΄Π²Π΅ Сксплоатиращи уязвимости ΡΡŠΡ‰ΠΎ бяха установСни Π² NPM CLI.

Π˜Π·Ρ‚ΠΎΡ‡Π½ΠΈΠΊ: opennet.ru

ΠšΡƒΠΏΠ΅Ρ‚Π΅ Π½Π°Π΄Π΅ΠΆΠ΄Π΅Π½ хостинг Π·Π° сайтовС със Π·Π°Ρ‰ΠΈΡ‚Π° ΠΎΡ‚ DDoS, VPS ΠΈ VDS ΡΡŠΡ€Π²ΡŠΡ€ΠΈ πŸ”₯ ΠšΡƒΠΏΠ΅Ρ‚Π΅ Π½Π°Π΄Π΅ΠΆΠ΄Π΅Π½ хостинг Π·Π° сайтовС със Π·Π°Ρ‰ΠΈΡ‚Π° ΠΎΡ‚ DDoS, VPS ΠΈ VDS ΡΡŠΡ€Π²ΡŠΡ€ΠΈ | ProHoster