После предыдущего поста мне задали множество вопросов, касающихся деталей реализации JavaScript-инъекций на стороне сервера (Server Side JavaScript Injection, SSJI). Читатели просили показать больше примеров. Чтобы продемонстрировать проблему в явном виде, думаю, мы можем начать с обхода аутентификации на простенькой форме.
Автор: Barry Shteiman
После предыдущего поста мне задали множество вопросов, касающихся деталей реализации JavaScript-инъекций на стороне сервера (Server Side JavaScript Injection, SSJI). Читатели просили показать больше примеров. Чтобы продемонстрировать проблему в явном виде, думаю, мы можем начать с обхода аутентификации на простенькой форме.
Я написал простейший фронтенд для MongoDB с базовым механизмом аутентификации при помощи имени пользователя и пароля, которые вы можете встретить в любом более менее серьезном приложении. Пользовательская коллекция хранится базе данных MongoDB в связке с PHP и Apache.
Ниже показан снимок коллекции из таблицы «myusers»:
Рисунок 1: Содержимое таблицы «myusers»
На стороне приложения реализован простейший аутентификационный механизм, где происходит сравнение введенного имени пользователя и пароля (см. скриншот ниже).
Рисунок 2: Кусок кода, отвечающий за процесс аутентификации
Чтобы лучше понимать принцип работы кода, немного коснемся формата запросов. Все запросы в MongoDB должны быть в формате JSON, где передаются массивы параметров и значений. Драйвер MongoDB представляет собой компонент, преобразующий массив к формату JSON.
Запрос, заполненный значениями, будет передаваться в MongoDB в следующем виде:
db.myusers.find( {username: 'barry',Password:'jimmypage'})
Теперь рассмотрим механизмы манипуляции входными данными для создания инъекции. В коде, показанном выше, используются два параметра: имя пользователя и пароль. Форма авторизации выглядит следующим образом:
Рисунок 3: Форма авторизации к базе данных
URL, выполняющий аутентификацию, в моем случае выглядит следующим образом:
http://<hostname/mongoapp/login.php?username=barry&password=jimmypage
Как правило, в атаках, связанных с манипуляцией входными данными, основная цель – «перехитрить» логику работы бэкэнда. В нашем случае логика проста – необходимо, чтобы было возвращено значение true.
Значение true возвращается, когда: (username = X) and (password = Y).
Кроме того, следующее выражение также истинно: (username !=A) and (password !=B).
Чтобы обойти механизм аутентификации, мы будем использовать отрицательный аргумент как от имени анонимного, так и от имени конкретного пользователя.
Обход авторизации от имени анонимного (любого) пользователя
В PHP можно передавать отрицательные параметры через оператор [$ne], что поможет нам обойти механизм аутентификации при помощи следующего URL’а:
http://<hostname>/mongoapp/login.php?username[$ne]=foo&password[$ne]=bar
На стороне MongoDB выполнится следующий запрос:
db.myusers.find( {username: { $ne: ‘foo’} ,Password: {$ne:’bar’}})
который возвратит полное содержимое коллекции, и наша инъекция завершится успешно:
Рисунок 4: Успешный обход авторизации
Обход авторизации от имени конкретного пользователя
Чтобы обойти авторизацию от имени пользователя Mark, необходимо создать следующий запрос:
(username = Mark) and (password != bar)
Вместо слова bar можно подставить любое другое сочетание символов, которое не является паролем Марка.
URL будет выглядеть следующим образом:
http://<hostname>/mongoapp/login.php?username=mark&password[$ne]=bar
В базе MongoDB будет выполнен запрос:
db.myusers.find( {username: ‘mark’ ,Password: {$ne:’bar’}})
Успешное выполнение инъекции позволило нам пройти авторизацию от имени Марка.
Рисунок 5: Успешный обход авторизации от имени конкретного пользователя
Заключение
Как было продемонстрировано выше, манипуляция с входными данными и атаки с использованием инъекций – серьезная угроза для приложений, оперирующих большими объемами данных. Проблема становится все более критичной, поскольку подобные приложения становятся все более популярными. Для нас же важно повышать уровень компетенции относительно атак связанных с инъекциями на стороне сервера с использованием JavaScript, а входные данные должны подвергаться тщательной обработке.Цифровые следы - ваша слабость, и хакеры это знают. Подпишитесь и узнайте, как их замести!