Arbitrary file upload vulnerability in WordPress Ultimate Member plugin.

Updated: August 9, 2018

Update: A new version 2.0.22 of Ultimate Member has just been released, consider updating as soon as possible

As we mentioned earlier today, a critical vulnerability in the popular Ultimate Member plugin v2.0.21 (100k+ active installations) allows attackers to upload any files, including PHP backdoors. This is a 0day vulnerability, which means there is no patch available yet.
We saw the first hacking attempts on Tuesday, August 7th. Here’s a log sample showing hackers probing a WordPress installation:

31.211.86.13 - - [07/Aug/2018:13:09:05 +0200] "GET /um-api/route/um!core!Files/ajax_image_upload/1234123412 HTTP/1.1"
128.199.157.152 - - [07/Aug/2018:15:26:12 +0200] "GET /um-api/route/um!core!Files/ajax_image_upload/1234123412 HTTP/1.1"
93.189.36.111 - - [07/Aug/2018:18:06:48 +0200] "GET /um-api/route/um!core!Files/ajax_image_upload/1234123412 HTTP/1.1"

PHP backdoors are uploaded inside one or more wp-content/uploads/ultimatemember/temp/ sub-folders and named stream_photo_XXX_YYY.php where XXX is a MD5 hash of the filename and YYY is the value returned by the PHP uniqid() function. Although the original name is changed by Ultimate Member, the original .php extension isn’t. Because the uploaded image contains PHP code and the full URL to the newly created file is returned as a json-encoded string right after the upload, it can be executed from a browser. Note that this requires a specifically crafted image because Ultimate Member will modify it using some image manipulation functions that could remove the PHP code otherwise.

It is extremely easy to exploit this vulnerability, e.g., with a simple command line application such as curl. I won’t provide a POC as there is no fix yet.

If you are using our NinjaFirewall WAF for WordPress:

  • Make sure you have the latest security rules: Go to “NinjaFirewall > Rules Update” and click “Check for updates now!”.
  • If you don’t need uploads, disable uploads from the Firewall Policies page. If you have the premium WP+ Edition and want to keep uploads enabled, you can restrict them with the “Allow, but block dangerous files” policy, it will block scripts (PHP, CGI, Ruby, Python, bash/shell), C/C++ source code, binaries (MZ/PE/NE and ELF formats), system files (.htaccess, .htpasswd and PHP INI) and SVG files containing Javascript/XML events.

Note that by default, NinjaFirewall has a spoofed MIME-type protection and will never allow access to a PHP script located inside the wp-content/uploads/ folder or any of its sub-folders.