漏洞盒子/细数Django框架核心历史SQL注入漏洞(上)_详细信息安全笔记
0x02 CVE-2019-14234漏洞描述
在2019年发布的一个安全更新,修复了在 、 两个模型字段中存在的SQL注入漏洞。
漏洞影响
该漏洞需要开发者使用了 或者 ,并且 中的键名可控, 自带的 -admin 中就存在这样的写法,可以利用其进行攻击。
漏洞分析
当我们进行查询时,会使用到 ,一般形式为
Collection.objects.filter(blog__author__extra='tom').all()
中包含三个部分,由 __ 分割,第一部分被称为 ,比如此处,就是查找 blog 表中的 字段,一般这里就是通过外键表现两个表之间的关系,但也存在特殊情况,比如存在 类型的字段时,那么就是从 JSON 字段中查找;第二部分是字段,表的字段或者 JSON 的字段;第三部分被称为 ,表示为后面值之间的对比关系,可不写,默认为 extra。
此处我们选择 进行分析,当 blog 字段为 类型时,
继承自 Field ,Field 又是继承 ,已经存在一个 方法,此处由于获取方式不同,因此重写该方法,之后是返回了一个 (name) ,接下来看看这里的代码
直接被调用时,又会触发 (self., *args, **)
在这里,最后会被执行 方法,目的是生成 sql 语句,但是这里的 self. 没有经过任何过滤就被拼接并直接返回,因此造成了注入。
漏洞复现
复现直接借助了 的环境,直接启动,环境代码可以直接在最下面的参考链接中找到
如下所示, 就是在 model 中使用了
代码和细节如下
此处的 使用了 ,访问链接即可触发漏洞
http://your-ip:8000/admin/vuln/collection/?detail__a%27b=123
0x03 CVE-2020-7471漏洞描述
在2020年发布的一个安全更新,修复了在 中存在的SQL注入漏洞。
漏洞影响
该漏洞需要开发者使用了 ,并且 参数可控,则可以利用其进行攻击。
漏洞分析
先来看到 上的代码比对
这里说明两点问题,第一, 参数没有经过过滤就传入,第二, 会直接进行字符串拼接,因此也是导致了存在 SQL 注入漏洞的原因。
接下来我们要做的就是找到使用该漏洞类的地方,关于 的使用可以看官方文档
很容易就可以得到一个可以利用的场景
Collection.objects.annotate(tempname=StringAgg('name', delimiter=query)).values('name')
漏洞复现
中没有找到相应的环境,找一个类似的环境改改,注意也需要使用 数据库
views.py
from django.shortcuts import render, HttpResponse
from .models import Collection
from django.contrib.postgres.aggregates.general import StringAgg
# Create your views here.
def vuln(request):
query = request.GET.get('q', default=0.05)
qs = Collection.objects.annotate(tempname=StringAgg('name', delimiter=query))
print(qs.query)
return HttpResponse(qs)
.py
from django.db import models
from django.contrib.postgres.fields import JSONField
class Collection(models.Model):
name = models.CharField(max_length=128)
detail = models.CharField(max_length=128)
def __str__(self):
return self.name
urls.py
from django.contrib import admin
from django.urls import path
from vuln import views
urlpatterns = [
path('admin/', admin.site.urls),
path('vuln/', views.vuln),
]
最后可以得到如下 poc
0x04 CVE-2020-9402漏洞描述
在2020年发布的安全更新,修复了在 GIS 查询功能中存在的 SQL 注入漏洞。
漏洞影响
需要使用了 GIS 聚合查询,用户使用 的数据库且存在可控
漏洞分析
首先看 的分析
这里修补了两处漏洞,都是同一个参数 引起的,看到这里会觉得还比较简单,直接从 self.extra 中获取到参数,直接进行拼接,得到最后的 sql 代码, 方法,就是得到的 的 sql 代码,也就是这个漏洞应该只存在于使用 数据库时
虽然知道这里存在漏洞,我们更重要的是去获取什么时候会触发这两个漏洞,所以要去看代码,可以直接搜索
第一处漏洞
位于 .py
此类继承于 .db... ,然后下面这个 Union 类又继承
因此可以通过使用 GIS 中的 Union 类来触发第一个漏洞
第二处漏洞
位于 .py
这里逻辑也是一样,没有任何过滤,接下来就是去找可以直接调用这里的位置,也就是找继承的位置,可以找到下面这个
至于接下来该如何去直接使用这两个类,可以查看官方文档,这里我直接看的 中的
漏洞复现
复现直接借助了 的环境,直接启动,环境代码可以直接在最下面的参考链接中找到
第一处
http://127.0.0.1:8000/vuln/q=?20) = 1 OR (select utl_inaddr.get_host_name((SELECT version FROM v$instance)) from dual) is null OR (1-1
第二处
http://127.0.0.1:8000/vuln2/q=?0.05))) FROM "VULN_COLLECTION2" where (select utl_inaddr.get_host_name((SELECT user FROM DUAL)) from dual) is not null --
0x05 CVE-2021-35042漏洞描述
在2021年发布的安全更新,修复了在 中存在的 SQL 注入漏洞。
漏洞影响
需要使用了
漏洞分析
出现问题的点是在 ,先搜索这个方法
首先 ,也就是将 置空
然后进行
想要将传进来的字段添加到 ,需要经过一些验证
将每一部分取出来进行比较,是字符串时进行比较,包含点号时,直接 ,跳过了后面的 验证,因此可以通过添加点号的形式绕过。
处理带点号的代码位于文件 /db//sql/.py 的 函数中,核心代码如下
在这里对 table 进行了过滤,但是并没有对 col 进行过滤,因此造成了注入。
漏洞复现
复现直接借助了 的环境,直接启动,环境代码可以直接在最下面的参考链接中找到
简单来个报错的
http://127.0.0.1:8000/vuln/?order=aaa.tab'
0x06 链接
环境与 poc 都可以在如下链接获取
参考链接
原文始发于微信公众号(安全漏洞复现):细数框架核心历史SQL注入漏洞(上)
~
网络安全学习,我们一起交流
~