安全矩阵

 找回密码
 立即注册
搜索
查看: 1993|回复: 0

Django SQL 引入逻辑分析

[复制链接]

249

主题

299

帖子

1391

积分

金牌会员

Rank: 6Rank: 6

积分
1391
发表于 2022-6-9 09:25:24 | 显示全部楼层 |阅读模式
原文链接:Django SQL 引入逻辑分析


前言
考试前翻Python的组件漏洞时发现Django考完SQL存在漏洞,抽空后抽空相关的漏洞,分别是CVE-2020-7471CVE-2021-35042CVE-2022-28346
姜戈简介
Django 是一个高级 Python Web 框架,它鼓励快速开发和简洁、实用的设计。它由经验丰富的开发人员构建,解决了 Web 开发的大部分麻烦,因此您可以专注于编写应用程序,而无需重新发明轮子。它是免费和开源的。
CVE-2020-7471
漏洞简介
1.11.28 之前的 Django 1.112.2.10 之前的 2.2 3.0.3 之前的 3.0 如果将不受信任的数据用作 StringAgg 分隔符,则允许 SQL 注入(例如,在 Django 应用程序中,将数据下载作为用户的一系列行提供-指定的列分隔符)。通过将适当设计的分隔符传递给 contrib.postgres.aggregates.StringAgg 实例,可以打破转义并注入恶意 SQL
漏环境
·参考27个环境CVE-2020-1
漏洞分析
在漏洞描述中描述该漏洞的核心是StringAgg聚合函数的delimiter参数SQL存在注入漏洞。通过查找Djangocommit记录,在官方对的修复代码中可以看到,漏洞函数from django.contrib.postgres.aggregates import StringAgg模块位于其中。
官方修复通过引入from django.db.models import ValueValue来处理来该部署中的漏洞:
delimiter_expr  = 值(str (分隔符))
后续可以在中查看django.db.models的函数Value中查看、Value函数处理、后续处理的参数加入到sql parameter list之后会进Django组过滤机制的过滤、定点来sql注入漏洞。
漏洞利用点是StringAgg聚合函数的delimiter参数,官方文档中使用了简单的权利保护函数进行说明,在它的级联中使用了它的级联划分delimiter符。
通过为单项声明时会Fuzz发现delimiter报错信息,且通过打印的报错可以,未经验证的转义就嵌入到单项声明sql中。
def  fuzz ():
    symbol_str  =  "!@#$%^&*()_+=-| \\\" ':;?/>.<,{}[]"
    for  c  in  symbol_str :
        results  =  Info objects .all ( ) .values ( ' gender ' ) .annotate ( mydefinedname = StringAgg ( ' name' , delimiter = c )) try : for e in results : pass except IndexError :
        
               
               
         
            pass
        except  Exception  as  err :
            print ( "[+] 报错信息: " ,  err )
            print ( "[+] 漏洞分隔符: " ,  c )
