从0学代码审计 | thinkphp 5.0.23 RCE

admin 2023年12月19日12:59:27评论46 views字数 2650阅读8分50秒阅读模式

扫码领资料

获网安教程

免费&进群

从0学代码审计 | thinkphp 5.0.23 RCE

从0学代码审计 | thinkphp 5.0.23 RCE

本文由掌 - xilitter 稿

0x01 前言

ThinkPHP 是一款开源的 PHP 框架,用于快速、简单地开发 PHP 应用程序。它提供了一套丰富的功能和工具,使开发者能够更容易地构建各种规模的 Web 应用。ThinkPHP 的目标是提高开发效率,同时保持代码的可读性和可维护性。thinkphp的许多版本中也爆出了多个漏洞,本篇文章主要记录thinkphp 5.0.23版本 RCE的漏洞复现。

0x02 thinkphp RCE分析

thinkphp的开发框架就不说了,RCE的分析会说的详细点,在此只记录这次分析过程中我对于thinkphp的认识。
主要有两个poc,其实都大同小异

poc1

/?s=captcha
POST
_method=__construct&filter[]=system&method=get&get[]=whoami
贴个执行截图
从0学代码审计 | thinkphp 5.0.23 RCE
还有类似验证码的图片,怎么来的
下断点调试,打入poc看看thinkphp内部的一个执行流程。
断点下在哪,thinkphp框架都有一个入口文件index.php,在public目录下,既然我们要在该文件下传数据,那么就在该文件下断点。
从0学代码审计 | thinkphp 5.0.23 RCE
这里会调用 start.php 引导文件
从0学代码审计 | thinkphp 5.0.23 RCE
执行app.php的run方法,app.php用于配置应用程序的全局设置和参数,我们跟进run方法,跟进之后会进入到Loader.php,
从0学代码审计 | thinkphp 5.0.23 RCE
这里判断是否存在对应的类文件,是否是windows环境,然后就包含这个文件。
从0学代码审计 | thinkphp 5.0.23 RCE
接下来进入到run方法,这里会创建一个Request类的实例,Request 就是处理请求的类,继续跟进
从0学代码审计 | thinkphp 5.0.23 RCE
又需要 Loader 去包含,然后走到Request类的构造方法
从0学代码审计 | thinkphp 5.0.23 RCE
这里将POST数据写入到input变量里,
从0学代码审计 | thinkphp 5.0.23 RCE
创建完Request实例后,进入到 routeCheck 方法里
从0学代码审计 | thinkphp 5.0.23 RCE
这里获取到path,跟进方法
从0学代码审计 | thinkphp 5.0.23 RCE
这里做了一个判断,从Config类里获取到varpathinfo的值,然后检查$_GET全局变量里是否存在这个变量,我们不妨跟进这个get方法去看一下
从0学代码审计 | thinkphp 5.0.23 RCE
$range是_sys
,name属性的值就是var_pathinfo,对应config默认值就是s
那么所获取到的path就是captcha 然后走到路由检查这块地方
从0学代码审计 | thinkphp 5.0.23 RCE
时刻关注与request有关的代码,因为可控的地方只有我们请求的数据
这里跟进到check方法
从0学代码审计 | thinkphp 5.0.23 RCE
在857行这里,执行的request实例的 method 方法
从0学代码审计 | thinkphp 5.0.23 RCE
这里,在config配置类中var_method的默认值就是
从0学代码审计 | thinkphp 5.0.23 RCE
然后从$_POST全局变量中找键名为_method的值,这里存在任意函数调用,很关键,我们当前所传的值就是request类的构造方法,这里跟进
从0学代码审计 | thinkphp 5.0.23 RCE
遍历键值对,然后判断键名在当前类中是否存在,若存在,就覆盖掉键值。
实际上该类的filter属性是没有空的,我们传的 filter[]=system 会在此刻覆盖掉原有的值,参数值的覆盖同理,又是一个关键的一步。poc中method=get 是将 method 的值给改回来,防止报错。
从0学代码审计 | thinkphp 5.0.23 RCE
走到App类的exec方法,应该对应路由的调用,跟进
从0学代码审计 | thinkphp 5.0.23 RCE
这里会走到这个分支,还像是captcha路由影响的,至于为什么,代码还没调出来,先留个坑。
然后跟进到 param 方法
从0学代码审计 | thinkphp 5.0.23 RCE
$this->mergeParam 为true,进入不到 if 里面,那么进入到input方法
首先是对$name做一些格式 上的处理
从0学代码审计 | thinkphp 5.0.23 RCE
然后判断$data是否为数组,满足条件就调用 filterValue 方法,此时的$data和$filter为
从0学代码审计 | thinkphp 5.0.23 RCE
从0学代码审计 | thinkphp 5.0.23 RCE
弹出filter数组的最后一个元素,然后遍历数组,call_user_func函数调用达到任意命令执行的目的。

poc2

大同小异
?s=captcha
POST
_method=__construct&filter[]=system&method=get&server[REQUEST_METHOD]=whoami
在 param 方法中
从0学代码审计 | thinkphp 5.0.23 RCE
又有一处method方法的调用,不过参数设置为true了,跟进
从0学代码审计 | thinkphp 5.0.23 RCE
调用了 server 方法,参数是 REQUEST_METHOD
从0学代码审计 | thinkphp 5.0.23 RCE
最后也会走到input,任意函数调用。
补坑
来补坑了,写完这篇文章之后不甘心,打算又调一下代码,这次算是调明白了。
坑:为什么要get传一个 ?s=captcha
结论:为了方便使 $dispatch=method 从而进入 Request::instance()->param(),当时不懂,为什么传一个captcha 就能让$dispatch=method???
从0学代码审计 | thinkphp 5.0.23 RCE
就是在这里,所对应的$dispatch[‘type’]就是method
从0学代码审计 | thinkphp 5.0.23 RCE
继续往上跟,看它是由什么赋值
从0学代码审计 | thinkphp 5.0.23 RCE
在118行,调用routeCheck方法获取路由调度,这个方法返回的是 $result 那么继续看$result是由谁赋值
从0学代码审计 | thinkphp 5.0.23 RCE
路由检查方法的返回值赋给 $result 调试跟的话实际上会走到这里
从0学代码审计 | thinkphp 5.0.23 RCE
那么就需要看checkRoute函数的返回值了
从0学代码审计 | thinkphp 5.0.23 RCE
此时遍历$rules的下标,有两个元素
从0学代码审计 | thinkphp 5.0.23 RCE
拆分,解析路由相关参数
从0学代码审计 | thinkphp 5.0.23 RCE
然后跟进到这个函数
从0学代码审计 | thinkphp 5.0.23 RCE
在这个match函数里,将 $rule 的内容以斜杠分隔符拆分为数组,然后遍历,经过一系列的判断
从0学代码审计 | thinkphp 5.0.23 RCE
这是一个关键点,这里判断$val 和 $m1[$key] 是否不相等,若不相等,返回非0,然后会 return false;所以在get传参上,一定要让s=captcha,至于为什么是参数s,因为在config类中默认参数就是s了。
这里进入不了 elseif 就会遍历下一个元素,
从0学代码审计 | thinkphp 5.0.23 RCE
成功匹配后就会调用到 parseRule函数来解析路由
从0学代码审计 | thinkphp 5.0.23 RCE
最后就是让 $dispatch[‘type’]=method了,回到了结论。
而如果我们get传入的不是 captcha,在match函数匹配规则的时候就会返回false,然后一路返回false
从0学代码审计 | thinkphp 5.0.23 RCE
进入到这个if条件,然后调用 parseUrl 函数
从0学代码审计 | thinkphp 5.0.23 RCE
最后返回的 type 是module,在主要执行流中就走不到call_user_func函数了。

0x03 结语

thinkphp没有对用户输入的方法名进行过滤和限制,导致可以任意函数调用,(此时的任意函数只是在Request类中)调用Request类的构造方法达到变量覆盖,最终call_user_func任意代码执行。
主要还是多调试才能理解poc的执行过程。

申明:本公众号所分享内容仅用于网络安全技术讨论,切勿用于违法途径,

所有渗透都需获取授权,违者后果自行承担,与本号及作者无关,请谨记守法.

从0学代码审计 | thinkphp 5.0.23 RCE

原文始发于微信公众号(掌控安全EDU):从0学代码审计 | thinkphp 5.0.23 RCE

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年12月19日12:59:27
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   从0学代码审计 | thinkphp 5.0.23 RCEhttp://cn-sec.com/archives/2313539.html

发表评论

匿名网友 填写信息