前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >CVE-2020-7471 Django StringAgg SQL Injection漏洞复现

CVE-2020-7471 Django StringAgg SQL Injection漏洞复现

作者头像
墙角睡大觉
发布2020-02-25 12:47:26
1.6K0
发布2020-02-25 12:47:26
举报

0X1 漏洞概述

近日,Django 官方发布安全通告公布了一个通过StringAgg(分隔符)的潜在SQL注入漏洞(CVE-2020-7471)。

如果将不受信任的数据用作StringAgg分隔符,则部分版本的 Django将允许SQL注入。

通过将精心设计的分隔符传递给contrib.postgres.aggregates.StringAgg实例,可以打破转义并注入恶意SQL。

受影响Django版本:

代码语言:javascript
复制
1.11 到 1.11.28(不含)
2.2 到 2.2.10(不含)
3.0 到 3.0.3(不含)

目前已存在针对该漏洞的 PoC。

0X2 环境搭建

系统:Ubuntu18.04

安装django,这里我选择的是2.2版本

安装postgres数据库

进入psql中,创建数据库,并修改用户密码

后面我们使用django创建项目的时候,需要关联psql,这里需要安装psycopg2,使用命令如下:

代码语言:javascript
复制
sudo apt-get install python3-psycopg2
sudo apt-get install libpq-dev

这样数据库环境就可以了。

然后我们使用django创建项目和应用,命令如下:

代码语言:javascript
复制
django-admin startproject sql   创建项目
django-admin startapp  vul_app  创建应用

创建应用要在创建的项目目录中创建,完成之后目录结构如下所示:

然后修改settings.py文件,注册应用到项目中

并修改数据连接配置

代码语言:javascript
复制
DATABASES = {
    'default': {
        #'ENGINE': 'django.db.backends.sqlite3',
        #'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'test',         # 数据库名称
        'USER': 'postgres',
        'PASSWORD': 'postgres', # 数据库用户密码
        'HOST': '127.0.0.1',    # 数据库地址
        'PORT': '5432',
    }
}

保存之后,初始化数据库和表,命令如下:

代码语言:javascript
复制
python3 manage.py makemigrations
python3 manage.py migrate
python3 manage.py runserver 0.0.0.0:80

最后一条命令是启动环境命令

打开浏览器即可访问

0X3 漏洞分析

在github官方查看django的commit记录,不难发现:

从上面的代码中,我们知道漏洞函数位于模块StringAgg之中

代码语言:javascript
复制
from django.contrib.postgres.aggregates import StringAgg

官方对 delimiter 使用Value(str(delimiter))处理来防御 django。

为什么这种方式能防御呢?因为在 django开发中编写查询操作的时候,正确的做法是用下面的代码段:

代码语言:javascript
复制
sql = "SELECT * FROM user_contacts WHERE username = %s"
user = 'helloworld'
cursor.execute(sql, [user])

django会根据你所使用的数据库服务器(例如PostSQL或者MySQL)的转换规则,自动转义特殊的SQL参数。如果你的查询代码像下面这种写法就存在注入的风险:

代码语言:javascript
复制
sql = "SELECT * FROM user_contacts WHERE username = %s" % 'helloworld'
cursor.execute(sql)

而跟进Django的源码查看是可以发现问题的:

Vlue处理过的参数会被加到sql的参数列表里,之后会被 django 内置的过滤机制过滤,从而防范 SQL 漏洞。

0X4 漏洞利用

根据其他安全员发布的POC,这里使用Fuzzing测试找到delimiter导致SQL注入的原因是在过滤单引号引起的,我们在创建的应用module中需要添加一个数据模型,用来显示注入前后数据的返回结果,如下所示:

然后使用Saferman的CVE-2020-7471脚本测试,链接如下:

代码语言:javascript
复制
https://github.com/Saferman/CVE-2020-7471

将CVE-2020-7471.py放在项目根目录中,并修改脚本关联的环境配置文件

修改完成后测试:

前后数据不一致说明注入漏洞存在,不过如果还想将数据库中的用户数据进一步提取出来,就进一步需要写不同的数据模型方法了。

0X5 加固修复

升级到Django最新版3.0.3即可。

0X6 参考链接

代码语言:javascript
复制
https://xz.aliyun.com/t/7218
https://github.com/Saferman/CVE-2020-7471
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-02-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 安全漏洞环境学习 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档