ORM Injection
Last updated
Last updated
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
В цьому пості пояснюється, як можна зробити Django ORM вразливим, використовуючи, наприклад, код на кшталт:
Зверніть увагу, як всі request.data (які будуть у форматі json) безпосередньо передаються для фільтрації об'єктів з бази даних. Зловмисник може надіслати несподівані фільтри, щоб витягти більше даних, ніж очікувалося.
Приклади:
Логін: У простому логіні спробуйте витягти паролі користувачів, зареєстрованих у системі.
Можливо здійснити брутфорс пароля, поки він не буде витікати.
Реляційне фільтрування: Можливо проходити через відносини, щоб витікати інформацію з колонок, які навіть не очікувалися для використання в операції. Наприклад, якщо можливо витікати статті, створені користувачем з цими відносинами: Article(created_by
) -[1..1]-> Author (user
) -[1..1]-> User(password
).
Можливо знайти пароль усіх користувачів, які створили статтю
Фільтрація багато-до-багато: У попередньому прикладі ми не змогли знайти паролі користувачів, які не створили статтю. Однак, слідуючи іншим зв'язкам, це можливо. Наприклад: Article(created_by
) -[1..1]-> Author(departments
) -[0..*]-> Department(employees
) -[0..*]-> Author(user
) -[1..1]-> User(password
).
У цьому випадку ми можемо знайти всіх користувачів у відділах користувачів, які створили статті, а потім витікати їх паролі (у попередньому json ми просто витікаємо імена користувачів, але потім можливо витікати паролі).
Зловживання багатосторонніми відносинами між групами та правами Django з користувачами: Більше того, модель AbstractUser використовується для створення користувачів у Django, і за замовчуванням ця модель має деякі багатосторонні відносини з таблицями Permission та Group. Це, по суті, стандартний спосіб доступу до інших користувачів з одного користувача, якщо вони в одній групі або мають одне й те саме право.
Обхід обмежень фільтрації: Той самий блог пропонував обійти використання деяких фільтрів, таких як articles = Article.objects.filter(is_secret=False, **request.data)
. Можливо вивантажити статті, які мають is_secret=True, оскільки ми можемо повернутися з відношення до таблиці Article і витікати секретні статті з не секретних статей, оскільки результати об'єднуються, а поле is_secret перевіряється в не секретній статті, тоді як дані витікають з секретної статті.
Зловживаючи відносинами, можна обійти навіть фільтри, призначені для захисту показаних даних.
Помилка/Часова основа через ReDoS: У попередніх прикладах очікувалося отримати різні відповіді, якщо фільтрація працювала чи ні, щоб використовувати це як оракул. Але може бути так, що якась дія виконується в базі даних, і відповідь завжди однакова. У цьому сценарії може бути можливим викликати помилку бази даних, щоб отримати новий оракул.
Від того ж поста щодо цього вектора:
SQLite: За замовчуванням не має оператора regexp (потрібно завантажити стороннє розширення)
PostgreSQL: Не має тайм-ауту regex за замовчуванням і менш схильний до зворотного проходження
MariaDB: Не має тайм-ауту regex
Наступні трюки витягнуті з цього поста.
Повний контроль пошуку:
Можна побачити, що все тіло javascript передається до prisma для виконання запитів.
У прикладі з оригінального поста це перевірить всі пости, створені кимось (кожен пост створюється кимось), повертаючи також інформацію про користувача цього когось (ім'я користувача, пароль...)
Наступний запит вибирає всі пости, створені кимось з паролем, і повертає пароль:
Повний контроль над умовою where:
Давайте розглянемо це, де атака може контролювати where
умову:
Можливо безпосередньо фільтрувати паролі користувачів, як:
Використовуючи операції, такі як startsWith
, можливо витікати інформацію.
Обхід фільтрації в реляційних зв'язках багато-до-багато:
Можливо витікати непубліковані статті, повертаючись до багатосторонніх відносин між Category
-[*..*]-> Article
:
Також можливо витягти всіх користувачів, зловживаючи деякими зворотними багатосторонніми зв'язками:
Помилки/Запити з затримкою: У оригінальному пості ви можете прочитати дуже детальний набір тестів, проведених для знаходження оптимального корисного навантаження для витоку інформації з використанням навантаження на основі часу. Це:
Де {CONTAINS_LIST}
- це список з 1000 рядків, щоб переконатися, що відповідь затримується, коли правильний leak знайдено.
Ці трюки були знайдені в цьому пості.
Зверніть увагу, що Ransack 4.0.0.0 тепер вимагає використання явного allow list для атрибутів та асоціацій, які можна шукати.
Вразливий приклад:
Зверніть увагу, як запит буде визначено параметрами, надісланими зловмисником. Було можливим, наприклад, методом грубої сили отримати токен скидання за допомогою:
Завдяки брутфорсингу та потенційним зв'язкам було можливим витікати більше даних з бази даних.
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)