漏洞簡介
Django 在2022年釋出的安全更新,修複了在 QuerySet 的 annotate(), aggregate(), extra() 等函數中存在的 SQL 注入漏洞。
影響版本
2.2<= Django Django <2.2.28 3.2<= Django Django <3.2.13 4.0<= Django Django <4.0.4
需要使用了 annotate 或者 aggregate 或 extra 方法
環境搭建
搭建特定版本的 django 項目
利用 pycharm 建立一個 python 項目
建立完成項目後在 Settings 中找到 Project: CVE202228346 對應的 Python Interpreter
添加存在問題的 Django 版本
在 Terminal 中執行指令,建立 django 項目
django-admin startproject CVE202228346
配置啟動設定
運作後就啟動了最簡單的 django 項目
編寫配置漏洞代碼
折騰來折騰去,出現了很多問題,一度想要放棄說直接采用 docker ,但是在不斷的試錯下,最終還是編寫成功
因為對 python 的 django 不太熟悉,是以其中可能更多的是比較偏向于基礎的操作
【----幫助網安學習,需要網安學習資料關注我,私信回複“資料”免費擷取----】
① 網安學習成長路徑思維導圖
② 60+網安經典常用工具包
③ 100+SRC漏洞分析報告
④ 150+網安攻防實戰技術電子書
⑤ 最權威CISSP 認證考試指南+題庫
⑥ 超1800頁CTF實戰技巧手冊
⑦ 最新網安大廠面試題合集(含答案)
⑧ APP用戶端安全檢測指南(安卓+IOS)
進入到項目目錄下建立指令 建立第一個應用
在 settings.py 中添加配置
在 urls.py 中添加 對應的 url,urls.py 相當于路由解析器,将路由解析到對應的 views.py 中對應的函數上
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 主要定義了對應路由所響應的函數
from django.db.models import Count
from django.http import HttpResponse
from django.shortcuts import render
from .models import User
# Create your views here.
def index(request):
return HttpResponse('hello world')
def users(request):
field = request.GET.get('field', 'name')
user_amount = User.objects.annotate(**{field: Count("name")})
html = ""
for u in user_amount:
html += "<h3>Amoount of users: {0}</h3>".format(u)
return HttpResponse(html)
def loadexampledata(request):
u = User(name="Admin")
u.save()
u = User(name="Staff1")
u.save()
u = User(name="Staff12")
u.save()
return HttpResponse("ok")
三個函數分别是 helloword 函數,往資料庫中加參數,以及查詢資料庫中的字段
編寫好代碼後,需要對資料庫執行初始化操作
python manage.py makemigrations
python manage.py migrate
漏洞複現
先通路 initialize 為資料庫中添加資訊
構造 payload
http://127.0.0.1:8000/demo/?field=demo.name" FROM "demo_user" union SELECT "1",sqlite_version(),"3" --
漏洞分析
發現一個問題,在加上斷點調試以後,每次運作輸出的結果跟不加斷點運作的結果存在很大的差異,結果完全不同。不斷嘗試之後發現是因為在某些地方加上斷點之後,在調試器中檢視變量和狀态可能會影響程式的執行速度和記憶體使用情況,為了友善的輸出某些位置的變量,采用 print 的方法結合斷點調試。
通過 get 傳入的參數 field
CVE202228346.demo.views.users
此處的**{field: Count("name")} 用來表示拆分字典
跟進 annotate 對傳入參數的處理
django.db.models.query.QuerySet.annotate
繼續将參數傳入到 _annotate 進行處理
django.db.models.query.QuerySet._annotate
在将 kwargs 的值 update 到 annotations 後,調用 add_annotation 進行處理
django.db.models.sql.query.Query.add_annotation
add_annotation 也是漏洞存在的關鍵位置,因為修複漏洞的關鍵位置也在此處
調用 resolve_expression 解析表達式
django.db.models.aggregates.Aggregate.resolve_expression
django.db.models.expressions.Func.resolve_expression
django.db.models.expressions.F.resolve_expression
django.db.models.sql.query.Query.resolve_ref
最後我們可以看到 clone 對應的值 以及執行的 SQL 語句
整個漏洞分析下來,仍然有很多不太清楚的地方,可能再分析幾個關于 Django 的漏洞會好一些
漏洞修複
在 add_annotation 添加了 check_alias 來對傳入的參數進行校驗