前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >追洞小组 | 实战CVE-2020-7471漏洞

追洞小组 | 实战CVE-2020-7471漏洞

作者头像
Ms08067安全实验室
发布2021-02-26 16:38:42
9950
发布2021-02-26 16:38:42
举报

文章来源|MS08067 WEB攻防知识星球

本文作者:守拙(Ms08067实验室追洞小组成员)

一、漏洞名称:

通过StringAgg(分隔符)的潜在SQL注入漏洞

二、漏洞编号:

CVE-2020-7471

三、漏洞描述:

Django 1.11.28之前的1.11.x、2.2.10之前的2.2.x和3.0.3之前的3.0.x版本允许SQL注入,如果不受信任的数据用作StringAgg分隔符(例如,在存在多行数据下载的Django应用程序中,使用用户指定的列分隔符进行下载的场景)。通过向contrib.postgres.aggregates.StringAgg实例传递一个精心构造的分隔符,可能会破坏转义并注入恶意SQL。

四、影响版本:

Django 1.11.x < 1.11.28

Django 2.2.x < 2.2.10

Django 3.0.x < 3.0.3

五、漏洞分析

聚合函数StringAgg的delimiter参数未经任何转义就嵌入到sql语句中,导致sql注入

六、实验环境及准备:

1.数据库:postgresql,版本无所谓,本文中使用kali虚拟机中自带的数据库,允许外部连接

  • 修改如下文件,监听所有端口
代码语言:javascript
复制
/etc/postgresql/12/main/postgresql.conf
  • 修改如下文件,允许外部连接
代码语言:javascript
复制
/etc/postgresql/12/main/pg_hba.conf
  • 重启服务后,连接数据库并创建测试数据库
代码语言:javascript
复制
登陆:psql -U postgres -h [kali主机的IP]
创建测试数据库:CREATE DATABASE test,后面poc中会用到
其他postgresql语法可以参考菜鸟教程

2.POC: https://github.com/Saferman/CVE-2020-7471,运行环境django3.0.2

  • 安装django3.0.2

pip installdjango==3.0.2

  • 使用pycharm调试POC代码,参考POC中的readme文档
  • 初始化数据库后可以用pgadmin连接看下,test数据库中应该有如下表
  • Vul_app_info表中应该如下字段和数据

七、复现步骤:

POC测试脚本中有两个函数query()和query_with_evil(),前者用于模糊测试,后者用于注入点证明

1.模糊测试

  • 通过运行query()函数的异常捕获可以知道有两个特殊字符让程序产生了报错(%和’)
  • 将程序中异常捕获注释掉,payload使用%和’单独测试
  • 通过报错可以看出分号没有转义导致sql语句报错,并直接在报错信息返回了拼接后的sql语句。将断点打在执行sql语句并产生报错的代码块去看完整的sql
  • 得到程序运行的实际sql语句
代码语言:javascript
复制
SELECT "vul_app_info"."gender", STRING_AGG("vul_app_info"."name", \'\'\') AS "mydefinedname" FROM "vul_app_info" GROUP BY "vul_app_info"."gender" LIMIT 21

2.注入点证明

  • 通过注入sql语句使查询结果区别与程序原本的查询结果来证明注入点的可用
  • 程序原本执行的sql语句,最后是limit 21
代码语言:javascript
复制
SELECT "vul_app_info"."gender", STRING_AGG("vul_app_info"."name", \'- \') AS "mydefinedname" FROM "vul_app_info" GROUP BY "vul_app_info"."gender" LIMIT 21
  • 注入后的 sql 语句,最后是 limit 1,只返回一行数据
代码语言:javascript
复制
SELECT "vul_app_info"."gender", STRING_AGG("vul_app_info"."name", \'- \') AS "mydefinedname" FROM "vul_app_info" GROUP BY "vul_app_info"."gender" LIMIT 1 OFSET 1 --
  • 运行结果验证

八、其他思考:

1. 漏洞利用场景

  • Django 应用返回聚合数据的场景
  • 用于聚合的字符用户可控
  • 数据库得是 postgresql 数据库
  • 好像不容易存在这种场景...

2. 漏洞挖掘思路

  • 针对可能存在问题的函数,构建测试环境
  • 针对该函数进行模糊测试,看是否有 sql 语句报错信息
  • 如果模糊测试成功让 sql 语句报错,进行注入点利用验证

3. 漏洞修复

  • 在django的git仓库的提交记录中可以看到django官方的修复方案
  • https://github.com/django/django/commit/eb31d845323618d688ad429479c6dda973056136
  • 新版本中将delimiter 参数用Value函数处理了一下,再传递到sql中
  • 升级django版本(3.1.6)再debug一下
  • 分割符的地方用了%s,没有直接拼接进去,根据Value函数的注释说法是将参数放到sql的参数列表中,最终以下面的方式执行,则不存在sql注入风险
代码语言:javascript
复制
sql="SELECT * FROM user_contacts WHERE username = %s"
user='zhugedali'
cursor.execute(sql,[user])

4.同类型函数

  • 在postgresql数据库中和StringAgg函数一样可以传递分隔符参数的函数还有
代码语言:javascript
复制
array_to_string(array_agg(name),'-')
  • 但是django中没有找到这个函数的API(没有提供或者是我太菜了没找到..)
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-02-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Ms08067安全实验室 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档