Horizon3.ai
Horizon3.ai

Ivanti Sentry Authentication Bypass CVE-2023-38035 Deep Dive

by | Aug 24, 2023 | Attack Blogs

Introduction

Ivanti has recently published an advisory for CVE-2023-38035. The vulnerability has been added to CISA KEV and is described as an authentication bypass in the Ivanti Sentry administrator interface. This new vulnerability comes on the heels of an in-the-wild-exploited vulnerability in Ivanti EPMM (CVE-2023-35078). In this post we will take a deep dive into how this new vulnerability can be used to give an attacker the ability to remotely execute code as the root user. You can find our PoC here.

Patch Diffing

The advisory contains rpm files that we can use to patch supported versions of Ivanti Sentry. We use the tool rpm2cpio to examine the contents of these files to start to get an idea of how the patch works.

rpm2cpio sentry-security-update

rpm2cpio sentry-security-update

We find two more rpm files, one described as mi-mics and another described as mi-system-scripts. Let’s see what’s in the mi-mics rpm.

rpm2cpio mi-mics

rpm2cpio mi-mics

From this file listing, we are quickly drawn to mics.war. We assume that mics.war contains majority of the code for the Sentry web interface. Next, let’s pull a vulnerable mics.war from a live system and compare the contents.

mics.war diff

mics.war diff

Luckily for us, there aren’t that many differences considering we are comparing Sentry version 9.12 with 9.18. After some digging, we notice that a service has been removed from the remoting-servlet.xml file.

remoting-servlet.xml diff

remoting-servlet.xml diff

We also see that the endpoint for services/ has no authentication requirements.

cat security.xml

cat security.xml

We see that the removed service should expose the interface described by com.mi.middleware.service.ConfigService and should be implemented in the configServiceHandler class. Let’s see if we can find those classes.

grep for com.mi.middleware.service.ConfigService

grep for com.mi.middleware.service.ConfigService

grep for configServiceHandler

grep for configServiceHandler

It appears we can find the ConfigService interface in common-10.6.0.1s-1.jar and the implementing class, configServiceHandler, in mics-core-9.12.0-R9.12.0.jar. Let’s see what interface the service offers.

Config Service Interface

Config Service Interface

Hessian RPC

Let’s take a step back and see how we are supposed to call these functions. We know from the advisory that this should be an HTTP vulnerability, but these functions don’t look like your typical HTTP endpoints. If we look back at remoting-servlet.xml from earlier we see that this service references a class called SentryMicsHessianServiceExporter. We have never heard of Hessian before, but after some searching on the internet it appears to be a type of binary/XML RPC. http://hessian.caucho.com/doc/

We can use the python-hessian package to try to connect this this service.

python-hessian

python-hessian

Here, we can see that its pretty easy to call methods from this service. The only complicating factor is that there doesn’t seem to be an easy way to disable SSL certificate checking. To get around this, we monkey patch HTTPSConnection used by python-hessian.

Close, but no Cigar

At first, it seems like there is a command injection in the doMICSServiceOperation endpoint. This endpoint ultimately calls Java’s Runtime.exec with attacker controlled arguments. However, it is really just an argument injection, not a full command injection. The endpoint passes the string /usr/bin/sudo /sbin/service <attacker input> <attacker input> to Runtime.exec. It appears on this system, Runtime.exec does not run this command through a shell so the normal bash command substitutions won’t work. It seems challenging to get RCE using this attack path. Shifting our attention, we notice that there are some changes to httpd configuration files for similar hessian endpoints.

httpd configuration changes

httpd configuration changes

Let’s take a look at the MICSLogService.

MICSLogService Command Injection

After some searching, we find an interesting method named uploadFileUsingFileInput

uploadFileUsingFileInput

uploadFileUsingFileInput

This function takes a SystemCommandRequestDTO and passes it to a thread (new 1(this,requestDTO), this is a decompiler artifact). Let’s take a look at what this thread does.

exec thread

exec thread

We can see on line 44, attacker controlled input is passed into rt.exec. This time, our input is passed directly to the function so we don’t have to worry about not having shell parsing like last time. We just need to figure out how to pass a SystemCommandRequestDTO which has the following form.

SystemCommandRequestDTO

SystemCommandRequestDTO

We can simply pass a Python dictionary with the same layout. Our updated PoC now looks like this with a curl payload.

new PoC

new PoC

Indicators of Compromise

There aren’t any definitive IoCs that we have found so far. However, any unrecognized HTTP requests to /services/* should be cause for concern. The endpoint that we exploited is likely not the only one that would allow an attacker to take control of the machine.

Ivanti Sentry doesn’t offer a standard Unix shell, but if a known exploited system is being forensically analyzed, /var/log/tomcat2/contains access logs that can be used to check which endpoints were accessed.

Lastly, there are logs in the web interface that might be of use to check for any suspicious activity.

GUI logs

GUI logs

Summary

We were able to successfully utilize an exposed endpoint to execute arbitrary commands without any authentication. Shodan shows that this product has over 500+ instances exposed on the internet.

Shodan

Shodan

We recommend that any affected users of this product apply the patch for their version and verify that it is not exposed externally to the internet if possible.

How can NodeZero help you?

Let our experts walk you through a demonstration of NodeZero, so you can see how to put it to work for your company.