05.01.2015

Обход аутентификации в NoSQL

image

После предыдущего поста мне задали множество вопросов, касающихся деталей реализации  JavaScript-инъекций на стороне сервера (Server Side JavaScript Injection, SSJI). Читатели просили  показать больше примеров. Чтобы продемонстрировать проблему в явном виде, думаю, мы можем начать с обхода аутентификации на простенькой форме.

Автор: Barry Shteiman

После предыдущего поста мне задали множество вопросов, касающихся деталей реализации JavaScript-инъекций на стороне сервера (Server Side JavaScript Injection, SSJI). Читатели просили показать больше примеров. Чтобы продемонстрировать проблему в явном виде, думаю, мы можем начать с обхода аутентификации на простенькой форме.

Я написал простейший фронтенд для MongoDB с базовым механизмом аутентификации при помощи имени пользователя и пароля, которые вы можете встретить в любом более менее серьезном приложении. Пользовательская коллекция хранится базе данных MongoDB в связке с PHP и Apache.

Ниже показан снимок коллекции из таблицы «myusers»:

http://imperva.typepad.com/.a/6a01156f8c7ad8970c01bb078f8c0b970d-pi

Рисунок 1: Содержимое таблицы «myusers»

На стороне приложения реализован простейший аутентификационный механизм, где происходит сравнение введенного имени пользователя и пароля (см. скриншот ниже).

http://imperva.typepad.com/.a/6a01156f8c7ad8970c01bb078f8c30970d-pi

Рисунок 2: Кусок кода, отвечающий за процесс аутентификации

Чтобы лучше понимать принцип работы кода, немного коснемся формата запросов. Все запросы в MongoDB должны быть в формате JSON, где передаются массивы параметров и значений. Драйвер MongoDB представляет собой компонент, преобразующий массив к формату JSON.

Запрос, заполненный значениями, будет передаваться в MongoDB в следующем виде:

db.myusers.find( {username: 'barry',Password:'jimmypage'})

Теперь рассмотрим механизмы манипуляции входными данными для создания инъекции. В коде, показанном выше, используются два параметра: имя пользователя и пароль. Форма авторизации выглядит следующим образом:

http://imperva.typepad.com/.a/6a01156f8c7ad8970c01b8d0745ffa970c-pi

Рисунок 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’}})

который возвратит полное содержимое коллекции, и наша инъекция завершится успешно:

http://imperva.typepad.com/.a/6a01156f8c7ad8970c01bb078f8f63970d-pi

Рисунок 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’}})

Успешное выполнение инъекции позволило нам пройти авторизацию от имени Марка.

http://imperva.typepad.com/.a/6a01156f8c7ad8970c01b7c6ea6b43970b-pi

Рисунок 5: Успешный обход авторизации от имени конкретного пользователя

Заключение

Как было продемонстрировано выше, манипуляция с входными данными и атаки с использованием инъекций – серьезная угроза для приложений, оперирующих большими объемами данных. Проблема становится все более критичной, поскольку подобные приложения становятся все более популярными. Для нас же важно повышать уровень компетенции относительно атак связанных с инъекциями на стороне сервера с использованием JavaScript, а входные данные должны подвергаться тщательной обработке.
comments powered by Disqus