Найти тему
Белый хакер

Инъекция NoSQL в простом виде

Инъекция NoSQL в простом виде

Белый хакер 12, 2022December 12, 2022

Обратите внимание, что это не будет техническим руководством по причинам существования NoSQL инъекций. Я просто поделюсь мыслительным процессом и подходом, которые были у меня при тестировании этого конкретного приложения.

Когда я попал в эту программу, у нее было одно приложение в скоупе. Это был аутентифицированный тест, и учетные данные были предоставлены клиентом.

Как всегда, я запустил Burp Suite, открыл встроенный браузер Burp, перешел на страницу входа и начал перехватывать запросы.

Я внимательно следил за каждым запросом после нажатия кнопки "Войти".

Во-первых, был запрос на вход в конечную точку /oauth2/token. Эта конечная точка вернула токен JWT, который позволил нам получить доступ к API приложения. Тем не менее, здесь не было ничего интересного.

После запроса на вход был еще один запрос к конечной точке сбора метаданных. Это также было не очень интересно, так как конечная точка вернула данные, которые должны были быть использованы для отображения интерфейса.

Но после первых двух запросов был отправлен запрос на /api/[CLIENT_NAME]/Customers. Этот запрос, в частности, был очень интересным, так как у него был параметр с именем $filter. И внутри параметра была длинная NoSQL строка.

Запрос выглядел так:

GET /api/[CLIENT_NAME]/Customers?$filter=(id%20eq%202)%20and%20((is_active%20eq%20%27Y%27)%20and%20(is_deleted%20eq%20%27N%27))&$orderby=name HTTP/1.1

Host: [TARGET_APPLICATION]

...

[SNIPPED_BECAUSE_IRRELEVANT]

Если вы посмотрите на значение параметра $filter, до декодированная из URL строка выглядит так:

(id eq 2) and ((is_active eq 'Y') and (is_deleted eq 'N'))

Эта конечная точка возвращает основную информацию о клиенте, такую как имя клиента, дата последнего входа в систему и т.д.

Вы можете увидеть полную пару запрос-ответ ниже:

В прошлом я читал несколько блогов о NoSQL инъекциях. Особенно после HackIM CTF. Итак, я понял, что это может быть что-то, относящееся к NoSQL.

eq в $filter это тоже самое, что и = или LIKE в SQL.

Итак, что на самом деле сделала конечная точка, так это прочитала значение $filter и извлекла данные, указанные в фильтре.

Разобьем параметры в приведенном выше фильтре:

  • id (Это был идентификатор клиента. У нашего текущего пользователя был идентификатор клиента 2. Если бы я изменил его на 1, то это был бы простой IDOR.)
  • is_active (это атрибут, который был у нашего пользователя. Атрибут is_active должен быть Y если наш пользователь активен и N если нет.)
  • id_deleted (Еще один атрибут для указания того, был ли удален наш пользователь или нет)

Итак, конечная точка /api/[CLIENT_NAME]/Customersendpoint берет фильтр и возвращает данные нашего пользователя (user ID 2), тогда и только тогда, когда наш пользователь активен и не удален.

Для теста я удалил последнюю часть, которая выглядела так: ((is_active eq 'Y') and (is_deleted eq 'N')) и просто отправил следующее значение фильтра:

$filter=(id eq 2)

Приложение с радостью вернуло мои данные без ошибок.

Когда я понял, что это NoSQL, я погуглил "Подстановочные знаки в NoSQL" и попытался поиграть с подстановочными знаками. Я наткнулся на следующую документацию MongoDB по Wildcard Indexes: https://www.mongodb.com/docs/manual/core/index-wildcard/

Я игрался с подстановочными знаками, делая такие вещи, как $filter=($** eq 2), и некоторые из них работали, в то время как некоторые из них не работали.

Я также попытался принудительно добавить подстановочные знаки в стоимость и создал эту полезную нагрузку: $filter=(id eq $**)

Но у запроса был недействительный синтаксис, поэтому он также потерпел неудачу.

Честно говоря, я не приложил много усилий к подстановочным знакам, так как не правильно понял синтаксис.

Потом мне пришла в голову мысль. В фильтре был один оператор, называемый eq. Что делать, если я использую какой-то другой оператор? Можно ли это сделать?

Я погуглил "MongoDB syntax", и снова пришел к этой потрясающей документации MongoDB: https://www.mongodb.com/docs/manual/tutorial/query-documents/

Вышеуказанная документация очень хорошо объясняет синтаксис MongoDB с альтернативами в SQL синтаксисе, что позволяет правильно его понять.

Однако, углубившись в документацию, я перешел к другой странице, посвященной "Query and Projection Operators". Вы можете найти ее здесь: https://www.mongodb.com/docs/manual/reference/operator/query/

И эта страница была именно тем, что мне было нужно, чтобы создать свой эксплойт! На странице перечислены все операторы MongoDB и сценарии их использования.

Я решил перейти к оператору gt, потому что хотел, чтобы конечная точка возвращала сведения обо всех пользователях, чей идентификатор пользователя был больше 0. Я предположил, что идентификаторы пользователей будут начинаться с нуля.

Для этого я создал следующую полезную нагрузку:

$filter=(id gt 0)

И приложение вернуло личную информацию другого пользователя. К сожалению, было только два пользователя, и это был предпродакшен. Тем не менее, я все еще был счастлив, потому что получил информацию о другом пользователе.

Я все еще не был доволен результатами, потому что утекла только основная информация для входа. Никакие персональные данные или конфиденциальная информация не просочились с этой конечной точки.

Я вернулся к своей истории Burp и нашел все конечные точки, которые имели параметр $filter. Я собрал в общей сложности 7 конечных точек.

Внимательно проверив конечные точки, я нашел одну интересную конечную точку под названием/api/[CLIENT_NAME]/CustomerLogins. Это было интересно, потому что она брала фильтр и возвращала персональную информацию в ответе.

Я использовал ту же полезную нагрузку, что и выше, и отправил запрос. И приложение слило адрес электронной почты, имя пользователя, хэш пароля и номер телефона! И это был пользователь-администратор. Не просто случайный пользователь.

Я сообщил обо всех конечных точках и написал хороший отчет.

Mr.Brain Proger