0x00. 前言
ThinkPHP被认为是PHP入门级框架。作为菜鸡的我,据破神经验,寒假打算系统学习一下ThinkPHP框架开发及梳理其安全问题。恰逢契机,写篇文章梳理一下ThinkPHP。
因为是梳理漏洞,不可能每个漏洞都分析太详细(每一个漏洞都够发一篇文章了),所以每个漏洞都附带一个详细链接供大家参考。毕竟也不是自己挖的漏洞,肯定比不上原创描述的精准透彻。都是学习别人的东西,重要的是有所收获。
刚刚学习ThinkPHP,若有错误,还请大家多多指点谅解。
0x01. ThinkPHP简介
——大道至简,开发由我
ThinkPHP(简称TP)是一个快速、兼容而且简单的轻量级国产PHP开发框架。其遵循Apache2开源协议发布,从Struts结构移植过来并做了改进和完善,同时也借鉴了国外很多优秀的框架和模式,使用面向对象的开发结构和MVC模式。
优点:中文文档、快速、简单、灵活
缺点:不规范
ThinkPHP的这些优点正好迎合了目前国内IT行业敏捷开发、短期效益、廉价成本的这种形势,故占有不小的市场;其缺点也相对应产生了不少的安全问题。
0x02. ThinkPHP发展
——一波三折,重构升级
2006.01.15-2012.04.05:
FSC->ThinkPHP->PHP5重构->2.0版本
2.0版本框架之前这段时间,TinkPHP知名度不高,使用其做网站也比较少。目前,可搜索到漏洞也是屈指可数。故不是本文重点。
2012.04.05-2015.12.11:3.x黄金时代
在ThinkPHP3.2.3版本的黄金时期,据说国内PHP网站里面有三分之一都是基于ThinkPHP开发。时至金日,仍然有很多公司使用并维护ThinkPHP3.x版本的框架开发的网站。故ThinkPHP3.x版本的漏洞是本文重点。
2015.12.11-目前:5.x时期
转型重构,功能更加完善,跻身国际主流开发框架。正是TinkPHP的灵活、轻量、快速必然对应其规范性、严谨性降低,故产生更多安全问题。
详细发展史可参考:
https://baike.baidu.com/item/ThinkPHP#1
0x03. ThinkPHP漏洞梳理
V2.0
'index.php'跨站脚本漏洞
时间:2010-02
原因:未知
可能此漏洞危害不大,相关信息很少。
详情链接:
https://www.exploit-db.com/exploits/33933
V2.1-2.2
URL任意代码执行(高危)
时间:2012-04
原因:
此处使用了preg_replace的危险参数/e,使得perg_replace的第二个参数会被当做php代码执行。同时,此处还利用PHP代码给数组动态赋值,而且是双引号。双引号中的php变量语法是能够被解析执行的。
Payload:index.php/module/action/param1/${@print(THINK_VERSION)}
详情链接:
https://www.cnblogs.com/gaoxu387/archive/2012/04/23/2466133.html
由于任意代码执行危害巨大,官方马上修复了此漏洞。去乌云镜像搜了一下,发现当时不少网站都受到了很大的影响,比如:江苏移动、成都移动、飞飞电影程序v2.0、91手机某分站等等。
V3.0
1. 敏感信息泄露
时间:2012-08
原因:延续2.1代码执行漏洞,模块加载失败虽不可以执行命令,但是错误信息可以暴路径。
Payload:index.php/module/action/param1/$%7B@print(THINK_VERSION)%7D
详情链接:
https://www.secpulse.com/archives/9788.html
2. 代码执行(lite模式开启,同V2.1)
时间:2014-03
原因:ThinkPHP开启lite模式后,会加载ThinkPHP/Extend/Mode/Lite/Dispacher.class.php去匹配URL并分发用户请求,这样又会触发V2.1的URL任意代码执行漏洞。
V3.1
1. 逻辑漏洞
时间:2012-10
原因:没有验证token形式是否正确,用户随便构造一个没有下划线的_hash_提交验证永远为真。
详情链接:
http://www.thinkphp.cn/bug/1949.html
2. SQL注入
时间:2013-07
原因:ThinkPHP/Lib/Core/Model.class.php文件里parseSql函数未能实现SQL过滤,允许远程攻击者利用漏洞提交特殊的SQL查询,可获取敏感信息或获取shell
详请链接:
http://www.thinkphp.cn/code/253.html
3. PDO封装与SQL注入分析
时间:2013-10
详情连接:
http://www.thinkphp.cn/topic/8095.html
4. 代码执行(lite模式开启,同V2.1)
时间:2014-03
原因:ThinkPHP开启lite模式后,会加载ThinkPHP/Extend/Mode/Lite/Dispacher.class.php去匹配URL并分发用户请求,这样又会触发V2.1的URL任意代码执行漏洞。
详情链接:
http://0day5.com/archives/1402/
5.Ubb标签读取任意内容
时间:2014-04
原因:ThinkPHP的Ubb标签,有一个代码高亮的功能,即满足:[code]xxx[/code]或者[php]xxx[/php]的时候,会对中间的xxx读取,并高亮,xxx是路径,而非具体的代码。由ThinkPHP开发且提供评论功能(支持UBB)标签的时候发帖,若输入[code]/etc/passwd[/code]即可读到对应目录下的文件信息。
详情链接:
http://www.0day5.com/archives/1586/
6. between关键字正则匹配错误SQL注入
时间:2014-11
原因:ThinkPHP\Library\Think\Db.class.php文件,parseWhereItem函数对between关键字的正则匹配错误。
详细链接:
https://bugs.leavesongs.com/php/thinkphp%E6%9C%80%E6%96%B0%E7%89%88%E6%9C%ACsql%E6%B3%A8%E5%85%A5%E6%BC%8F%E6%B4%9E/
7. Driver.class.php SQL注入
时间:2016-03
原因:未知
详细链接:
https://www.seebug.org/vuldb/ssvid-90846
8. 跨站脚本漏洞
时间:2017-03
原因:/Tpl/think_exception.tpl模板文件代码,没有使用htmlspecialchars(),用户输入没有变成符号实体,隐藏可攻击XSS。
详情链接:
https://blog.csdn.net/ljl890705/article/details/60757516
V3.1.3
V3.2
1. Driver.class.php SQL注入
时间:2016-03
原因:未知
详细链接:
https://www.seebug.org/vuldb/ssvid-90846
2. 报错SQL注入
时间:2018-04
原因:updataxml报错注入
Payload:
index.php?name[0]=bind&name[1]=0 and updatexml(2,concat(0x7e,user()),0)
详细链接:
https://bbs.ichunqiu.com/forum.php?mod=viewthread&tid=38901&highlight=thinkphp
3. 报错SQL注入
时间:2018-08
Payload:
index.php?m=Home&c=Index&a=test&id[where]=1%20and%20updatexml(1,concat(0x7e,user(),0x7e),1)--
原因:select(),find(),delete()方法可能会传入数组类型数据,产生的多个sql注入隐患。
详细链接:https://xz.aliyun.com/t/262
V3.2.3
1. 缓存函数设计缺陷导致Getshell
时间:2017-08
原因:thinkphp\library\think\cache\driver\File.php文件的public function set($name, $value, $expire = null)方法中换行与回车导致绕过了注释。
详细链接:https://xz.aliyun.com/t/99
2. updata注入
时间:2018-04
原因:updata绕过I函数的过滤
Paylaod:
money[]=1123&user=liao&id[0]=bind&id[1]=0%20and%20(updatexml(1,concat(0x7e,(select%20user()),0x7e),1))
详细链接:
https://www.anquanke.com/post/id/104847
V3.2.4
1. parseOrder函数SQL注入漏洞(CVE-2018-18546)
时间:2018-10
原因:Library/Think/Db/Driver.class.php文件的parseOrder函数使得程序错误地处理了变量key。远程攻击者可借助order参数利用该漏洞执行任意的SQL命令。
详细链接:
https://98587329.github.io/2018/10/09/thinkphp%E6%B3%A8%E5%85%A5%E5%88%86%E6%9E%90/
2. parseKey函数SQL注入漏洞(CVE-2018-18529)
时间:2018-10
原因:Library/Think/Db/Driver/Mysql.class.php中的parseKey函数未能正确的处理变量key。远程攻击者可利用该漏洞获取数据。
详细链接:
https://www.kingkk.com/2018/10/Thinkphp-%E8%81%9A%E5%90%88%E6%9F%A5%E8%AF%A2%E6%BC%8F%E6%B4%9E/#ThinkPHP3-lt-3-2-4
V5.0
1. 远程代码执行
时间:2016-11
原因:未知
详细链接:
http://www.cnvd.org.cn/flaw/show/CNVD-2016-10697
2. SQL注入 && PDO真伪/预处理
时间:2017-07
原因:若PDO::ATTR_EMULATE_PREPARES => false,则PDO没有模拟“预处理机制”,从而参数化绑定的整个过程都是和数据库交互进行的。
详细链接:
https://www.leavesongs.com/PENETRATION/thinkphp5-in-sqlinjection.html
V5.0.10
1. 缓存函数设计缺陷导致Getshell
时间:2017-08
原因:thinkphp\library\think\cache\driver\File.php文件的public function set($name, $value, $expire = null)方法中换行与回车导致绕过了注释。
详细链接:https://xz.aliyun.com/t/99
2. ilterExp函数过滤不严SQL注入
时间:2017-09
原因:ThinkPHP5重写了数据库操作类方法,新加了not like表达式但filterExp函数没有及时更新过滤。
详细链接:https://xz.aliyun.com/t/58
V5.1.24
delete注入(CVE-2018-17566)
时间:2018-09
原因:delete时如果where中参数可控,产生SQL注入。
详情链接:
https://github.com/top-think/think/issues/858
V5.1.25
count注入(CVE-2018-18530)
时间:2018-10
原因:/think/db/Query.php聚合函数错误处理了聚合变量
详情链接:
https://www.kingkk.com/2018/10/Thinkphp-%E8%81%9A%E5%90%88%E6%9F%A5%E8%AF%A2%E6%BC%8F%E6%B4%9E/#ThinkPHP5-lt-5-1-25
V5.1.x
SQL注入(CVE-2018-16385)
时间:2018-10
原因:处理order by 后的参数时,未正确过滤处理数组的key值。如果该参数用户可控,且当传递的数据为数组时,会导致漏洞的产生。
Payload:
index/test/index?order[id',111)| updatexml(1,concat(0x3a,user()),1)%23][]=1
详情链接:http://blog.topsec.com.cn/?p=3513
V5.x
未开启强制路由的情况下引发getshell漏洞
时间:2018-12
原因:程序未对控制器进行过滤,导致攻击者可以通过引入\符号来调用任意类方法。
详情链接:https://xz.aliyun.com/t/3570
V5.0.x
远程代码执行
时间:2019-01
原因:library/think/Request.php文件method函数在POST方法下可控。
详情链接:
https://www.freebuf.com/column/194617.html
V3.x和V5.x
order by注入
时间:2018-08
原因:处理order by排序时,当排序参数可控且为关联数组(key-value)时,框架为对key值作看全过滤处理。可以利用key构造SQL语句进行注入。
详情链接:
https://github.com/top-think/thinkphp/issues/528
0x04. 结语
ThinkPHP推出的目标更多是为了让国内众多的小白PHPer能够快速上手。而目前国内整个IT行业都急功近利,追求敏捷开发,短期效益,市场需求也是廉价劳动力。ThinkPHP的简单、易学、方便、廉价,恰好迎合了这种形势。
PHP的灵活也使得我们在写PHP代码的时候顾虑很少,以至于写出的代码不是很规范。当其他框架发誓要让PHP程序规范起来的时候,而ThinkPHP把这种不规范发挥到了新的高度(开发人员技术良莠不齐+牺牲规范注重灵活的框架)。
不过,ThinkPHP官方非常重视安全问题。这一点是非常值得我们肯定的。也有人说:“框架本身就没有安全这个概念,大部分的问题都是开发者的代码抒写问题,然后又刚好踩了一下框架的雷区,才导致了各种问题。”
以上观点均个人并结合网络的鄙见,如有不对恳请谅解。最后,祝大家新年快乐!2019,在安全的路上继续前进!
0x05. 参考文章
https://www.kancloud.cn/top-think/thinkphp-blog/913359
https://xz.aliyun.com/t/2630
SKSEC
山东科技大学信息安全小组
关注
领取专属 10元无门槛券
私享最新 技术干货