该代码块首先检测路由规则,如果没有制定规则则按照默认规则进行URL调度,在preg_replace()函数中,正则表达式中使用了/e模式,将“替换字符串”作为PHP代码求值,并用其结果来替换所搜索的字符串。
正则表达式可以简化为“\w+/([\^\/])”,即搜索获取“/”前后的两个参数,$var[‘\1’]=”\2”;是对数组的操作,将之前搜索到的第一个值作为新数组的键,将第二个值作为新数组的值,我们发现可以构造搜索到的第二个值,即可执行任意PHP代码,在PHP中,我们可以使用${}里面可以执行函数,然后我们在thinkphp的url中的偶数位置使用${}格式的php代码,即可最终执行thinkphp任意代码执行漏洞,如下所示:
index.php?s=a/b/c/${code} index.php?s=a/b/c/${code}/d/e/f index.php?s=a/b/c/d/e/${code}由于ThinkPHP存在两种路由规则,如下所示:
模块/控制器/操作/[参数名/参数值...]
如果不支持PATHINFO的服务器可以使用兼容模式访问如下:
?s=http://www.likecs.com/模块/控制器/操作/[参数名/参数值...]
也可采用 index.php/a/b/c/${code}一下形式。
4.2、ThinkPHP 5.x 远程代码执行漏洞14.2.1、漏洞概要
漏洞名称:ThinkPHP 5.0.x-5.1.x 远程代码执行漏洞
参考编号:无
威胁等级:严重
影响范围:ThinkPHP v5.0.x < 5.0.23,ThinkPHP v5.1.x < 5.0.31
漏洞类型:远程代码执行
利用难度:容易
4.2.2、漏洞描述
2018年12月10日,ThinkPHPv5系列发布安全更新,修复了一处可导致远程代码执行的严重漏洞。此次漏洞由ThinkPHP v5框架代码问题引起,其覆盖面广,且可直接远程执行任何代码和命令。电子商务行业、金融服务行业、互联网游戏行业等网站使用该ThinkPHP框架比较多,需要格外关注。由于ThinkPHP v5框架对控制器名没有进行足够的安全检测,导致在没有开启强制路由的情况下,黑客构造特定的请求,可直接进行远程的代码执行,进而获得服务器权限。
4.2.3、漏洞分析
本次ThinkPHP 5.0的安全更新主要是在library/think/APP.php文件中增加了对控制器名的限制,而ThinkPHP 5.1的安全更新主要是在library/think/route/dispatch/Module.php文件中增加了对控制器名的限制。
从以上补丁更新可知,该漏洞的根源在于框架对控制器名没有进行足够的检测,从而会在未开启强制路由的情况下被引入恶意外部参数,造成远程代码执行漏洞。
由ThinkPHP的架构可知,控制器(controller)是通过url中的路由进行外部传入的,即/index.php?s=http://www.likecs.com/模块/控制器/操作/[参数名/参数值…],控制器作为可控参数,经过library/think/APP.php文件进行处理,我们跟踪路由处理的逻辑,来完整看一下该漏洞的整体调用链:
首先在run()主函数中,url传入后需要经过路由检查,如下代码所示:
跟进 self::routeCheck 函数
在 620行中调用 $request->path() 函数,该函数位于thinkphp/library/think/Request.php文件中,在该函数中跟进到本文件的$this->pathinfo()函数,在该函数中,就进行url解析,获取路由中的各个部分内容。
其中var_pathinfo参数即为系统默认参数,默认值为s,通过GET方法将获取到的var_pathinfo的值,即s=http://www.likecs.com/模块/控制器/操作/[参数名/参数值…]的内容送到routeCheck()函数中$path参数进行路由检查处理。
继续回到routeCheck()函数: