ThinkPHP<6.0.14版本文件包含漏洞

函数调用链:

9eb60bc8bf233201

 

漏洞成因:

     这个漏洞是有利用条件的,前提是当前的ThinkPHP开启了”多语言”中间件功能。中间件是ThinkPHP中的一个功能,可以用来对请求数据进行过滤处理,请求拦截,自动分发处理等等。很多额外的非核心业务流程的处理都可以交给中间件执行。ThinkPHP中的中间件分为系统中间件和应用中间件,系统中间件为框架自带的内置的中间件。问题出在多语言加载的中间件中(系统中间件),在默认情况下系统中间件都是关闭的,需要手动开启。该中间件功能开启后会根据具体需求自动加载语言包,系统会自动侦测多语言进行自动切换。该中间件在获取用户键入参数时,没有对lang参数进行严格过滤,从而导致了文件包含。

                                                  中间件详细介绍—https://www.php.cn/phpkj/thinkphp/438708.html

 

本地复现:

Version:6.0.12

前提条件:

            开启多语言中间件功能

 

0x01:

          首先在public文件夹下新建test.php文件,用于充当被包含文件测试漏洞是否存在4a47a0db6e225944

 

0x02:

         进到\vendor\topthink\framework\src\think\middleware\LoadLangPack.php文件,中间件在开启的情况下会默认调用其中的handle()方法,在handel方法中调用了detect方法。

fb5c81ed3a230121

         跟进detect方法,langSet变量默认情况下为空,再向下会进入第一个分支获取url中的lang参数,config变量在该中间件类的构造方法中进行了获取,在配置文件中其”detect_var”键的值为”lang”,所以这里获取到了url中的lang参数,并且没有对该参数做任何过滤,直接赋值给了LangSet变量。继续向下,进入分支,”allow_lang_list”默认为空,进入第一个分支LangSet直接被赋值给了Range并返回。

09dd8c2662230443

ff7c346f99230702

 

0x03:

        所以detect方法返回值是可控的lang参数,回到handle方法,再向下调用了defaultLangSet()该方法用于获取当前默认语言默认语言值为”zh-cn”,与传入的可控变量langSet参数进行字符串比较,如果不一样则调用switchLangSet()方法,langSet作为参数进行传递。

8266e4bfed231654

f19c908512232331

 

0x04:

      跟进switchLangSet方法,该方法首先判断参数是否为空,参数不为空继续向下执行。调用load方法,load方法首先获取tp项目路径。再将可控变量$langset直接与其绝对路径进行拼接。最终得到字符串”项目路径+\vendor\topthink\framework\src\lang../../../../public/test.php”,将其作为数组成员传递进load方法。

9eb9cd58b9232544

602e8f042f232550

 

0x05:

      跟进load方法, 到达漏洞触发点,load方法对传入数组进行遍历取值,首先判断该文件是否存在,存在则调用parse()方法,parse方法中判断被包含文件后缀如果为.php结尾则直接使用Include进行包含。

7afbb16026233003

586e508f16233055

利用成功截图:

59b2900aa0233103

© 版权声明
THE END
喜欢就支持一下吧
点赞11 分享