September 27, 2023

IDOR. Autorize. Broken Access Control.

Уязвимости IDOR (Insecure direct object references) и Broken Access Control (BAC) являются одними из самых опасных уязвимостей в веб-приложениях. Они позволяют злоумышленнику получить доступ к конфиденциальным данным или функциям, к которым он не должен иметь доступа.


Что такое BAC и IDOR?

Все прекрасно знают о том, что авторизация предоставляет пользователю права на выполнение определённых действий, а также процесс проверки (подтверждения) данных прав при попытке выполнения этих действий. Авторизация не эквивалентна аутентификации. После успешной аутентификации авторизация определяет, к каким функциям и данным может получить доступ пользователь, обеспечивая при этом надлежащее разграничение прав доступа.

Именно поэтому веб-приложению необходимы средства контроля доступа, позволяющие его пользователям использовать веб-приложение с различными привилегиями. Контроль доступа — это применение ограничений на то, кто (или что) может выполнять различные функции и получать доступ к запрошенным ресурсам. Нарушенный контроль доступа (Broken Access Control) — часто встречающаяся уязвимость в системе безопасности веб-приложений. Существуют несколько типов контроля доступа, а вместе с ними и уязвимостей, связанных с их нарушением:

  1. Вертикальный контроль доступа;
  2. Горизонтальный контроль доступа;
  3. Контекстно-зависимый контроль доступа.

Про горизонтальный контроль доступа мы поговорим подробнее.

IDOR, или небезопасные прямые ссылки на объекты — это тип уязвимости контроля доступа, которая возникает, когда приложение использует вводимые пользователем данные для прямого доступа к объектам. Термин IDOR стал популяризирован после его появления в первой десятке OWASP 2007 года. Однако это лишь один пример многих ошибок реализации контроля доступа, которые могут привести к его обходу. Уязвимости IDOR чаще всего связаны с горизонтальным повышением привилегий, но они также могут привести к вертикальному повышению привилегий, получив, например, учетные данные администратора путём эксплуатации уязвимой конечной точки.


В этой статье мы рассмотрим принцип работы уязвимостей IDOR и Broken Access Control, а также методы их обнаружения и автоматизации с помощью Autorize.

Как искать

Для автоматизации поиска уязвимости IDOR нам необходимо наличие двух аккаунтов.

Создаём два аккаунта, воспользовавшись расширением для Firefox под названием Multi-Account-Container, которое позволяет нам открывать несколько сессий в одном окне браузера:

Советую использовать данное расширение, так как оно очень часто может помочь в ситуациях, когда необходим режим инкогнито или другой браузер для проверки каких-либо уязвимостей.

Дополнительно устанавливаем расширение под названием Autorize для Burp Suite:

Добавляем сессионный идентификатор атакующего

Первое, что вам нужно сделать — это добавить сессионный идентификатор второго пользователя или злоумышленника в Autorize.

Если вы не уверены, какие заголовки вам точно необходимы, то можно скопировать большую часть запроса и использовать его, ведь лучше копировать больше заголовков, чем меньше:

Теперь просто копируем заголовки запроса атакующего и вставляем в Autorize:

Больше второй аккаунт нам не понадобится, и мы можем переходить к поиску нарушений контроля доступа, но сначала я объясню, как работает Autorize:

Всякий раз, когда совершается запрос, расширение будет менять его и подставлять добавленный нами сессионный идентификатор и проверять различия в ответах. Например, если я попытаюсь добавить какой-то товар в корзину, Autorize поменяет часть запроса и попробует совершить то же действие с сессионным идентификатором атакующего.
Таким образом, мы будем пытаться получить содержимое данных, принадлежащих другому пользователю, то есть проверять веб-приложение на наличие IDOR.
По сути, расширение делает то же самое, что и Repeater, но подставляет каждый раз другие заголовки в запрос.

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

Можно переходить к тестированию контроля доступа и поиска уязвимости IDOR. Просто используем все доступные функциональности и изучаем работу сайта.

Detect

Как можно заметить, после добавления товара в корзину приложение говорит нам, что мы просмотрели корзину другого пользователя:

Перейдем в Autorize и посмотрим, в каком запросе у нас нарушается контроль доступа:

Как вы видите, сессионный идентификатор отличается, и можно заметить, что ответ приложения одинаков при разных заголовках запроса, тогда как у запроса без заголовков авторизации ответ отличается:

Autorize совершает две проверки:

  1. Добавляет заголовки атакующего в запрос;
  2. Удаляет заголовки, сигнализирующие об успешной авторизации (то есть отправляет запрос без заголовков).

Вторая проверка также является нарушением контроля доступа, так как позволяет получить информацию неавторизованному пользователю.

Теперь покупаем товар:

Добавляем адрес:

Выбираем доставку:

Добавляем карту для оплаты:

Размещаем заказ:

