Yesterday

IDOR: использование и предотвращение [Complete web app pentesting series #19]

Введение

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

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

Тестирование «черного ящика»

URL лаборатории — https://app.hackthebox.com/challenges/Kryptos%2520Support

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

После получения первоначального доступа просмотрите настройки и найдите опцию для сброса пароля.

Теперь, если вы посмотрите запрос, стоящий за сбросом, он не проверяется с помощью какого-либо токена, и мы находим параметр uid. Что произойдет, если мы изменим его значение?

Вы можете затуманить значения uid, используя burp intruder. Мы видим, что со значением uid равным 1 мы можем изменить пароль для пользователя admin.

И с этим мы должны получить наш флаг.

Тестирование «серого ящика»

В отличие от предыдущих блогов, у нас было тестирование «белого ящика», так как в Интернете не смог найти ничего подходящего, но нашелся другой способ — лабораторию portswigger, которая в некоторой степени объясняет веб-приложения с помощью javascript.

Паттерны в цифровом пространстве

Тестирование безопасности часто начинается с наблюдения — поиска закономерностей (паттернов), которые могут выявить скрытые слабые места в архитектуре приложения. Во время недавнего проекта история прокси-сервера приложения выявила интересную конечную точку:

/download-transcript/{ID}.txt

Что сразу вызвало подозрения в отношении этой конечной точки, так это ее соответствие классическому шаблону IDOR — ресурсу, доступ к которому осуществляется через простой числовой параметр, который, по всей видимости, является внутренним идентификатором. Этот шаблон часто предполагает прямое сопоставление между параметром URL и записями бэкэнд-базы данных, что представляет собой потенциальную границу безопасности, которую можно протестировать.

Анализ уязвимостей: снятие слоев

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

Рассмотрим уязвимый паттерн запроса:

GET /download-transcript/2.txt HTTP/2
Host: 0a25009004c1db6081ed89ff001e0026.web-security-academy.net
Cookie: session=kp1BS7J2wYMZPvEWYVEGbIYnB4ktSHz5
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36
Accept: */*

Критическая уязвимость заключается в том, как приложение обрабатывает идентификатор «2» в URL-адресе. Этот числовой идентификатор служит прямой ссылкой на конкретный файл транскрипта, хранящийся на сервере. Приложение извлекает запрошенный файл исключительно на основе этого идентификатора, не проверяя, должен ли иметь к нему доступ текущий авторизованный пользователь.

Расследование проводилось по методичному подходу:

1. Наблюдение: в истории HTTP был обнаружен конечный пункт /download-transcript/2.txt, который показал паттерн, указывающий на прямую ссылку на объект (HTTP-запрос, выделенный синим цветом).

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

3. Контролируемое тестирование: создана вкладка «Repeater» в Burp Suite для тестирования доступа к /download-transcript/1.txt с сохранением того же сессионного куки, но с изменением только идентификатора ресурса.

4. Подтверждение уязвимости: успешно извлечена транскрипция с ID «1», которая принадлежала другому пользователю и содержала конфиденциальную информацию, включая пароль.

Успешное извлечение этой несанкционированной транскрипции подтвердило уязвимость. Приложение не проверило, имел ли запрашивающий пользователь законные права на доступ к ресурсу, обозначенному «1», а вместо этого слепо извлекло и вернула все данные, связанные с этим идентификатором.

Технический анализ: анатомия уязвимости

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

Из приведенного выше изображения мы получили два файла javascript, один из которых — chat.js, а другой — viewTranscript.js. Давайте взглянем на viewTranscript.js. Эта функция JavaScript в приложении раскрыла механизм загрузки транскрипта:

function viewTranscript(downloadTranscriptPath) {
    var chatForm = document.getElementById("chatForm");
    var viewTranscriptButton = document.createElement("button");
    viewTranscriptButton.setAttribute("id", "download-transcript");
    viewTranscriptButton.setAttribute("class", "button");
    viewTranscriptButton.innerText = "View transcript";
    viewTranscriptButton.onclick = viewTranscript;
    
    chatForm.appendChild(viewTranscriptButton)
    
    function viewTranscript() {
        var chatArea = document.getElementById("chat-area");
        var messages = chatArea.getElementsByClassName("message")
        var transcript = []
        for (var i = 0; i < messages.length; i++) {
           var message = messages.item(i)
           transcript.push(message.getElementsByTagName("th").item(0).innerText + " " + message.getElementsByTagName("td").item(0).innerText)
        }
        
        var xhr = new XMLHttpRequest();
        xhr.onload = function() {
            window.location = xhr.responseURL;
        }
        xhr.open("POST", downloadTranscriptPath);
        data = new FormData();
        data.append("transcript", transcript.join("<br/>"));
        xhr.send(data);
    }
};

Эта функция раскрывает несколько важных деталей, и мы делаем следующие выводы:

  1. Приложение собирает сообщения чата из DOM и отправляет их в виде транскрипта на сервер с помощью POST-запроса.
  2. Сервер обрабатывает эти данные и возвращает перенаправление на URL-адрес, по которому можно скачать транскрипт.
  3. Перенаправление ведет к конечной точке /download-transcript/{ID}.txt, где ID назначается сервером.

Уязвимость существует по следующим причинам:

  • Сервер генерирует последовательные или предсказуемые идентификаторы для транскриптов
  • Когда пользователи запрашивают файл транскрипта, приложение не может проверить право собственности
  • Сервер слепо доверяет параметру ID, предполагая, что запрос является законным, если он содержит действительный сессионный куки

Усовершенствование эксплуатации: от открытия до воздействия

1. Первоначальный доступ: успешно получен доступ к файлу /download-transcript/1.txt, несмотря на то, что он принадлежит другому пользователю.

2. Анализ содержания: в транскрипте содержалась конфиденциальная информация, в том числе:

  • Детали разговора
  • Пароль пользователя (наиболее важная находка)
  • Возможно, другие конфиденциальные данные, которыми обменивались участники чата

3. Анализ паттерна: Последовательный характер идентификаторов (1, 2, 3…) позволял предположить, что все транскрипты могут быть доступны, что указывало на широкомасштабный сбой системы контроля доступа.

Предлагаемые стратегии устранения недостатков

Для устранения уязвимостей IDOR требуется многоуровневый подход:

Немедленные тактические исправления

1. Внедрение проверок авторизации на уровне ресурсов

function downloadTranscript(transcriptId, currentUser) {
        // Retrieve the transcript object
        transcript = getTranscriptById(transcriptId)
        
        // Verify ownership or permission
        if (transcript.owner != currentUser.id && !currentUser.isAdmin) {
            return AccessDeniedError
        }
        
        // Proceed with download if authorized
        return transcript.content
    }

2. Используйте карты косвенных ссылок вместо того, чтобы напрямую раскрывать внутренние идентификаторы, реализуйте уровень сопоставления:

   // Server-side map (stored in session)
    userResourceMap = {
        "a7f392e": "transcript_2"  // User-specific mapping
    }
    
    // URL becomes /download-transcript/a7f392e
    // Server translates the reference before retrieving the resource
    

Ссылки:

  1. https://www.cisa.gov/news-events/cybersecurity-advisories/aa23-208a
  2. https://github.com/urma/indirect-reference
  3. https://www.nodejs-security.com/blog/secure-javascript-coding-to-avoid-insecure-direct-object-references-idor

Заключение

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

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

Оригинальная статья | Перевод: THREAD