![](https://habrastorage.org/getpro/habr/upload_files/a06/476/c7b/a06476c7bc422bfe660c16c238ec5c7e.jpg)
В рамках данной статьи мы рассмотрим уязвимость Prototype Pollution на клиенте и AST-injection на сервере и то, к чему может привести их совместная эксплуатация, а также, как они были встроены для обучения в конкурс “Hack To Be Hired” на ZeroNights X от Академии Digital Security.
Всем желающим познакомиться с подробными механизмами уязвимостей и как их взаимодействие может привести к RCE на сервере — приветствуем!
Как я встретил “Вашу маму”
История началась с того, что на очередном аудите я обнаружил уязвимость с интересным для меня тогда названием — Prototype Pollution. В целом я понимал, что эта уязвимость связана с прототипом именно в JavaScript, так как в других языках программирования я не встречал данного слова ну и самого прототипа тоже. Но что именно с ним происходит не так, и как вообще происходит загрязнение нашего прототипа, для меня оставались загадкой, которую я хотел решить.
![Критический уровень уязвимости Prototype Pollution Критический уровень уязвимости Prototype Pollution](https://habrastorage.org/getpro/habr/upload_files/6a0/bc1/e23/6a0bc1e2303bcee718a03f0988b5ac6e.jpg)
Для себя я решил ответить на несколько основных вопросов:
Почему эта уязвимость с высоким рейтингом безопасности?
Что именно идет не так в уязвимых приложениях?
Можем ли мы добраться до удаленного исполнения кода?
Рейтинг риска безопасности приложений
Итак, почему эта уязвимость с высоким рейтингом риска?
Все просто, существует общая система оценки рейтинга уязвимых приложений, я использовал CVSS 3.0 версии и есть калькулятор для самостоятельной оценки риска. Сам рейтинг состоит из 8 основных параметров, сочетание которых и рассчитывает риск нашего приложения от 0.0 до 10.0, от меньшего большему риску соответственно. Так как вектор атаки у нас сетевой, сложность эксплуатации небольшая и доступность высокая, вот мы и получаем рейтинг HIGH от 7.3 и выше для некоторых весьма популярных уязвимых приложений:
Прототип в JavaScript
Давайте представим, что мы создаем пустой объект в JavaScript. Пусть будет const test = {}
При создании наш новый созданный объект уже имеет множество свойств и методов. Откуда они взялись у него? Ответ — прототип.
![](https://habrastorage.org/getpro/habr/upload_files/6a0/b1a/b37/6a0b1ab370c8c9bfa2ecafaf97c7850e.jpg)
Объектно-ориентированные языки Java или PHP к примеру, используют классы как схемы для создания объектов. Каждый объект принадлежит классу, и классы организованы в так называемую иерархии, Родитель — Потомок. Если мы вызываем любой метод объекта, среда выполнения языка или компилятор будет искать метод в классе, к которому принадлежит объект и если он его не сможет найти, то будет искать выше в родительском классе, а затем еще выше, пока не достигнет вершины иерархии классов.
Но JavaScript другой — это объектно-ориентированный язык программирования, основанный на прототипах. Каждый объект связан с «прототипом». Когда мы вызываем метод, например test.doSomething()
, JavaScript сначала будет проверять, определяли ли мы его сами явно для нашего объекта и если нет, то пойдет искать его в прототипе.
![Прототип есть у всех объектов, даже пустых Прототип есть у всех объектов, даже пустых](https://habrastorage.org/getpro/habr/upload_files/261/0bc/00d/2610bc00de105e18cd79ce2acbedc556.jpg)
Как происходит загрязнение прототипа?
Загрязнение прототипа — это инъекционная атака. При эксплуатации злоумышленник может контролировать значения свойств объекта по умолчанию. То есть, это позволяет злоумышленнику изменять логику приложения. Суть в том, что если мы изменяем свойство в прототипе, который общий для двух или более объектов, то все объекты в итоге получат измененное нами свойство!
Это важно понимать, так как большинство объектов по умолчанию используют один и тот же прототип, поэтому, если мы изменим прототип только одного из объектов, мы сможем изменить поведение всех объектов!
![Загрязнение прототипа пакета flat v5.0.0 Загрязнение прототипа пакета flat v5.0.0](https://habrastorage.org/getpro/habr/upload_files/6de/550/073/6de550073fa4c55444a23f0172fdc6c6.jpg)
Дотянуться до RCE
В последнее время появляется все больше статей про Prototype Pollution в связке с XSS. Так как JavaScript в основном используется на стороне клиента, то и вектор эксплуатации видится нам, как возможность дотянуться до XSS, но это не совсем всё что можно сделать.
Мы поговорим о другом векторе, а именно, возможно ли довести вектор атаки до эксплуатации на стороне сервера. Для понимания эксплуатации уязвимости на серверной стороне нужно знать две вещи:
место, где присутствует уязвимость Prototype Pollution
и как, или посредством чего, уязвимость может влиять на серверную логику приложения.
Если у нас на сервере стоит NodeJS, то нам на помощь приходит AST с его возможностью обрабатывать и исполнять код на сторону сервера.
AST (Abstract Syntax Tree) — абстрактное синтаксическое дерево. Это особое представление (можно представить в виде описательного JSON объекта), с которым было бы удобно программно обрабатывать код. Зачастую используемая в шаблонизаторах и при компиляции TypeScript. Для более углубленного понимания работы AST рекомендую почитать эту статью.
Если мы имеем дело с одним из шаблонизаторов, например PUG, то программная обработка кода его выглядеть будет как на схеме.
![Схема корректной обработки кода в шаблонизаторе PUG Схема корректной обработки кода в шаблонизаторе PUG](https://habrastorage.org/getpro/habr/upload_files/a04/031/60e/a0403160e531c95ef3ca66f1baf45a23.jpeg)
Если мы нашли уязвимости Prototype Pollution, то можем воспользоваться AST, заставив исполнить наш произвольный код, направив его в процессы parser или compiler. Шаблонизаторы Handlebars и Pug удачно подходят для этой цели.
![](https://habrastorage.org/getpro/habr/upload_files/76b/f14/6ee/76bf146ee82bf6232619b8a339231d69.jpeg)
Важно понимать, что код, встроенный в логику приложения, посредством уязвимости Prototype Pollution, попадает в шаблонизатор и в конечном итоге исполняется.
![Участок кода пакета шаблонизатора PUG где исполняется код Участок кода пакета шаблонизатора PUG где исполняется код](https://habrastorage.org/getpro/habr/upload_files/1eb/31d/29f/1eb31d29fa420ba5cd086c372a63cc7c.jpeg)
Конкурс на ZeroNights X
25 августа 2021 в Санкт-Петербурге прошла десятая конференция по информационной безопасности ZeroNights. Это хакерская конференция c атмосферной обстановкой и большим сообществом, конкурсы для которой я готовил неоднократно.
В этот раз конкурс назвали “Hack to be Hired”. Этим названием мы хотели подчеркнуть важность навыков в сфере информационной безопасности при приеме на работу в различные ИТ-компании.
Идея конкурса родилась из популярного мема.
![](https://habrastorage.org/getpro/habr/upload_files/1d7/2c4/908/1d72c49083ab3a9890fd26ea3e2d36d1.jpeg)
Чтобы усложнить задание, мы сделали все вакансии компании неактивными. Так, злоумышленнику предстоит взломать сайт компании, открыть вакансию, которая пришлась ему по душе, затем ответить на нее и принять свое же приглашение.
Сценарий конкурса
участник изучает сайт компании
собирает всю необходимую информацию
взламывает административную панель
активирует выбранную им вакансию
эксплуатирует найденные уязвимости и получает RCE на сервере
получив RCE можно перевести свое резюме в статус одобренной
Следовательно, если участник пригласил себя на собеседование – победа!
Последний флаг успешно получен, и поставленная задача выполнена.
Итоги
Сценарий проверили и запустили на нашей образовательной платформе. Благодаря персонажам и игровым механикам конкурс получился интерактивным и занимательным.
Тизер для тех, кто хочет пройти ее: лабораторная работа скоро будет включена в курс JavaScript на платформе Академии Digital Security.
Спасибо всем, кто дочитал до конца!
Список использованных материалов:
Исследования на тему AST-injection — https://blog.p6.is/AST-Injection/
Практическое применение трансформации AST-деревьев —https://habr.com/ru/post/439564/
Выступление на ZeroNights 2021 — https://youtu.be/ggqLPR6TBDw
ht-pro
Было интересно, спасибо.