CVSS3
Attack Vector
NETWORK
Attack Complexity
LOW
Privileges Required
NONE
User Interaction
NONE
Scope
UNCHANGED
Confidentiality Impact
HIGH
Integrity Impact
HIGH
Availability Impact
HIGH
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
AI Score
Confidence
High
EPSS
Percentile
95.2%
Remote command execution due to use of default passwords. The following products are affected: Acronis Cyber Infrastructure (ACI) before build 5.0.1-61, Acronis Cyber Infrastructure (ACI) before build 5.1.1-71, Acronis Cyber Infrastructure (ACI) before build 5.2.1-69, Acronis Cyber Infrastructure (ACI) before build 5.3.1-53, Acronis Cyber Infrastructure (ACI) before build 5.4.4-132.
Recent assessments:
h00die-gr3y at September 15, 2024 5:15pm UTC reported:
On 24 July, Acronis published the security advisory SEC-6452: Remote command execution due to use of default passwords where default passwords are exploited to gain admin access to the Acronis Cyber Infrastructure. It was also reported by Acronis that this vulnerability was actively exploited by cyber criminals and patched 9 months ago.
If you search for actual examples of the exploit, no detailed technical publications are available, so I thought let’s give it a go and figure out what this vulnerability is all about.
So I downloaded a Acronis Cyber Infrastructure (ACI) appliance 4.7
from their website and installed it on VirtualBox (see this article).
After completing the installation process, you access the Acronis Web Portal on port 8888 via HTTPS with the admin credentials set during the installation. You can also the access the appliance directly by logging in as root. These credentials are also asked and set during the installation process. This is of course very helpful to analyze the server image because you have full access to appliance and the installed software.
So lets start the search for our default passwords!!!
Let’s check first the user credentials available on the appliance itself by checking the /etc/password
and /etc/shadow
files.
Not much to gain here. The only password hash available in the /etc/shadow
file is for user root
which is set during the initial setup of the ACI appliance.
Next in line is to investigate the user credentials available in the Acronis Web Portal.
If you login as admin, you will find in the settings->user and projects
section, three default users:
admin
backup-service-user
vstorage-service-user
User admin credentials are set during the installation process so that rules out the default password.
Both the backup-service-user and storage-service-user are potential candidates where the storage-service-user is the most promising candidate because this user is default enabled and has the role system-administrator assigned.
The appliance has a PostgreSQL DB that stores all configuration information. The users, passwords and roles are stored in the keystone
database.
You can easily query the database by logging into the appliance as root and switch to the postgres
user and access the database with psql
.
Acronis Cyber Infrastructure release 4.7
========================================================================
= Warning! Do not enable third-party repositories. Install third-party =
= software only from the default repository. Use only commands allowed =
= in the product documentation. =
========================================================================
[root@aci-471-53 ~]# su postgres
bash-4.2$ psql
could not change directory to "/root": Permission denied
psql (11.16)
Type "help" for help.
postgres=# \l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
------------+------------+----------+-------------+-------------+-----------------------
coredns | coredns | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
grafana | grafana | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
keystone | vstoradmin | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
postgres | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
template0 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres +
| | | | | postgres=CTc/postgres
vstoradmin | vstoradmin | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
(7 rows)
postgres=# \c keystone
You are now connected to database "keystone" as user "postgres".
keystone=# select * from "local_user";
id | user_id | domain_id | name | failed_auth_count | failed_auth_at
----+----------------------------------+-----------+-----------------------+-------------------+----------------
1 | a56cc7f698fa41d99d1c9dd22aa73580 | default | vstorage-service-user | 0 |
2 | 57bf107a224145c6a1217c71da5f4911 | default | backup-service-user | |
3 | fad1606d29a64ff6b7c45b1128551a97 | default | admin | 0 |
(3 rows)
keystone=# select * from "password";
id | local_user_id | expires_at | self_service | password_hash | created_at_int | expires_at_int | created_at
----+---------------+----------------------------+--------------+--------------------------------------------------------------+------------------+------------------+----------------------------
1 | 1 | 2024-08-05 11:31:58.573171 | f | $2b$12$/.ZPGchRUlOGJcNO2S.bOOF3ykww0vShNEr/jwZxvQtksCzGHYcrO | 1653058897767616 | 1722857518573171 | 2022-05-20 15:01:37.767616
2 | 1 | | f | $2b$12$YKyODw1N3mTO9qj7ch1h6O2qZQGjSgW/CIKyQ2Tz7A49sJvHI0r/q | 1722857518573171 | | 2024-08-05 11:31:58.573171
3 | 3 | | f | $2b$12$3PT2/rbf4rkNBPThiZclyeD/FFP5UXLs4bTfg0L27LeSjqyxNQ2xO | 1722857529542615 | | 2024-08-05 11:32:09.542615
(3 rows)
We can query the users and the password hashes, which is promising but “Are these default passwords?”, and if yes, “What is the password?”
To answers these questions, we need to dig a bit deeper within the appliance and figure out what happens during the initial installation and configuration setup of the appliance.
One very interesting directory is /usr/libexec/vstorage-ui-backend/libexec
that holds most of initial configuration shell scripts called during the installation of the appliance.
[root@aci-471-53 libexec]# pwd
/usr/libexec/vstorage-ui-backend/libexec
[root@aci-471-53 libexec]# ls
alua-functions.sh keystone-service-init.sh oneshot-0021-enable-russian-language.sh
bouncer-functions.sh logging.sh oneshot-cleanup-wal-archive.sh
check-backend.sh oneshot-0008-upgrade-to-roles-sets.sh oneshot-disable-wal-archiving.sh
clear-vips.sh oneshot-0009-upgrade-db.sh oneshot-init-keystone.sh
db-functions.sh oneshot-0010-disable-pghba-ident-entry.sh oneshot-migrate-roles-to-agent.sh
dns-functions.sh oneshot-0011-init-coredns.sh on-master.sh
functions.sh oneshot-0012-enable-ha-for-postgresql.sh on-standby.sh
gen-certificate.sh oneshot-0013-clean-up-mdses-in-order-to-add-dns-srv-recs.sh pg-convert-layout.sh
ha-ovh-setup oneshot-0014-create-self-service-roles-in-keystone.sh pg-scripts.sh
ha-ovh-teardown oneshot-0015-clean-up-mdses-in-order-to-activate-vstorage-target-manager.sh pg-switch-to-hot-standby.sh
ha-scripts.sh oneshot-0016-update-internal-endpoint-in-keystone.sh pg-switch-to-master.sh
init-backend.sh oneshot-0017-create-roles-implication-in-keystone.sh set-vips.sh
init-grafana.sh oneshot-0018-create-backup-service-user.sh takeover-management-node.sh
init-postinstall.sh oneshot-0019-create-compute-cert.sh utils-functions.sh
keystone-functions.sh oneshot-0019-enable-postgres-backup.sh uwsgi-backend-stop.sh
keystone-gen-env.sh oneshot-0020-turn-off-aip-early-access.sh
[root@aci-471-53 libexec]#
I am not gonna dwell on all scripts, but the oneshot-init-keystone.sh
is an interesting script to explore what is happening during initial installation.
#!/usr/bin/env bash
#set -x
. ~vstoradmin/libexec/logging.sh
LOG_FILE="/var/log/vstorage-ui-backend/init_keystone.log"
BACKEND_CONFIG=/usr/libexec/vstorage-ui-backend/etc/backend.cfg
log_init "${LOG_FILE}"
exec &>>"${LOG_FILE}"
. ~vstoradmin/libexec/db-functions.sh
. ~vstoradmin/libexec/keystone-functions.sh
grep -q -w "KEYSTONE_SERVICE_PASSWORD" ${BACKEND_CONFIG} || init_keystone
It calls two other scripts db-functions.sh
and keystone-functions.sh
which are worthwhile to explore and the last grep
command is very interesting where a KEYSTONE_SERVICE_PASSWORD
is queried from the file /usr/libexec/vstorage-ui-backend/etc/backend.cfg
.
We are getting closer…
If we check the file /usr/libexec/vstorage-ui-backend/etc/backend.cfg
it actually reveals the password of the vstorage-service-user!!!
KEYSTONE_USER_MIGRATION=True
KEYSTONE_SERVICE_USER='vstorage-service-user'
KEYSTONE_SERVICE_PASSWORD='3bfda47e79d62f7798e38acc7ff6'
KEYSTONE_SERVICE_PROJECT='admin'
KEYSTONE_ENDPOINT='https://127.0.0.1:5000/v3'
Is this the famous default password? Mmm, this looks too simple…
Let’s check how this password is ending up in this config file.
Let’s explore the other two scripts.
Browsing thru keystone-functions.sh
the first function gen_keystone_passwd()
already shows that the password gets randomly generated with openssl
for the vstorage-service-user
. This looks like a dead-end street.
function gen_keystone_passwd() {
sudo -u vstoradmin openssl rand -hex 14 2>/dev/null
[ $? -ne 0 ] && error "Unable to generate password for keystone service user" || :
}
But…
After exploring the second script db-functions.sh
, interesting new information is revealed because it seems that during the creation and configuration of the database, default passwords are indeed being used.
configure_db() {
log_inf "Configure database..."
create_user "vstoradmin" "CREATEDB CREATEROLE LOGIN REPLICATION PASSWORD 'vstoradmin'"
create_database "vstoradmin" "vstoradmin"
log_inf "Database has been configured"
}
Database user vstoradmin
seems to have a default password vstoradmin.
That is really interesting, so let’s validate this in the database by querying the passwords for these DB users which are stored in the postgres database table below.
postgres=# select * from "pg_authid";
rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil
---------------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------------------------------+---------------
postgres | t | t | t | t | t | t | t | -1 | |
pg_monitor | f | t | f | f | f | f | f | -1 | |
pg_read_all_settings | f | t | f | f | f | f | f | -1 | |
pg_read_all_stats | f | t | f | f | f | f | f | -1 | |
pg_stat_scan_tables | f | t | f | f | f | f | f | -1 | |
pg_read_server_files | f | t | f | f | f | f | f | -1 | |
pg_write_server_files | f | t | f | f | f | f | f | -1 | |
pg_execute_server_program | f | t | f | f | f | f | f | -1 | |
pg_signal_backend | f | t | f | f | f | f | f | -1 | |
vstoradmin | f | t | t | t | t | t | f | -1 | md5dc23b46758bc7e2c4d3d19493c492aae |
coredns | f | t | f | f | t | f | f | -1 | md56e2738b0f8848df4ed98977974c83a7e |
grafana | f | t | f | f | t | f | f | -1 | |
(12 rows)
We can see the md5 hashed passwords in the table for user vstoradmin
and coredns
which are in the typical PostgreSQL format of the string “md5” followed by the md5 hash of a string comprised of the password followed by the postgres username.
Let’s use this logic and check if these accounts are using default passwords with hashcat
.
# cat md5.hash
6e2738b0f8848df4ed98977974c83a7e
dc23b46758bc7e2c4d3d19493c492aae
# cat password.txt
vstoradminvstoradmin
corednscoredns
# hashcat --show -a 0 -m 0 md5.hash password.txt
6e2738b0f8848df4ed98977974c83a7e:corednscoredns
dc23b46758bc7e2c4d3d19493c492aae:vstoradminvstoradmin
Or you can do the other way around .
[root@aci-471-53 libexec]# echo -n "md5"; echo -n "vstoradminvstoradmin" | md5sum | awk '{print $1}'
md5dc23b46758bc7e2c4d3d19493c492aae
[root@aci-471-53 libexec]# echo -n "md5"; echo -n "corednscoredns" | md5sum | awk '{print $1}'
md56e2738b0f8848df4ed98977974c83a7e
[root@aci-471-53 libexec]#
And BINGO, the md5 hashed passwords are matching and we have found default passwords!!!
The final confirmation is to validate a patched version of the Acronis Cyber Infrastructure and check if these flaws have been mitigated.
Checking the db-functions.sh
on a patched ACI 5.0.1-61
appliance, shows that no default password is set in the configure_db()
function.
configure_db() {
log_inf "Configure database..."
create_user "vstoradmin" "CREATEDB CREATEROLE LOGIN REPLICATION"
create_database "vstoradmin" "vstoradmin"
log_inf "Database has been configured"
}
Also the pg_auth
table in the postgres database does not show any passwords for the vstoradmin
and coredns
database users.
This confirms that the use of default passwords for these accounts have been mitigated.
postgres=# select * from "pg_authid";
rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvalidu
ntil
---------------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+----------
-----
postgres | t | t | t | t | t | t | t | -1 | |
pg_monitor | f | t | f | f | f | f | f | -1 | |
pg_read_all_settings | f | t | f | f | f | f | f | -1 | |
pg_read_all_stats | f | t | f | f | f | f | f | -1 | |
pg_stat_scan_tables | f | t | f | f | f | f | f | -1 | |
pg_read_server_files | f | t | f | f | f | f | f | -1 | |
pg_write_server_files | f | t | f | f | f | f | f | -1 | |
pg_execute_server_program | f | t | f | f | f | f | f | -1 | |
pg_signal_backend | f | t | f | f | f | f | f | -1 | |
vstoradmin | f | t | t | t | t | t | f | -1 | |
coredns | f | t | f | f | t | f | f | -1 | |
grafana | f | t | f | f | t | f | f | -1 | |
(12 rows)
postgres=#
Now we want to understand how we can exploit this vulnerability.
After digging into the keystone
db with the privileges of the vstoradmin
user, it already shows that we can easily add a new administrative user by editing it directly in the keystone
database. This administrative user allows us to upload ssh-keys via the ACI Web Portal that enables direct root access via SSH to the appliance.
You will need access to Acronis Web Portal, the PostgreSQL database and the SSH service, but if these three services are available and accessible from the outside world, you can easily hack yourself into any non-patched ACI appliance as user root.
I have created an Metasploit module that does all the magic for you.
You can find this module in Metasploit as PR 19463 – Acronis Cyber Infrastructure default password remote code execution.
You should patch your ACI appliance immediately following the Acronis security advisory SEC-6452.
CVE-2023-45249
Acronis security advisory SEC-6452
Acronis ACI Downloads
Metasploit PR 19463 – Acronis Cyber Infrastructure default password remote code execution
Assessed Attacker Value: 5
Assessed Attacker Value: 5Assessed Attacker Value: 4
CVSS3
Attack Vector
NETWORK
Attack Complexity
LOW
Privileges Required
NONE
User Interaction
NONE
Scope
UNCHANGED
Confidentiality Impact
HIGH
Integrity Impact
HIGH
Availability Impact
HIGH
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
AI Score
Confidence
High
EPSS
Percentile
95.2%