Acronis Cyber Backup <= v12.5 Build 16341 Full Unauthenticated SSRF
Sep 14, 2020 · By Julien Ahrens
ADVISORY INFORMATION
- Product: Acronis Cyber Backup
- Vendor URL: https://www.acronis.com
- Type: Server-Side Request Forgery [CWE-918]
- Date found: 2020-07-30
- Date published: 2020-09-14
- CVSSv3 Score: 8.3 (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:L/A:L)
- CVE: CVE-2020-16171
CREDITS
This vulnerability was discovered and researched by Julien Ahrens from RCE Security.
VERSIONS AFFECTED
Acronis Cyber Backup v12.5 Build 16327 and probably below.
INTRODUCTION
Businesses can be at risk of losing important data. Lost data leads to costly downtime, customer dissatisfaction, regulatory fines, and lost revenue. As a result, IT pros must meet extremely high expectations. You need to keep the company running 24-hours a day.
Acronis Cyber Backup delivers the data protection that meets today’s demands. It keeps your business running, protecting any workload, scaling without limits, and saving you money.
(from the vendor’s homepage)
VULNERABILITY DETAILS
All API endpoints running on port 9877 under “/api/ams/” whereof some are reachable without authentication, do accept an additional custom header called “Shard”:
def get_ams_address(headers):
if 'Shard' in headers:
[...]
return headers.get('Shard') # Mobile agent >= ABC5.0
The value of this header is afterwards to construct a separate web request send by the application using a urllib.request.urlopen call:
def make_request_to_ams(resource, method, data=None):
port = config.CONFIG.get('default_ams_port', '9892')
uri = 'http://{}:{}{}'.format(get_ams_address(request.headers), port, resource)
logging.debug('Making request to AMS %s %s', method, uri)
headers = dict(request.headers)
del headers['Content-Length']
if not data is None:
headers['Content-Type'] = 'application/json'
req = urllib.request.Request(uri,
headers=headers,
method=method,
data=data)
resp = None
try:
resp = urllib.request.urlopen(req, timeout=wcs.web.session.DEFAULT_REQUEST_TIMEOUT)
except Exception as e:
logging.error('Cannot access ams {} {}, error: {}'.format(method, resource, e))
return resp
This can be abused to conduct SSRF attacks against otherwise unreachable internal hosts of Acronis services that are bound to localhost such as the “NotificationService” running on 127.0.0.1:30572 with a request header like:
Shard: localhost:30572/external_email?
For more details, see the referenced blog post.
RISK
The vulnerability can be used by an unauthenticated or authenticated attacker to query otherwise unreachable internal network resources. As demonstrated in the corresponding blog post, using this vulnerability, it is possible to i.e. (amongst others) send out fully customized emails or modify the application’s resource settings.
SOLUTION
Update to v12.5 Build 16342
REPORT TIMELINE
- 2020-07-30: Discovery of the vulnerability
- 2020-07-30: Since the vulnerability is fixed in Cyber Protect: Sent out a request to the Vendor to check whether Cyber Backup is EOL and users are advised to migrate to Cyber Protect instead. date set to 2020-09-14 reference ABR-202103
- 2020-07-30: CVE requested from MITRE
- 2020-07-31: MITRE assigns CVE-2020-16171
- 2020-07-31: Public Disclosure date set to 2020-08-14
- 2020-08-04: Vendor asks for a 90 days extension
- 2020-08-04: Extension not granted because there is a fix available already. Public disclosure
- 2020-09-05: Asking vendor about the status of the fix
- 2020-09-08: Vendor states that a fix has been backported to Cyber Backup 12.5 under the
- 2020-09-14: Public disclosure