Critical Vulnerability Disclosed on WordPress Custom Contact Forms Plugin

If you’re a using the Custom Contact Forms WordPress plugin, you need to update it right away.

During a routine audit for our WAF, we found a critical vulnerability that allows an attacker to download and modify your database remotely (no authentication required).

The vulnerability was disclosed to the plugin developer a few weeks ago, they were unresponsive. The developers were unresponsive so we engaged the WordPress Security team. They were able to close the loops with the developer and get a patch released, you might have missed it:

Sucuri - Custom Contact Form Crictial Vulnerability

Who’s affected

This plugin has more than 600,000 downloads and the vulnerability affects every websites using the plugin’s 5.1.0.3 version and lower. As we said before, it allows an attacker to take control of a victim’s website without requiring any sort of privileges/accounts beforehand.

Technical details

It all started when we came upon these lines of code (remember is_admin?):

if (!is_admin()) { /* is front */
require_once(‘custom­contact­forms­front.php’);
$custom_contact_front = new CustomContactFormsFront();

(…)
} else { /* is admin */

$GLOBALS['ccf_current_page'] = (isset($_GET['page'])) ? $_GET['page'] : ”;
require_once(‘custom­contact­forms­admin.php’);
$custom_contact_admin = new CustomContactFormsAdmin();

(…)
add_action(‘init’, array(&$custom_contact_admin, ‘adminInit’), 1);

(…)
}

As you can see, it creates a new instance of the CustomContactFormsAdmin class whenever a user is viewing one page in /wp­admin/. We hurried to look at this class’s adminInit() function, just in case some sensitive functionalities would be hidden in there, and it turns out there were:

function adminInit() {

$this­>downloadExportFile();
$this­>downloadCSVExportFile();
$this­>runImport();
}

Scary names, no?

After a brief analysis, we found out that the downloadExportFile() function was used to generate and download a SQL dump of the plugin’s parameters, whereas the runImport() was doing the opposite, importing a SQL backup to the database!

Those familiar with WordPress know that all of the table names and some of WordPress’s important option fields names are “protected” by a database prefix set in the website’s wp-config.php file. That said, it is of no use here as we can download a SQL dump of the plugin’s parameters which contains this piece of information!

Anybody could alter the SQL dump, adding their own queries to create a new administrative user or modify anything that is stored in the database.

Protect yourself

This vulnerability is categorized as Critical. You need to update the Custom Contact Forms now, to its latest version asap, and if you’re seeing symptoms of a hack, get in touch with us immediately so we can clean your site..

Users of our website firewall (CloudProxy) product are already protected against this threat via our virtual patching.

Due to the unresponsive nature of the development team, we’d encourage you to pursue other sources for your WordPress form needs. There are various options with developers that are very responsive and are actively concerned with your security needs. The most common and popular ones would obviously be JetPack and Gravity Forms.

Scan your website for free:
About Marc-Alexandre Montpas

His passion for code and IT security got no limit. You'll generally find him competing in some security capture-the flag competitions or searching for security vulnerabilities in widespread products for the fun of it. He's also a great fan of heavy-metal music.

  • https://www.mensmaximus.de/ Michael Weichselgartner

    I came across some hacked sites lately where all files got encrypted. Those files carry .locked as suffix. As for now I am not sure whether the hackers used an old vulnerability due to outdated WordPress installations or a new exploit like this one to gain access to the admin area.

    • test

      test

  • yasir

    “>

  • jdvfj
  • jdvfj

    “>

  • xcbvc

    cbjdsfh