Советую чаще проверять конечные точки, содержащие pdf или какие-либо файлы, так как потенциально они могут не иметь проверки контроля доступа и обычно защищены уникальным идентификатором, полагаясь на безопасность за счет непредсказуемости идентификатора.

Таким образом, мы проверили всю функциональность покупки на наличие уязвимостей IDOR и Broken Access Control в автоматическом режиме, и Autorize показал нам результат работы в удобном для чтения и восприятия формате.

Теперь вернёмся к Authorize и посмотрим, где нам удалось обойти ограничения контроля доступа:

Как можно подметить, длина ответа приложения с разными сессионными данными одинаковая. Это говорит нам о том, что в данном месте есть IDOR, и мы получаем доступ к данным другого пользователя (в данном случае чек после размещения заказа), которые содержат конфиденциальную информацию.

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

Сравниваем содержимое pdf с помощью Comparer, чтобы убедиться, что мы получили доступ к одному и тому же чеку:

Переходим в браузере в аккаунт атакующего и смотрим содержимое чека:

В другом запросе также раскрывается email другого пользователя:

Также по длине ответа можно понять, в каких запросах расишрению не удалось обойти ограничения:

IDOR bypass BugBounty

Закончим с теоретической частью и для примера рассмотрим лабораторную работу, посвященную найденной исследователем IDOR-уязвимости в рамках программы BugBounty.

В данной лабораторной показан пример слабого шифрования и возможности обхода ограничения скорости перебора значений и защиты от ботов.

Скачиваем лабораторную работу:

git clone https://github.com/leetCipher/bug-bounty-labs.git

Запускаем уязвимое приложение:

sudo docker-compose up

Создаем аккаунт:

Сервис, где была обнаружена уязвимость, похож на Instagram, где можно публиковать фотографии и делиться ими.

Когда я проверил все конечные точки, то обратил внимание на вызов метода /api/user, в теле которого находился параметр, благодаря которому можно просмотреть учетные данные конкретного пользователя:

Простой перебор данного идентификатора невозможен из-за количества символов, и на первый взгляд может показаться, что всё безопасно и никакого IDOR нет. Но на сайте мной была обнаружена конечная точка /js/register.js, которая показывает, как происходит формирование данного хэша:

Так как в формировании хэша участвует дата регистрации, first_name и last_name, то единственное, что нам нужно угадать, — это дата. Ниже приведён скрипт, который может подобрать все варианты хэша для заданных имени имени и фамилии:

#!/usr/bin/python3
import hashlib
import sys

def main(first_name, last_name):
    # hashes wordlist
    wordlist_fd = open("hashes-wordlist.txt", "w")
    # user full name reversed
    full_name = first_name + last_name
    full_name = full_name[::-1]

    # brute-force all dates since 2017
    for year in range(2017, 2023, 1):
        for month in range(1, 13):
            for day in range(1, 32):
                string = "{}{:02}{:02}{}".format(full_name, day, month, year)
                # generate the SHA-256 sum of the reversed full name and the date
                hashed_string = hashlib.sha256(string.encode()).hexdigest()

                # write the hash to the hashes-wordlist.txt file
                wordlist_fd.write("{}\n".format(hashed_string))

    # close the fd
    wordlist_fd.close()
    print("[+] wordlist generated for {} {}".format(first_name, last_name))


if __name__ == "__main__":
    if len(sys.argv) == 3:
        main(str(sys.argv[1]), str(sys.argv[2]))
    else:
        print("usage: ./generate-hashes.py  ")

Исследователь обнаружил, что домен с уязвимым приложением был зарегистрирован в 2017 году. Это значит, что отсчет даты регистрации пользователей можно начинать с этого года:

Приведённый выше скрипт подбирает хэши на основе двух значений: first_name и last_name. Он объединяет (конкатенирует) имя и фамилию в переменную full_name, а затем перебирает все даты, начиная с 2017 года. Затем вся информация объединяется в переменную string и вычисляется хэш SHA256 в шестрадцатеричной кодировке для этой строки. Результат вычисления вероятных значений хэша для конкретного пользователя записывается в файл hashshes-wordlists.txt.

Теперь можно попробовать перебрать хэш пользователя john doe, имя которого раскрывается на странице:

Получаем возможные хэши пользователя:

Переходим в Intruder и пробуем перебрать все значения:

Спустя 20 запросов мы получаем ограничения на попытку просмотра данных:

Кастомные заголовки не помогли обойти ограничения, но исследователем было замечено, что при смене заголовка Referer ограничения снимаются, и мы можем продолжать проверку хэша:

Таким образом, в Intruder добавляем точку перебора в заголовок Referer (его значение не играет особой роли):

После атаки получаем доступ к данным пользователя john doe:

Повторим атака с именем sam young:

Таким образом, исследователю удалось найти изъян в механизме генерации хэша пользователя, что позволило проэксплуатировать уязвимость IDOR в, казалось бы, неуязвимом приложении.