Sample backdoor in default installation

That’s funny, but in default installation any unauthenticated user may get information about any sysobject in repository:

]$ cat deployments/ServerApps.ear/DmMethods.war/WEB-INF/web.xml
<?xml version="1.0" encoding="UTF-8"?>
...
<web-app>
...
    <servlet>
        <servlet-name>DmSampleServlet</servlet-name>
        <servlet-class>DmSampleServlet</servlet-class>
    </servlet>
...
    <servlet-mapping>
        <servlet-name>DmSampleServlet</servlet-name>
        <url-pattern>/servlet/DmSampleServlet</url-pattern>
    </servlet-mapping>
</web-app>

What the fuck is DmSampleServlet? Documentum installer graciously provides it’s source code:

]$ cat DmMethods.war/WEB-INF/classes/DmSampleServlet.java
/**
 * This class is a simple sample Servlet that demonstrates how to
 * a develop a custom Servlet that receives HTTP POST requests
 * from a Documentum eContent Server.
 *
 * This Servlet expects to be called with a parameter Map containing
 * parameter names as keys of type String, and parameter values
 * of type String array.
 *
 * KEY          VALUE
 * docbase      <docbase_name>
 * user         <user_name>
 * ticket       <login_ticket>
 * id           <r_object_id>
 *
 * The user credentials and r_object_id will be used to obtain the attributes
 * or meta-data of the docbase object specified by the r_object_id.  These
 * attributes are returned as an XML file.
 *
 * No attributes will be returned if launched asynchronously.
 *
 * NOTE: If HTTP_POST apply method was launched asynchronously, the
 * additional parameter "launch_async" is set by the Documentum eContent
 * Server and no response can be returned.  When "launch_async" is set,
 * the OutputStream of the HttpServletResponse must NOT be accessed.
 */

...

// Retrieve the document object
String queryStr = "dm_sysobject where r_object_id = '" + id + "'";
IDfSysObject sysObj = (IDfSysObject) session.getObjectByQualification(queryStr);
if (sysObj == null)
{
    throw new ServletException( "DmSampleServlet failed to retrieve " +
                "dm_sysobject with r_object_id '" +
                id + "' from docbase '" + docbase + "'." );
}

if(!launchAsync) {
    OutputStream ostream = response.getOutputStream();
    ostream.write(XML_PROLOG.getBytes());
    ostream.write(XML_ELEMENT_START.getBytes());
    String xmlAttributes = sysObj.getString("_xml_string");
    ostream.write(xmlAttributes.getBytes());
    ostream.write(XML_ELEMENT_END.getBytes());
    ostream.close();
}

As you can see, servlet does not require real credentials (it’s possible to use trusted authentication capabilities), and at first glance it requires valid value of r_object_id, which makes it bit hard to traverse trough possible ids, but it is obvious that following line of code

String queryStr = "dm_sysobject where r_object_id = '" + id + "'";

is vulnerable to SQL-injection attacks.

Demonstration:

One thought on “Sample backdoor in default installation

  1. Pingback: LOL | Documentum in a (nuts)HELL

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s