![]() |
Исследователи Центра Гельмгольца по информационной безопасности (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". Пример изменения прототипа: Код:
Code:Код:
Code:В качестве примера ситуаций, которые могут привести к выполнению кода атакующего, приводится создание свойств "main", "shell", "exports", "contextExtensions" и "env". Например, атакующий может создать в корневом прототипе объекта свойство "main", записав в него путь к своему скрипту (Object.prototype.main = "./../../pwned.js") и данное свойство будет вызвано в момент выполнения в коде конструкции require("my-package"), если подключаемый пакет явно не определяет в package.json свойство "main" (если свойство не определено, оно будет получено из корневого прототипа). Аналогично могут быть подставлены свойства "shell", "exports" и "env": Код:
Code:В качестве работающего примера можно привести эксплоит для атаки на бэкенд Parse Server, переопределяющий свойство evalFunctions. Для упрощения выявления подобных уязвимостей разработан инструментарий, комбинирующий методы статического и динамического анализа. В ходе тестирования Node.js было выявлено 11 гаджетов, которые можно использовать для организации атак, приводящих к выполнению кода атакующего. Помимо Parse Server, две эксплуатируемые уязвимости также были выявлены в NPM CLI. |
| Время: 22:04 |