Py学习  »  Django

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

安全漏洞环境学习 • 4 年前 • 291 次点击  

0X1 漏洞概述


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


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


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


受影响Django版本:

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,使用命令如下:

sudo apt-get install python3-psycopg2sudo apt-get install libpq-dev

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

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

django-admin startproject sql   创建项目django-admin startapp  vul_app  创建应用

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

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

并修改数据连接配置

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',    }}

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

python3 manage.py makemigrationspython3 manage.py migratepython3 manage.py runserver 0.0.0.0:80

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

打开浏览器即可访问



0X3 漏洞分析


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

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

from django.contrib.postgres.aggregates import StringAgg

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

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

sql = "SELECT * FROM user_contacts WHERE username = %s"user = 'helloworld'cursor.execute(sql, [user])

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

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脚本测试,链接如下:

https://github.com/Saferman/CVE-2020-7471

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

修改完成后测试:

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


0X5 加固修复


升级到Django最新版3.0.3即可。


0X6 参考链接

https://xz.aliyun.com/t/7218https://github.com/Saferman/CVE-2020-7471



Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/55004
 
291 次点击