根据报错信息,在_execute函数中打断点。
当遍历完数据库中的数据后,进行Fuzz操作,观察加入了delimiter为单引号取值的sql
此时sql是个字符串,因此会产生转义号,该sql语句在postgres中的执行语句为:
选择 vuln_app_info” 。"gender" ,  STRING_AGG ( "vuln_app_info" . "name" ,  ''') AS "mydefinedname" FROM "vuln_app_info" GROUP BY "vuln_app_info"."gender"
尝试delimiter设置')--错误,可以看到结果显示其结果的语句,查看报告信息,注释了FROM语句。
构造exp如下:
- \ ') AS "demoname" FROM "vuln_app_info" GROUP BY "vuln_app_info"."gender" LIMIT 1 OFFSET 1 --
CVE-2021-35042
漏洞简介
如果 order_by 是来自 Web 应用程序客户端的不受信任的输入,则 3.1.13 之前的 Django 3.1.x 3.2.5 之前的 3.2.x 允许 QuerySet.order_by SQL 注入。
漏环境
·35 好环境CVE-2021-42 .
漏洞分析
可知漏洞信息,先跟进order_by函数,该函数先调用clear_ordering函数清除Query类中的self.order_by参数,调用add_ordering函数self.order_by参数增加。
通过order_by函数代码环境的参数为调用函数中的参数,如下所示SQL
查询 = 请求。得到。获取('order_by' , 默认= 'vuln' res  =  User 。对象。order_by (查询)
选择 app_user” 。“vuln” 、 “app_user” 。"order_by"  FROM  "app_user"  ORDER  BY  "app_user" 。“order_by”  ASC , “app_user” 。“漏洞”  ASC
继续进行职能, 则职能add_orderingordering作为绩效之后进行鉴定, 如果item继续进行五次鉴定:
·if '.' in item: 判断是否为带列的查询,SQL语句中允许使用定义表名的列,例如order by (user.name),即根据user表下的name字段进行示例。该判断方法将在Django 4.0之后被警告删除,因此成功之后通过warning,之后进行continue
·if item == '?'item的字符串?时,可用order by的值进行语法RAND(),显示显示SQL的返回数据continue
·if item.startswith('-'):观感item为字符串的接续结果,则当顺序排列-时,会显示接续的连续order by查询上的正序表示。DESCASC-
·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)当前item列名中的ordering类别,进行到处理。Queryself.order_by
在第一次进行判断中,if '.' in item进行order by更好的地表查询能力查询,如果能够区分的话,如果列是否为表带表continuecontinue则直接跳过对列self.names_to_path的有效性。后续处理带字符串.的代码,位于文件django/db/models/sql/compiler.pyget_order_by函数中,核心代码:
如果 ''  在 字段中:
    表, col  =  col 。拆分('.' 1
    order_by append ((
            OrderBy (
                RawSQL ( ' %s . %s '  %  ( self . quote_name_unless_alias ( table ),  col ),  []),
                descending = descending
            ),  False ))
    继续
代码中函数表名,使用函数self.quote_name_unless_alias表名,使用强制处理来强制处理,后面表面则确实没有表面处理,则可以处理的列处理行为,SQL注入。
最后参数app_user.name) --数据库的语句为:
选择 ` app_user` _ ` id` ` app_user` _ _ ` name`FROM`app_user`ORDER BY ( ` app_user`.name ) -- ) ASC LIMIT 21 _ _ _ _ _      
使用)以下方式进行最终的最终实现payloadhttp://127.0.0.1:8000/vuln/?order_by=vuln_app_user.name);select%20updatexml(1,%20concat(0x7e,(select%20@@version)),1)%23
CVE-2022-28346
漏洞简介
2.2.28 之前的 Django 2.23.2.13 之前的 3.2 4.0.4 之前的 4.0 中发现了一个问题。QuerySet.annotate()aggregate() extra() 方法通过精心制作的字典(带有字典扩展)作为传递的 **kwargs 在列别名中进行 SQL 注入。
漏环境
·28个循环好环境CVE-2022-46
漏洞分析
查找Djangocommit记录示例,在官方对的修复代码中可以查看测试用例。
annotate由漏洞利用,在annotate函数中首先会调用函数并跟进漏点_annotate并调用kwargs
annotate函数在完成对kwargs.values()合法性更新等操作,之后将kwargs遍历annotationsannotations的元素调用add_annotation进行数据聚合。
然后,继续add_annotation函数调用resolve_expression解析表达式,并在此同时对这些参数进行相应的检查
继续跟进,最终进入到db.models.sql.query.py:resolve_ref会中resolve_ref获取annotations中的元素,并将其转换后带到查询中的条件中,最后其结果通过transform_function聚合到一个Col对象中。
执行、返回db.models.query.py:_annotatesql语句、将结果返回到QuerySet中进行展示。
参考
·CVE-2020-7471漏洞详细分析原理以及POC
·Django CVE-2021-35042 order_by SQL注入分析
·已发布 Django 安全版本:4.0.43.2.13 2.2.28
注:如有侵权请联系删除


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|安全矩阵

GMT+8, 2024-11-30 02:32 , Processed in 0.018225 second(s), 19 queries .

Powered by Discuz! X4.0

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表