CVE-2022-34265 Django Extract & Trunc SQL注入漏洞
2022-7-12 19:9:18 Author: mp.weixin.qq.com(查看原文) 阅读量:9 收藏

★且听安全-点关注,不迷路!

★漏洞空间站-优质漏洞资源和小伙伴聚集地!

这段时间 Java 卷的太狠,换一下口味。

漏洞信息

Django 数据库函数 `Trunc` 和 `Extract` 主要用于进行日期操作,定义如下:

`Extract` 用于提取日期,比如我们可以提取日期字段中的年、月、日等信息, `Trunc` 则用于截取,比如 `2000-01-01 11:11:11` ,可以根据需求获取到日期 `2000-01-01` 。如果将未过滤的数据传递给 `kind` 或 `lookup_name` 时,将会出现 SQL 注入漏洞。影响版本:

  •  Django 3.2.x prior to 3.2.14

  •  Django 4.0.x prior to 4.0.6

补丁对比

在 Django 新版本 `operations.py` 的 `BaseDatabaseOperations` 类中新增了 `extract_trunc_lookup_pattern` 正则表达式:

然后在 `datetime.py` 的 `Extract` 和 `Trunc` 类中 `as_sql` 函数分别加入了对 `self.lookup_name` 和 `self.kind` 参数的正则表达式检查:

环境搭建

为了深入分析漏洞原理,建议采用源码方式完成环境搭建:

参考 Django 官方提供的 `database-functions` 以及补丁中的测试例子,构造如下数据库实体类:

对应 MySQL 数据库定义:

在 `views.py` 中添加测试 API 接口定义:

在 `urls.py` 中配置路由规则:

漏洞分析

以 `Extract` 为例,构造请求 `/extract_test/?lookup_name=year` ,顺利进入 API 函数入口:

在 Django 框架自带的 ORM 模型中,当进行 SQL 查询操作时,将调用 `\django\db\models\query.py` 的 `QuerySet` 类中对应方法进行处理。比如 `Demo` 中的查询将调用 `QuerySet#exists` 函数:

经过多次传递后,进入 `SQLCompiler#compile` :

最终到达此次存在漏洞的 `Extract` 类中函数 `as_sql` :

因为 `demo` 中选择的字段 `start_datetime` 属于 `DateTimeField` 类型,所以将进入第 `58` 行的 `datetime_extract_sql` 函数:

跟进 `date_extract_sql` :

`date_extract_sql` 函数将根据输入的 `lookup_type` 取值生成不同的 SQL 语句,比如 `demo` 中设置为 `year` ,最终返回如下 :

对来自 GET 请求的 `lookup_name` 参数只是完成大写转换,但没有进行任何检查,直接拼接到 SQL 查询语句中,存在注入漏洞:

报错回显测试:

修复方式

前面补丁对比已经提到,新版本中对传入参数新增了正则表达式检查规则。

由于传播、利用此文档提供的信息而造成任何直接或间接的后果及损害,均由使用本人负责,且听安全及文章作者不为此承担任何责任。

★且听安全-点关注,不迷路!

★漏洞空间站-优质漏洞资源和小伙伴聚集地!


文章来源: https://mp.weixin.qq.com/s?__biz=Mzg3MTU0MjkwNw==&mid=2247491171&idx=1&sn=ae6b7a26b1cb9b0f3f5acc75d6fbd1c1&chksm=cefda777f98a2e61394f3c251c8a1aff84dcebf88974a83e796feb96117037690cdd0121bfe4&scene=58&subscene=0#rd
如有侵权请联系:admin#unsafe.sh