漏洞深度分析|Thinkphp 多语言 RCE

项目介绍

ThinkPHP 是一个快速、简单的面向对象的轻量级 PHP 开发框架,创立于2006年初,遵循Apache2开源协议发布,是为了敏捷WEB应用开发和简化企业应用开发而诞生的。

根据目前FOFA系统最新数据(一年内数据),显示全球范围内(header="think_lang")共有 73,302 个相关服务对外开放。中国使用数量最多,共有44,788 个;美国第二,共有 12,295;中国香港特别行政区第三,共有5,009 个;新加坡第四,共有 896 个;日本第五,共有 246 个。

项目地址

https://www.thinkphp.cn/

漏洞概述

如果 Thinkphp 程序开启了多语言功能,攻击者可以通过 get、header、cookie 等位置传入参数,实现目录穿越+文件包含,通过 pearcmd 文件包含这个 trick 即可实现 RCE。

默认情况下,系统只会加载默认语言包,如果需要多语言自动侦测及自动切换,需要在全局的中间件定义文件中添加中间件定义。因此只有启用多语言并且使用存在漏洞的版本时才存在漏洞。

影响版本

v6.0.1 < Thinkphp < v6.0.13

Thinkphp v5.0.x

Thinkphp v5.1.x

环境搭建

docker run -it -d -p 80:80 vulfocus/thinkphp:6.0.12

漏洞复现

漏洞深度分析|Thinkphp 多语言 RCE_第1张图片

 漏洞深度分析|Thinkphp 多语言 RCE_第2张图片

漏洞分析

这里以thinkphp 6为例进行分析,thinkphp 5类似。

Thinkphp的中间件默认会调用handle函数,因此直接在LoadLangPack.php的handle函数中下断点

漏洞深度分析|Thinkphp 多语言 RCE_第3张图片

在detect函数中会从request中提取多个参数

漏洞深度分析|Thinkphp 多语言 RCE_第4张图片

查看config可知,detect就是从请求的不同位置中提取lang等参数         漏洞深度分析|Thinkphp 多语言 RCE_第5张图片

默认情况下,allow_lang_list 这个配置为空,因此从lang参数中拿到的变量没有过滤直接传给了$this->range并返回该值

漏洞深度分析|Thinkphp 多语言 RCE_第6张图片

得到lang值之后,会调用switchLangSet函数加载对应的语言。在该函数中会先根据$langset拼接路径(这里我们就可以目录穿越),然后调用load进行加载

漏洞深度分析|Thinkphp 多语言 RCE_第7张图片

在load函数中调用了parse,处理上面拼接过的文件

漏洞深度分析|Thinkphp 多语言 RCE_第8张图片

在parse中可以看到,当后缀为php时直接include

漏洞深度分析|Thinkphp 多语言 RCE_第9张图片

因此攻击者可以通过目录穿越实现任意 php 文件的包含

分析了官方的修复方式,发现官方通过两个commit修复了此漏洞,核心改动如下,即判断了$langSet是否满足条件否则获取默认值:

漏洞深度分析|Thinkphp 多语言 RCE_第10张图片

修复方式

官方已经发布最新版,请升级到最新版

参考链接

删除废弃方法 优化多语言检测 · top-think/framework@c4acb8b · GitHub

调整 · top-think/framework@4c328dc · GitHub

Thinkphp 多语言 RCE - 跳跳糖

Docker PHP裸文件本地包含综述 | 离别歌

https://nosec.org/home/detail/5050.html

你可能感兴趣的:(漏洞深度分析,php,开发语言)