ThinkPHP简介
ThinkPHP 是一个免费开源的,快速、简单的面向对象的 轻量级PHP开发框架 ,创立于2006年初,遵循Apache2开源协议发布,是为了敏捷WEB应用开发和简化企业应用开发而诞生的。ThinkPHP从诞生以来一直秉承简洁实用的设计原则,在保持出色的性能和至简的代码的同时,也注重易用性。并且拥有众多的原创功能和特性,在社区团队的积极参与下,在易用性、扩展性和性能方面不断优化和改进,已经成长为国内最领先和最具影响力的WEB应用开发框架,众多的典型案例确保可以稳定用于商业以及门户级的开发。
漏洞简述
尽管ThinkPHP 5.0.x框架采用了参数化查询方式,来操作数据库,但是在 insert 和 update 方法中,传入的参数可控,且无严格过滤,最终导致本次SQL注入漏洞发生。
ThinkPHP基础知识
在进行漏洞分析之前,我们需要了解一下ThinkPHP基础知识,这里仅介绍对本次漏洞分析有帮助的部分。
ThinkPHP5.0的 目录结构
1 | thinkphp 应用部署目录 |
我们本次的 payload 为:http://localhost/thinkphp/public/index.php/index/index/index?name[0]=inc&name[1]=updatexml(1,concat(0x7,user(),0x7e),1)&name[2]=1
,解释如下:
1 | http://localhost/thinkphp/ public/ index.php/ index/ index/ index |
变量获取
1 | $name = input("get.name/a"); |
数据库查询
1 | Db::table("users")->where(["id"=>1])->insert(["username"=>$name]); |
环境搭建
在了解了基本知识后,我们可以开始搭建环境。这里我们使用ThinkPHP 5.0.14版本来进行实验,下载地址:http://www.thinkphp.cn/download/1107.html
我们先安装好phpstudy,然后将下载好的ThinkPHP 5.0.14解压至phpstudy的网站根目录下,安装ThinkPHP 5.0.14需要Mbstring、PDO、Curl三个插件,php版本这里用5.6。
接着我们需要配置连接数据库的文件,并开启thinkphp的调试功能。在此之前,你需要先在数据库中创建用于测试的数据,例如这里我用thinkphp作为数据库名,那么就在mysql命令行下执行create database thinkphp;
然后在建立一个users表,列名有id,username,password,执行create table users(id int auto_increment primary key,username varchar(20),password varchar(30));
即可,最后我们往表中插入测试数据,命令行执行insert into users(id,username,password) values(1,"test","thinkphp");
这样就算测试数据创建成功了。
配置连接数据库的文件,并开启thinkphp的调试功能,如下图:
最后修改文件 application\index\controller\Index.php 的内容,如下:
1 |
|
修改好后,访问我们的payload就可以触发漏洞了。
漏洞分析
首先,我们知道 insert 方法存在漏洞,那就查看 insert 方法的具体实现。该方法位于 thinkphp\library\think\db\Builder.php 文件中,我们可以看到在函数开头调用了 parseData 方法,并将 $data 作为参数传入, $data 的值是我们通过 get方式传入的一个数组类型的数据,如下图:
我们跟进 parseData 方法,该方法也在 thinkphp\library\think\db\Builder.php 文件中。可以看到,在结尾处有个switch语句,而且进入该语句后,会跳到case 'inc'
的地方,这里关键就是看看 $this->parseKey 是否有对 $val[1] 变量进行过滤了,因为 $val[1] 变量就是我们payload中的updatexml(1,concat(0x7,user(),0x7e),1)
,如下图:
继续跟进 parseKey 方法,会发现直接将传入的 $key 返回了,没有进行任何过滤。
我们再回到最开始的 insert 方法,加上调试语句,看看此时的sql语句变成了什么样子,如下图:
另一处update函数的注入与这个insert是类似的,这里就不在赘述。
总结
笔者也是第一次审计Thinkphp框架,在审计这套框架前还找了网络上的视频快速入门了下,再结合Thinkphp5.0手册,完成此次漏洞的审计。当然,文章有不当之处,还希望大家斧正。