Атака Π½Π° 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, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ Ρ‡Π΅Ρ€Π΅Π· ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ o1 Π±Ρ‹Π» ΠΈΠ·ΠΌΠ΅Π½Ρ‘Π½ ΠΊΠΎΡ€Π½Π΅Π²ΠΎΠΉ ΠΏΡ€ΠΎΡ‚ΠΎΡ‚ΠΈΠΏ, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹ΠΉ Π² Ρ‚ΠΎΠΌ числС ΠΈ Π² ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π΅ o2

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ уязвимого ΠΊΠΎΠ΄Π°: 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/»; // trigger call 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»; // trigger call require («bytes»);

Π˜ΡΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΠΈ ΠΏΡ€ΠΎΠ°Π½Π°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π»ΠΈ 10 тысяч NPM-ΠΏΠ°ΠΊΠ΅Ρ‚ΠΎΠ², ΠΈΠΌΠ΅ΡŽΡ‰ΠΈΡ… наибольшСС число зависимостСй, ΠΈ выявили, Ρ‡Ρ‚ΠΎ 1958 ΠΈΠ· Π½ΠΈΡ… Π½Π΅ ΠΈΠΌΠ΅ΡŽΡ‚ свойства main Π² package.json, 4420 ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ ΠΏΡƒΡ‚ΠΈ Π² Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠΈ require, Π° 355 Π½Π°ΠΏΡ€ΡΠΌΡƒΡŽ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ API для подстановки ΠΊΠΎΠΌΠ°Π½Π΄.

Π’ качСствС Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‰Π΅Π³ΠΎ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° ΠΌΠΎΠΆΠ½ΠΎ привСсти эксплоит для Π°Ρ‚Π°ΠΊΠΈ Π½Π° бэкСнд Parse Server, ΠΏΠ΅Ρ€Π΅ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΡŽΡ‰ΠΈΠΉ свойство evalFunctions. Для упрощСния выявлСния ΠΏΠΎΠ΄ΠΎΠ±Π½Ρ‹Ρ… уязвимостСй Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Π°Π½ инструмСнтарий, ΠΊΠΎΠΌΠ±ΠΈΠ½ΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΉ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ статичСского ΠΈ динамичСского Π°Π½Π°Π»ΠΈΠ·Π°. Π’ Ρ…ΠΎΠ΄Π΅ тСстирования Node.js Π±Ρ‹Π»ΠΎ выявлСно 11 Π³Π°Π΄ΠΆΠ΅Ρ‚ΠΎΠ², ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ для ΠΎΡ€Π³Π°Π½ΠΈΠ·Π°Ρ†ΠΈΠΈ Π°Ρ‚Π°ΠΊ, приводящих ΠΊ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΡŽ ΠΊΠΎΠ΄Π° Π°Ρ‚Π°ΠΊΡƒΡŽΡ‰Π΅Π³ΠΎ. Помимо Parse Server, Π΄Π²Π΅ эксплуатируСмыС уязвимости Ρ‚Π°ΠΊΠΆΠ΅ Π±Ρ‹Π»ΠΈ выявлСны Π² NPM CLI.

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

Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΉