Code audit | Zoho never authorized access to remote RCE

Author: Z1NG (core member of Xin'an Road, good at code audit and red team technology)

ZOHO ManageEngine ServiceDesk Plus (SDP) is a set of IT software based on ITIL architecture of American ZOHO company. The software integrates functional modules such as event management, problem management, asset management, IT project management, procurement and contract management.

The countries using the system are mainly foreign countries, such as the query results of fofa:

Let's analyze the cause of CVE-2021-44077 vulnerability, starting with unauthorized access.

0x01 unauthorized access

According to web From the XML file, you can see that all requests of the rest API are handled by struts:

  <servlet>
    <servlet-name>action</servlet-name>
    <servlet-class>
      org.apache.struts.action.ActionServlet
    </servlet-class>
  <servlet-mapping>
    <servlet-name>action</servlet-name>
    <url-pattern>/RestAPI/*</url-pattern>
  </servlet-mapping>

There is also a section of configuration. According to the comments, the following URL needs login authentication. For example, XXX do:

  <!-- Login required for the following URLs -->
  <security-constraint>
    <web-resource-collection>
      <web-resource-name>Secured Core Context</web-resource-name>
      <!--url-pattern>/jsp/*</url-pattern-->
      <url-pattern>*.do</url-pattern>
            <url-pattern>/app</url-pattern>
            <url-pattern>/ui/*</url-pattern>
      <url-pattern>*.cc</url-pattern>
      <url-pattern>*.ls</url-pattern>
      <url-pattern>/SoftwareFileUploader.up</url-pattern>
      <url-pattern>/WOResolutionFileUploader.up</url-pattern>
      <url-pattern>*.json</url-pattern>
      <url-pattern>*.jsp</url-pattern>
      <url-pattern>/servlet/*</url-pattern>
      <url-pattern>/ze/*</url-pattern>
      <url-pattern>/aplusinteg</url-pattern>
      <url-pattern>/RestAPI/WC/TwoFactorAction</url-pattern>
    </web-resource-collection>
    <auth-constraint>
      <role-name>*</role-name>
    </auth-constraint>
  </security-constraint>

A URL that does not require login is also configured:

<!-- Login not required for the following URLs -->
  <security-constraint>
    <web-resource-collection>
      <web-resource-name>Secured Core Context</web-resource-name>
      <url-pattern>/approval/*</url-pattern>
      <url-pattern>/purchase/ApprovalDetails.jsp</url-pattern>
      <url-pattern>/jsp/AuthError.jsp</url-pattern>
      <url-pattern>/AuthError.jsp</url-pattern>
      <url-pattern>/jsp/pagenotfound.jsp</url-pattern>
      <url-pattern>/jsp/exceptionerror.jsp</url-pattern>
            <url-pattern>/ze/*</url-pattern>
      <url-pattern>/servlet/HdFileDownloadServlet</url-pattern>
      <url-pattern>/workorder/CloseWorkOrder.jsp</url-pattern> <!-- Issue fix for id-61245 -->
      <url-pattern>/PurchaseRequestFileUploader.up</url-pattern>
      <url-pattern>/PurchaseOrderFileUploader.up</url-pattern>
            <url-pattern>/workorder/SDPOutlookAddIn.jsp</url-pattern>
      <!-- SD-72752 -->
      <url-pattern>/j_security_check</url-pattern>
      <url-pattern>/RestAPI/TwoFactorAction</url-pattern>
    </web-resource-collection>
  </security-constraint>

At code org apache. catalina. realm. The configuration information described above is used in realmbase#findsecurityconstraints.

However, a puzzling situation has occurred. When / RestAPI/ImportTechnicians are constructed, this method is not included in the above two configuration information. Do you need to log in?

According to the debugging, as shown in the figure below, after a match through findSecurityConstraints, due to the mismatch, the final return is null. The program enters the if statement block and continues to perform the next pipeline operation, so / RestAPI/ImportTechnicians do not need authentication. Similarly, access interfaces similar to / RestAPI/xxxx do not need authentication.

0x02 any file upload

On COM adventnet. servicedesk. setup. action. There is an obvious file writing action at the importtechniciansaction#execute, and the file content comes from the upload form.

The corresponding request can be constructed according to the configuration file. After execution, the uploaded file will be saved in the bin directory.

  <action name="ImportTechnicians" path="/ImportTechnicians" scope="request" type="com.adventnet.servicedesk.setup.action.ImportTechniciansAction">
            <forward name="GetInputFile" path="/setup/GetTechInputFile.jsp"/>
            <forward name="ImportConfirmation" path="/setup/TechImportConfirmation.jsp"/>
            <forward name="MapFields" path="/setup/TechMapFields.jsp"/>
        </action>

0x03 command execution

On COM manageengine. s247. util. S247util#installagentprogress calls MSIEXEC. In the bin directory Exe, combined with the file upload just now, so you can pass in a file named msiexe Exe file, and then call the interface.

installAgentProgress on COM manageengine. s247. actions. S247action #s247agentinstallationprocess can be called in this action.

Finally, by combining unauthorized and file upload, you can complete an unauthorized command execution.

summary

It took some time to find the reason for unauthorized access. At first, I thought it was authentication in the Filter, but I didn't find it after checking several filters. The next step is debugging step by step. Finally, it is found that the authentication is done in the Tomcat Pipline mechanism. After repeatedly comparing the configuration files, no configuration error was found, because it was not only equipped with URLs that need authentication, but also configured URLs that do not need authentication. It was confused for a long time and stepped on a big pit.

Added by el_quijote on Sun, 26 Dec 2021 07:07:16 +0200